From: markt Date: Wed, 18 May 2011 17:25:28 +0000 (+0000) Subject: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51197 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=23a06f6b400d887014bf011ded767ca2d46b62e0;p=tomcat7.0 Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51197 Fix possible dropped connection when sendError or sendRedirst are used during async processing. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1124342 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/connector/CoyoteAdapter.java b/java/org/apache/catalina/connector/CoyoteAdapter.java index 10fb3c55b..e691eca98 100644 --- a/java/org/apache/catalina/connector/CoyoteAdapter.java +++ b/java/org/apache/catalina/connector/CoyoteAdapter.java @@ -277,6 +277,9 @@ public class CoyoteAdapter implements Adapter { if (ctxt != null) { ctxt.fireRequestDestroyEvent(request); } + // Lift any suspension (e.g. if sendError() was used by an async + // request + response.setSuspended(false); } if (status==SocketStatus.TIMEOUT) { diff --git a/test/org/apache/catalina/core/TestAsyncContextImpl.java b/test/org/apache/catalina/core/TestAsyncContextImpl.java index 8cb5c7f09..d05b897b2 100644 --- a/test/org/apache/catalina/core/TestAsyncContextImpl.java +++ b/test/org/apache/catalina/core/TestAsyncContextImpl.java @@ -49,6 +49,8 @@ public class TestAsyncContextImpl extends TomcatBaseTest { private static final long REQUEST_TIME = 500; // Timeout thread (where used) checks for timeout every second private static final long TIMEOUT_MARGIN = 1000; + // Default timeout for these tests + private static final long TIMEOUT = 3000; public void testBug49528() throws Exception { // Setup Tomcat instance @@ -1112,4 +1114,74 @@ public class TestAsyncContextImpl extends TomcatBaseTest { } + public void testBug51197() throws Exception { + // Setup Tomcat instance + Tomcat tomcat = getTomcatInstance(); + + // Must have a real docBase - just use temp + File docBase = new File(System.getProperty("java.io.tmpdir")); + + Context ctx = tomcat.addContext("", docBase.getAbsolutePath()); + + AsyncErrorServlet asyncErrorServlet = + new AsyncErrorServlet(HttpServletResponse.SC_BAD_REQUEST); + Wrapper wrapper = + Tomcat.addServlet(ctx, "asyncErrorServlet", asyncErrorServlet); + wrapper.setAsyncSupported(true); + ctx.addServletMapping("/asyncErrorServlet", "asyncErrorServlet"); + + TesterAccessLogValve alv = new TesterAccessLogValve(); + ctx.getPipeline().addValve(alv); + + tomcat.start(); + + StringBuilder url = new StringBuilder(48); + url.append("http://localhost:"); + url.append(getPort()); + url.append("/asyncErrorServlet"); + + int rc = getUrl(url.toString(), new ByteChunk(), null); + + assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc); + + // Without this test may complete before access log has a chance to log + // the request + Thread.sleep(REQUEST_TIME); + + // Check the access log + validateAccessLog(alv, 1, HttpServletResponse.SC_BAD_REQUEST, TIMEOUT, + TIMEOUT + TIMEOUT_MARGIN + REQUEST_TIME); + + } + + private static class AsyncErrorServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private int status = 200; + + public AsyncErrorServlet(int status) { + this.status = status; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + final AsyncContext actxt = req.startAsync(); + actxt.setTimeout(TIMEOUT); + actxt.start(new Runnable() { + @Override + public void run() { + try { + ((HttpServletResponse) actxt.getResponse()).sendError( + status); + } catch (IOException e) { + // Ignore + } + } + }); + } + } + } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8d3579a22..0c25eaa9b 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -101,6 +101,10 @@ get returned with requests mapped to a context with a path of /foobar. (markt) + + 51197: Fix possible dropped connection when sendError or + sendRedirst are used during async processing. (markt) +