Author: violetagg
Date: Wed Jun  5 05:02:38 2013
New Revision: 1489706

URL: http://svn.apache.org/r1489706
Log:
Merged revision 1489536 from tomcat/trunk:
IllegalStateException will be thrown if more than one asynchronous dispatch 
operation is started within the same asynchronous cycle.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1489536

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=1489706&r1=1489705&r2=1489706&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java 
Wed Jun  5 05:02:38 2013
@@ -187,6 +187,10 @@ public class AsyncContextImpl implements
             logDebug("dispatch   ");
         }
         check();
+        if (dispatch != null) {
+            throw new IllegalStateException(
+                    sm.getString("asyncContextImpl.dispatchingStarted"));
+        }
         if (request.getAttribute(ASYNC_REQUEST_URI)==null) {
             request.setAttribute(ASYNC_REQUEST_URI, request.getRequestURI());
             request.setAttribute(ASYNC_CONTEXT_PATH, request.getContextPath());
@@ -350,7 +354,9 @@ public class AsyncContextImpl implements
             logDebug("intDispatch");
         }
         try {
-            dispatch.run();
+            Runnable runnable = dispatch;
+            dispatch = null;
+            runnable.run();
             if (!request.isAsync()) {
                 fireOnComplete();
             }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1489706&r1=1489705&r2=1489706&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
Wed Jun  5 05:02:38 2013
@@ -73,6 +73,7 @@ aprListener.initializedOpenSSL=OpenSSL s
 
 asyncContextImpl.requestEnded=The request associated with the AsyncContext has 
already completed processing.
 asyncContextImpl.noAsyncDispatcher=The dispatcher returned from the 
ServletContext does not support asynchronous dispatching
+asyncContextImpl.dispatchingStarted=Asynchronous dispatch operation has 
already been called. Additional asynchronous dispatch operation within the same 
asynchronous cycle is not allowed.
 containerBase.threadedStartFailed=A child container failed during start
 containerBase.threadedStopFailed=A child container failed during stop
 containerBase.backgroundProcess.cluster=Exception processing cluster {0} 
background process

Modified: 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1489706&r1=1489705&r2=1489706&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java 
Wed Jun  5 05:02:38 2013
@@ -1721,4 +1721,63 @@ public class TestAsyncContextImpl extend
             // NO-OP
         }
     }
+
+    @Test
+    public void testForbiddenDispatching() 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());
+
+        NonAsyncServlet nonAsyncServlet = new NonAsyncServlet();
+        Wrapper wrapper = Tomcat.addServlet(ctx, "nonAsyncServlet",
+                nonAsyncServlet);
+        wrapper.setAsyncSupported(true);
+        ctx.addServletMapping("/nonAsyncServlet", "nonAsyncServlet");
+
+        ForbiddenDispatchingServlet forbiddenDispatchingServlet = new 
ForbiddenDispatchingServlet();
+        Wrapper wrapper1 = Tomcat.addServlet(ctx,
+                "forbiddenDispatchingServlet", forbiddenDispatchingServlet);
+        wrapper1.setAsyncSupported(true);
+        ctx.addServletMapping("/forbiddenDispatchingServlet",
+                "forbiddenDispatchingServlet");
+
+        tomcat.start();
+
+        ByteChunk body = new ByteChunk();
+
+        try {
+            getUrl("http://localhost:"; + getPort()
+                    + "/forbiddenDispatchingServlet", body, null);
+        } catch (IOException ioe) {
+            // This may happen if test fails. Output the exception in case it 
is
+            // useful and let asserts handle the failure
+            ioe.printStackTrace();
+        }
+
+        assertTrue(body.toString().contains("OK"));
+        assertTrue(body.toString().contains("NonAsyncServletGet"));
+    }
+
+    private static class ForbiddenDispatchingServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+                throws ServletException, IOException {
+            AsyncContext asyncContext = req.startAsync();
+            asyncContext.dispatch("/nonAsyncServlet");
+            try {
+                asyncContext.dispatch("/nonExistingServlet");
+                resp.getWriter().println("FAIL");
+            } catch (IllegalStateException e) {
+                resp.getWriter().println("OK");
+            }
+        }
+
+    }
 }

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1489706&r1=1489705&r2=1489706&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Jun  5 05:02:38 2013
@@ -130,6 +130,12 @@
         logging properties without prefixes if the property cannot be found 
with
         a prefix. (markt)
       </add>
+      <fix>
+        Ensure that only the first asynchronous dispatch operation for a given
+        asynchronous cycle will be performed. Any subsequent asynchronous
+        dispatch operation for the same asynchronous cycle will be ignored and
+        <code>IllegalStateException</code> will be thrown. (violetagg)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



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

Reply via email to