Author: markt
Date: Tue Mar 15 17:48:15 2011
New Revision: 1081882

URL: http://svn.apache.org/viewvc?rev=1081882&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50903
If a connector is stopped, not not process any keep-alive connections. The 
exact behaviours are:
- HTTP BIO - blocks until request line is read and then returns 503
- HTTP NIO - uses polling, so returns 503 immediately connector is stopped
- HTTP APR - blocks until request line is read and then returns 503
- AJP BIO - blocks until request packet is received and then returns 503 - 
subsequent requests will timeout
- AJP APR - no change - subsequent requests will timeout

Added:
    tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java   (with 
props)
    tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java   (with 
props)
Modified:
    tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
    tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Tue Mar 15 
17:48:15 2011
@@ -287,6 +287,13 @@ public class AjpProcessor extends Abstra
                 error = true;
             }
 
+            if (endpoint.isPaused()) {
+                // 503 - Service unavailable
+                response.setStatus(503);
+                adapter.log(request, response, 0);
+                error = true;
+            }
+
             // Process the request in the adapter
             if (!error) {
                 try {

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Tue Mar 
15 17:48:15 2011
@@ -249,15 +249,24 @@ public class Http11AprProcessor extends 
                     openSocket = true;
                     // Add the socket to the poller
                     endpoint.getPoller().add(socketRef);
-                    break;
+                    if (endpoint.isPaused()) {
+                        // 503 - Service unavailable
+                        response.setStatus(503);
+                        adapter.log(request, response, 0);
+                        error = true;
+                    } else {
+                        break;
+                    }
                 }
-                request.setStartTime(System.currentTimeMillis());
-                keptAlive = true;
-                if (!disableUploadTimeout) {
-                    Socket.timeoutSet(socketRef,
-                            connectionUploadTimeout * 1000);
+                if (!endpoint.isPaused()) {
+                    request.setStartTime(System.currentTimeMillis());
+                    keptAlive = true;
+                    if (!disableUploadTimeout) {
+                        Socket.timeoutSet(socketRef,
+                                connectionUploadTimeout * 1000);
+                    }
+                    inputBuffer.parseHeaders();
                 }
-                inputBuffer.parseHeaders();
             } catch (IOException e) {
                 error = true;
                 break;

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Tue Mar 
15 17:48:15 2011
@@ -330,20 +330,29 @@ public class Http11NioProcessor extends 
                         // associated with socket
                         recycle = false;
                     }
-                    break;
-                }
-                keptAlive = true;
-                if ( !inputBuffer.parseHeaders() ) {
-                    //we've read part of the request, don't recycle it
-                    //instead associate it with the socket
-                    openSocket = true;
-                    recycle = false;
-                    break;
+                    if (endpoint.isPaused()) {
+                        // 503 - Service unavailable
+                        response.setStatus(503);
+                        adapter.log(request, response, 0);
+                        error = true;
+                    } else {
+                        break;
+                    }
                 }
-                request.setStartTime(System.currentTimeMillis());
-                if (!disableUploadTimeout) { //only for body, not for request 
headers
-                    socket.getIOChannel().socket().setSoTimeout(
-                            connectionUploadTimeout);
+                if (!endpoint.isPaused()) {
+                    keptAlive = true;
+                    if ( !inputBuffer.parseHeaders() ) {
+                        //we've read part of the request, don't recycle it
+                        //instead associate it with the socket
+                        openSocket = true;
+                        recycle = false;
+                        break;
+                    }
+                    request.setStartTime(System.currentTimeMillis());
+                    if (!disableUploadTimeout) { //only for body, not for 
request headers
+                        socket.getIOChannel().socket().setSoTimeout(
+                                connectionUploadTimeout);
+                    }
                 }
             } catch (IOException e) {
                 if (log.isDebugEnabled()) {

Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Tue Mar 15 
17:48:15 2011
@@ -194,14 +194,21 @@ public class Http11Processor extends Abs
                     }
                 }
                 inputBuffer.parseRequestLine(false);
-                request.setStartTime(System.currentTimeMillis());
-                keptAlive = true;
-                if (disableUploadTimeout) {
-                    socket.getSocket().setSoTimeout(soTimeout);
+                if (endpoint.isPaused()) {
+                    // 503 - Service unavailable
+                    response.setStatus(503);
+                    adapter.log(request, response, 0);
+                    error = true;
                 } else {
-                    socket.getSocket().setSoTimeout(connectionUploadTimeout);
+                    request.setStartTime(System.currentTimeMillis());
+                    keptAlive = true;
+                    if (disableUploadTimeout) {
+                        socket.getSocket().setSoTimeout(soTimeout);
+                    } else {
+                        
socket.getSocket().setSoTimeout(connectionUploadTimeout);
+                    }
+                    inputBuffer.parseHeaders();
                 }
-                inputBuffer.parseHeaders();
             } catch (IOException e) {
                 error = true;
                 break;

Added: tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java?rev=1081882&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java (added)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java Tue Mar 
15 17:48:15 2011
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.catalina.connector;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.startup.TesterServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+/**
+ * Test cases for {@link Connector}. 
+ */
+public class TestConnector extends TomcatBaseTest {
+
+    public void testStop() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        
+        Context root = tomcat.addContext("", TEMP_DIR);
+        Wrapper w =
+            Tomcat.addServlet(root, "tester", new TesterServlet());
+        w.setAsyncSupported(true);
+        root.addServletMapping("/", "tester");
+
+        Connector connector = tomcat.getConnector();
+        
+        tomcat.start();
+
+        ByteChunk bc = new ByteChunk();
+        int rc = getUrl("http://localhost:"; + getPort() + "/", bc, null, null);
+        
+        assertEquals(200, rc);
+        assertEquals("OK", bc.toString());
+        
+        rc = -1;
+        bc.recycle();
+
+        connector.stop();
+
+        rc = getUrl("http://localhost:"; + getPort() + "/", bc, 1000,
+                null, null);
+        assertEquals(503, rc);
+    }
+}

Propchange: tomcat/trunk/test/org/apache/catalina/connector/TestConnector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java?rev=1081882&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java (added)
+++ tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java Tue Mar 15 
17:48:15 2011
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.catalina.startup;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class TesterServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+            throws ServletException, IOException {
+        
+        resp.setContentType("text/plain");
+        PrintWriter out = resp.getWriter();
+        out.print("OK");
+    }
+}

Propchange: tomcat/trunk/test/org/apache/catalina/startup/TesterServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java (original)
+++ tomcat/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java Tue Mar 
15 17:48:15 2011
@@ -49,6 +49,8 @@ public abstract class TomcatBaseTest ext
     private File tempDir;
     private static int port = 8000;
 
+    public static final String TEMP_DIR = System.getProperty("java.io.tmpdir");
+
     /**
      * Make Tomcat instance accessible to sub-classes.
      */
@@ -190,11 +192,18 @@ public abstract class TomcatBaseTest ext
     public static int getUrl(String path, ByteChunk out,
             Map<String, List<String>> reqHead,
             Map<String, List<String>> resHead) throws IOException {
+        return getUrl(path, out, 1000000, reqHead, resHead);
+    }
+    
+    public static int getUrl(String path, ByteChunk out, int readTimeout,
+            Map<String, List<String>> reqHead,
+            Map<String, List<String>> resHead) throws IOException {
 
         URL url = new URL(path);
         HttpURLConnection connection = 
             (HttpURLConnection) url.openConnection();
-        connection.setReadTimeout(1000000);
+        connection.setUseCaches(false);
+        connection.setReadTimeout(readTimeout);
         if (reqHead != null) {
             for (Map.Entry<String, List<String>> entry : reqHead.entrySet()) {
                 StringBuilder valueList = new StringBuilder();

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1081882&r1=1081881&r2=1081882&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 15 17:48:15 2011
@@ -77,6 +77,12 @@
         <bug>50887</bug>: Add support for configuring the JSSE provider used to
         convert client certificates. Based on a patch by pknopp. (markt)
       </add>
+      <fix>
+        <bug>50903</bug>: When a connector is stopped, ensure that requests 
that
+        are currently in a keep-alive state and waiting for client data are not
+        processed. Requests where processing has started will continue to
+        completion. (markt) 
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Web applications">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to