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