Author: markt
Date: Tue Jun 11 20:18:10 2013
New Revision: 1491940

URL: http://svn.apache.org/r1491940
Log:
Servlet 3.1 requires an ISE if getRequest() or getResponse() are called after 
complete() or dispatch()

Modified:
    tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
    tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java

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=1491940&r1=1491939&r2=1491940&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Tue Jun 11 
20:18:10 2013
@@ -64,8 +64,8 @@ public class AsyncContextImpl implements
     protected static final StringManager sm =
         StringManager.getManager(Constants.Package);
 
-    private ServletRequest servletRequest = null;
-    private ServletResponse servletResponse = null;
+    private volatile ServletRequest servletRequest = null;
+    private volatile ServletResponse servletResponse = null;
     private final List<AsyncListenerWrapper> listeners = new ArrayList<>();
     private boolean hasOriginalRequestAndResponse = true;
     private volatile Runnable dispatch = null;
@@ -90,6 +90,7 @@ public class AsyncContextImpl implements
         check();
         request.getCoyoteRequest().action(ActionCode.COMMIT, null);
         request.getCoyoteRequest().action(ActionCode.ASYNC_COMPLETE, null);
+        clearServletRequestResposne();
     }
 
     @Override
@@ -222,17 +223,26 @@ public class AsyncContextImpl implements
 
         this.dispatch = run;
         this.request.getCoyoteRequest().action(ActionCode.ASYNC_DISPATCH, 
null);
+        clearServletRequestResposne();
     }
 
     @Override
     public ServletRequest getRequest() {
         check();
+        if (servletRequest == null) {
+            throw new IllegalStateException(
+                    sm.getString("asyncContextImpl.request.ise"));
+        }
         return servletRequest;
     }
 
     @Override
     public ServletResponse getResponse() {
         check();
+        if (servletResponse == null) {
+            throw new IllegalStateException(
+                    sm.getString("asyncContextImpl.response.ise"));
+        }
         return servletResponse;
     }
 
@@ -302,9 +312,13 @@ public class AsyncContextImpl implements
         instanceManager = null;
         listeners.clear();
         request = null;
+        clearServletRequestResposne();
+        timeout = -1;
+    }
+
+    private void clearServletRequestResposne() {
         servletRequest = null;
         servletResponse = null;
-        timeout = -1;
     }
 
     public boolean isStarted() {

Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1491940&r1=1491939&r2=1491940&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Tue Jun 
11 20:18:10 2013
@@ -64,7 +64,9 @@ aprListener.tooLateForSSLRandomSeed=Cann
 aprListener.tooLateForFIPSMode=Cannot setFIPSMode: SSL has already been 
initialized
 aprListener.initializedOpenSSL=OpenSSL successfully initialized ({0})
 
+asyncContextImpl.request.ise=It is illegal to call getRequest() after 
complete() or any of the dispatch() methods has been called
 asyncContextImpl.requestEnded=The request associated with the AsyncContext has 
already completed processing.
+asyncContextImpl.response.ise=It is illegal to call getResponse() after 
complete() or any of the dispatch() methods has been called
 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

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=1491940&r1=1491939&r2=1491940&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Tue 
Jun 11 20:18:10 2013
@@ -1777,6 +1777,77 @@ public class TestAsyncContextImpl extend
                 resp.getWriter().println("OK");
             }
         }
+    }
+
+
+    @Test
+    public void testGetRequestISE() throws Exception {
+        doTestAsyncISE(true);
+    }
+
+
+    @Test
+    public void testGetResponseISE() throws Exception {
+        doTestAsyncISE(false);
+    }
+
+
+    private void doTestAsyncISE(boolean useGetRequest) 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());
+
+        Wrapper w = Tomcat.addServlet(ctx, "AsyncISEServlet",
+                new AsyncISEServlet(useGetRequest));
+        w.setAsyncSupported(true);
+        ctx.addServletMapping("/test", "AsyncISEServlet");
+
+        tomcat.start();
+
+        ByteChunk response = new ByteChunk();
+        int rc = getUrl("http://localhost:"; + getPort() +"/test", response,
+                null);
 
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+        Assert.assertEquals("OK", response.toString());
+    }
+
+
+    private static class AsyncISEServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        private boolean useGetRequest = false;
+
+        public AsyncISEServlet(boolean useGetRequest) {
+            this.useGetRequest = useGetRequest;
+        }
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+                throws ServletException, IOException {
+
+            resp.setContentType("text/plain;UTF-8");
+            PrintWriter pw = resp.getWriter();
+
+            AsyncContext async = req.startAsync();
+            // This will commit the response
+            async.complete();
+
+            try {
+                if (useGetRequest) {
+                    async.getRequest();
+                } else {
+                    async.getResponse();
+                }
+                pw.print("FAIL");
+            } catch (IllegalStateException ise) {
+                pw.print("OK");
+            }
+        }
     }
 }



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

Reply via email to