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 2013/06/11 22:18:10 UTC

svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Violeta Georgieva <mi...@gmail.com>.
2013/6/14 Mark Thomas wrote:
>
> On 14/06/2013 07:00, Violeta Georgieva wrote:
>>
>>
>> Is that mean that if I have AsyncListener that does some work in
>> onComplete() then I will not be able to use the request and response
>> objects?
>
>
> Yes and no. You can't call getRequest() or getResponse() on the
AsyncContext but you can get the objects from getSuppliedRequest() and
getSuppliedResposne() on the AsyncEvent object.
>
> The Tomcat unit tests were updated to do things this way as a number of
them started failing as they were calling getRequest() or getResponse()
during onComplete()
>
> Mark
>

Agh.... You are right.

Thanks

Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Mark Thomas <ma...@apache.org>.
On 14/06/2013 07:00, Violeta Georgieva wrote:
> 2013/6/11 <ma...@apache.org>
>>
>> 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();
>>       }
>
>
> Is that mean that if I have AsyncListener that does some work in
> onComplete() then I will not be able to use the request and response
> objects?

Yes and no. You can't call getRequest() or getResponse() on the 
AsyncContext but you can get the objects from getSuppliedRequest() and 
getSuppliedResposne() on the AsyncEvent object.

The Tomcat unit tests were updated to do things this way as a number of 
them started failing as they were calling getRequest() or getResponse() 
during onComplete()

Mark


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


Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Violeta Georgieva <mi...@gmail.com>.
2013/6/11 <ma...@apache.org>
>
> 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();
>      }


Is that mean that if I have AsyncListener that does some work in
onComplete() then I will not be able to use the request and response
objects?


Thanks Violeta

Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Nick Williams <ni...@nicholaswilliams.net>.
On Jun 11, 2013, at 3:28 PM, Mark Thomas wrote:

> On 11/06/2013 21:25, Konstantin Kolinko wrote:
>> 2013/6/12  <ma...@apache.org>:
>>> 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();
>> 
>> s/../Response/
> 
> Ah, one of my favorite typos. It is almost worth writing a pre-commit hook to fix that :)

I type "reponse" a lot. I have a problem with that first S for some reason.

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


Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Mark Thomas <ma...@apache.org>.
On 11/06/2013 21:25, Konstantin Kolinko wrote:
> 2013/6/12  <ma...@apache.org>:
>> 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();
>
> s/../Response/

Ah, one of my favorite typos. It is almost worth writing a pre-commit 
hook to fix that :)

Thanks for the catch.

Mark


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


Re: svn commit: r1491940 - in /tomcat/trunk: java/org/apache/catalina/core/AsyncContextImpl.java java/org/apache/catalina/core/LocalStrings.properties test/org/apache/catalina/core/TestAsyncContextImpl.java

Posted by Konstantin Kolinko <kn...@gmail.com>.
2013/6/12  <ma...@apache.org>:
> 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();

s/../Response/

>      }
>

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