You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2011/06/29 14:57:51 UTC

svn commit: r1141079 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java test/org/apache/catalina/core/TestAsyncContextImpl.java webapps/docs/changelog.xml

Author: markt
Date: Wed Jun 29 12:57:50 2011
New Revision: 1141079

URL: http://svn.apache.org/viewvc?rev=1141079&view=rev
Log:
Ensure that if asyncDispatch() is called during an onTimeout event and the target Servlet does not call startAsync() or complete() that Tomcat calls complete() (or does the equivalent) once the target Servlet exits.

Modified:
    tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=1141079&r1=1141078&r2=1141079&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Wed Jun 29 12:57:50 2011
@@ -312,6 +312,9 @@ public class AsyncContextImpl implements
         }
         try {
             dispatch.run();
+            if (!request.isAsync()) {
+                fireOnComplete();
+            }
         } catch (RuntimeException x) {
             // doInternalComplete(true);
             if (x.getCause() instanceof ServletException) {

Modified: tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1141079&r1=1141078&r2=1141079&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Wed Jun 29 12:57:50 2011
@@ -365,18 +365,26 @@ public class TestAsyncContextImpl extend
         }
     }
 
-    public void testTimeoutListenerComplete() throws Exception {
+    public void testTimeoutListenerCompleteNoDispatch() throws Exception {
+        // Should work
         doTestTimeout(true, null);
     }
     
-    public void testTimeoutListenerNoComplete() throws Exception {
+    public void testTimeoutListenerNoCompleteNoDispatch() throws Exception {
+        // Should trigger an error - must do one or other
         doTestTimeout(false, null);
     }
 
-    public void testTimeoutListenerDispatch() throws Exception {
+    public void testTimeoutListenerCompleteDispatch() throws Exception {
+        // Should trigger an error - can't do both
         doTestTimeout(true, "/nonasync");
     }
-    
+
+    public void testTimeoutListenerNoCompleteDispatch() throws Exception {
+        // Should work
+        doTestTimeout(false, "/nonasync");
+    }
+
 
     private void doTestTimeout(boolean completeOnTimeout, String dispatchUrl)
     throws Exception {
@@ -413,23 +421,44 @@ public class TestAsyncContextImpl extend
         ctx.getPipeline().addValve(alv);
         
         tomcat.start();
-        ByteChunk res = getUrl("http://localhost:" + getPort() + "/async");
+        ByteChunk res = new ByteChunk();
+        try {
+            getUrl("http://localhost:" + getPort() + "/async", res, null);
+        } catch (IOException ioe) {
+            // Ignore - expected for some error conditions
+        }
         StringBuilder expected = new StringBuilder("requestInitialized-");
         expected.append("TimeoutServletGet-onTimeout-");
-        if (!completeOnTimeout) {
-            expected.append("onError-");
-        }
-        if (dispatchUrl == null) {
-            expected.append("onComplete-");
+        if (completeOnTimeout) {
+            if (dispatchUrl == null) {
+                expected.append("onComplete-");
+                expected.append("requestDestroyed");
+            } else {
+                // Error - no further output
+                // There is no onComplete- since the complete event would be
+                // fired during post processing but since there is an error that
+                // never happens.
+            }
         } else {
-            expected.append("NonAsyncServletGet-");
+            if (dispatchUrl == null) {
+                expected.append("onError-");
+            } else {
+                expected.append("NonAsyncServletGet-");
+            }
+            expected.append("onComplete-");
+            expected.append("requestDestroyed");
         }
-        expected.append("requestDestroyed");
         assertEquals(expected.toString(), res.toString());
 
         // Check the access log
-        validateAccessLog(alv, 1, 200, TimeoutServlet.ASYNC_TIMEOUT,
-                TimeoutServlet.ASYNC_TIMEOUT + TIMEOUT_MARGIN + REQUEST_TIME);
+        if (completeOnTimeout && dispatchUrl != null) {
+            validateAccessLog(alv, 1, 500, 0, TimeoutServlet.ASYNC_TIMEOUT +
+                    TIMEOUT_MARGIN + REQUEST_TIME);
+        } else {
+            validateAccessLog(alv, 1, 200, TimeoutServlet.ASYNC_TIMEOUT,
+                    TimeoutServlet.ASYNC_TIMEOUT + TIMEOUT_MARGIN +
+                    REQUEST_TIME);
+        }
     }
     
     private static class TimeoutServlet extends HttpServlet {
@@ -695,11 +724,10 @@ public class TestAsyncContextImpl extend
             resp.getWriter().write("onTimeout-");
             resp.flushBuffer();
             if (completeOnTimeout){
-                if (dispatchUrl == null) {
-                    event.getAsyncContext().complete();
-                } else {
-                    event.getAsyncContext().dispatch(dispatchUrl);
-                }
+                event.getAsyncContext().complete();
+            }
+            if (dispatchUrl != null) {
+                event.getAsyncContext().dispatch(dispatchUrl);
             }
         }
 

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1141079&r1=1141078&r2=1141079&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Jun 29 12:57:50 2011
@@ -167,6 +167,11 @@
         asynchronous request processing and the socket is immediately closed.
         (markt)
       </fix>
+      <fix>
+        Ensure that if asyncDispatch() is called during an onTimeout event and
+        the target Servlet does not call startAsync() or complete() that Tomcat
+        calls complete() once the target Servlet exits. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



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