Author: markt
Date: Thu Jan 23 22:45:19 2014
New Revision: 1560839

URL: http://svn.apache.org/r1560839
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56042
If a request in async mode has an error but has already been dispatched don't 
generate an error page in the ErrorReportValve so the dispatch target can 
handle it.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
    
tomcat/tc7.0.x/trunk/test/org/apache/catalina/valves/TestErrorReportValve.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

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

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?rev=1560839&r1=1560838&r2=1560839&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java 
Thu Jan 23 22:45:19 2014
@@ -106,8 +106,8 @@ public class ErrorReportValve extends Va
         Throwable throwable =
                 (Throwable) 
request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
 
-        if (request.isAsyncStarted() && response.getStatus() < 400 &&
-                throwable == null) {
+        if (request.isAsyncStarted() && ((response.getStatus() < 400 &&
+                throwable == null) || request.isAsyncDispatching())) {
             return;
         }
 

Modified: 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/valves/TestErrorReportValve.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/valves/TestErrorReportValve.java?rev=1560839&r1=1560838&r2=1560839&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/valves/TestErrorReportValve.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/valves/TestErrorReportValve.java 
Thu Jan 23 22:45:19 2014
@@ -16,8 +16,10 @@
  */
 package org.apache.catalina.valves;
 
+import java.io.File;
 import java.io.IOException;
 
+import javax.servlet.AsyncContext;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -28,6 +30,7 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
 import org.apache.tomcat.util.buf.ByteChunk;
@@ -169,4 +172,50 @@ public class TestErrorReportValve extend
             resp.sendError(ERROR_STATUS, ERROR_MESSAGE);
         }
     }
+
+    @Test
+    public void testBug56042() 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());
+
+        Bug56042Servlet bug56042Servlet = new Bug56042Servlet();
+        Wrapper wrapper =
+            Tomcat.addServlet(ctx, "bug56042Servlet", bug56042Servlet);
+        wrapper.setAsyncSupported(true);
+        ctx.addServletMapping("/bug56042Servlet", "bug56042Servlet");
+
+        tomcat.start();
+
+        StringBuilder url = new StringBuilder(48);
+        url.append("http://localhost:";);
+        url.append(getPort());
+        url.append("/bug56042Servlet");
+
+        ByteChunk res = new ByteChunk();
+        int rc = getUrl(url.toString(), res, null);
+
+        Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc);
+    }
+
+    private static class Bug56042Servlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+                throws ServletException, IOException {
+            // Only set the status on the first call (the dispatch will trigger
+            // another call to this Servlet)
+            if (resp.getStatus() != HttpServletResponse.SC_BAD_REQUEST) {
+                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+                AsyncContext ac = req.startAsync();
+                ac.dispatch();
+            }
+        }
+    }
 }

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=1560839&r1=1560838&r2=1560839&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Thu Jan 23 22:45:19 2014
@@ -112,6 +112,11 @@
         <bug>56032</bug>: Ensure that the WebSocket connection is closed after
         an IO error or an interrupt while sending a WebSocket message. (markt)
       </fix>
+      <fix>
+        <bug>56042</bug>: If a request in async mode has an error but has
+        already been dispatched don't generate an error page in the
+        ErrorReportValve so the dispatch target can handle it. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to