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 2012/03/05 13:05:26 UTC

svn commit: r1297017 - in /tomcat/trunk: java/org/apache/catalina/valves/ErrorReportValve.java test/org/apache/catalina/core/TestAsyncContextImpl.java

Author: markt
Date: Mon Mar  5 12:05:25 2012
New Revision: 1297017

URL: http://svn.apache.org/viewvc?rev=1297017&view=rev
Log:
Further fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=51197
Allow the ErrorReportValve to write a response body if sendError() is
called during an async request if it is being handled on a container
thread. As per SRV 10.9.2, if an error occurs during an async request on
an application thread, writing the response body - if any - is entirely
an application responsibility.

Modified:
    tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
    tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java

Modified: tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?rev=1297017&r1=1297016&r2=1297017&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java (original)
+++ tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java Mon Mar  5 12:05:25 2012
@@ -77,13 +77,14 @@ public class ErrorReportValve extends Va
             return;
         }
 
-        if (request.isAsyncStarted()) {
+        Throwable throwable =
+                (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+
+        if (request.isAsyncStarted() && response.getStatus() < 400 &&
+                throwable == null) {
             return;
         }
 
-        Throwable throwable =
-            (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
-
         if (throwable != null) {
 
             // The response is an error
@@ -109,6 +110,9 @@ public class ErrorReportValve extends Va
             ExceptionUtils.handleThrowable(tt);
         }
 
+        if (request.isAsyncStarted()) {
+            request.getAsyncContext().complete();
+        }
     }
 
 

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=1297017&r1=1297016&r2=1297017&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Mon Mar  5 12:05:25 2012
@@ -36,6 +36,7 @@ import javax.servlet.http.HttpServletRes
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import org.junit.Test;
@@ -1203,24 +1204,35 @@ public class TestAsyncContextImpl extend
         url.append(getPort());
         url.append("/asyncErrorServlet");
 
-        int rc = getUrl(url.toString(), new ByteChunk(), null);
+        ByteChunk res = new ByteChunk();
+        int rc = getUrl(url.toString(), res, null);
 
         assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc);
 
+        // SRV 10.9.2 - Writing the response is entirely the application's
+        // responsibility when an error occurs on an application thread.
+        // The test servlet writes no content in this case.
+        if (threaded) {
+            assertEquals(0, res.getLength());
+        } else {
+            assertTrue(res.getLength() > 0);
+        }
+
         // Without this test may complete before access log has a chance to log
         // the request
         Thread.sleep(REQUEST_TIME);
 
         // Check the access log
-        alv.validateAccessLog(1, HttpServletResponse.SC_BAD_REQUEST, TIMEOUT,
-                TIMEOUT + TIMEOUT_MARGIN + REQUEST_TIME);
-
+        alv.validateAccessLog(1, HttpServletResponse.SC_BAD_REQUEST, 0,
+                REQUEST_TIME);
     }
 
     private static class AsyncErrorServlet extends HttpServlet {
 
         private static final long serialVersionUID = 1L;
 
+        public static final String ERROR_MESSAGE = "It broke.";
+
         private int status;
         private boolean threaded;
 
@@ -1242,7 +1254,10 @@ public class TestAsyncContextImpl extend
                         try {
                             HttpServletResponse resp =
                                     (HttpServletResponse) actxt.getResponse();
-                            resp.sendError(status);
+                            resp.sendError(status, ERROR_MESSAGE);
+                            // Complete so there is no delay waiting for the
+                            // timeout
+                            actxt.complete();
                         } catch (IOException e) {
                             // Ignore
                         }



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