Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51436
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 28 Jun 2011 17:49:25 +0000 (17:49 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 28 Jun 2011 17:49:25 +0000 (17:49 +0000)
Send 100 (Continue) response earlier to enable ServletRequestListener implementations to read the request body.
Based on a patch by Simon Olofsson.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1140750 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/LocalStrings.properties
java/org/apache/catalina/core/StandardContextValve.java
java/org/apache/catalina/core/StandardWrapperValve.java
webapps/docs/changelog.xml

index f49e831..5581523 100644 (file)
@@ -156,6 +156,7 @@ standardContext.urlValidate=Cannot validate URL decoded request path {0}
 standardContext.workPath=Exception obtaining work path for context [{0}]
 standardContext.workCreateException=Failed to determine absolute work directory from directory [{0}] and CATALINA_HOME [{1}] for context [{2}]
 standardContext.workCreateFail=Failed to create work directory [{0}] for context [{1}]
+standardContextValve.acknowledgeException=Failed to acknowledge request with a 100 (Continue) response
 standardEngine.alreadyStarted=Engine has already been started
 standardEngine.jvmRouteFail=Failed to set Engine's jvmRoute attribute from system property
 standardEngine.mappingError=MAPPING configuration error for server name {0}
index 2b45997..934bad0 100644 (file)
@@ -115,7 +115,7 @@ final class StandardContextValve
             || (requestPathMB.equalsIgnoreCase("/META-INF"))
             || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
             || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
-            notFound(response);
+            error(response, HttpServletResponse.SC_NOT_FOUND);
             return;
         }
 
@@ -142,17 +142,28 @@ final class StandardContextValve
         // Select the Wrapper to be used for this Request
         Wrapper wrapper = request.getWrapper();
         if (wrapper == null) {
-            notFound(response);
+            error(response, HttpServletResponse.SC_NOT_FOUND);
             return;
         } else if (wrapper.isUnavailable()) {
             // May be as a result of a reload, try and find the new wrapper
             wrapper = (Wrapper) container.findChild(wrapper.getName());
             if (wrapper == null) {
-                notFound(response);
+                error(response, HttpServletResponse.SC_NOT_FOUND);
                 return;
             }
         }
 
+        // Acknowledge the request
+        try {
+            response.sendAcknowledgement();
+        } catch (IOException ioe) {
+            container.getLogger().error(sm.getString(
+                    "standardContextValve.acknowledgeException"), ioe);
+            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe);
+            error(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            return;
+        }
+        
         // Don't fire listeners during async processing
         // If a request init listener throws an exception, the request is
         // aborted
@@ -209,17 +220,17 @@ final class StandardContextValve
 
 
     /**
-     * Report a "not found" error for the specified resource.  FIXME:  We
+     * Report an error for the specified resource.  FIXME:  We
      * should really be using the error reporting settings for this web
      * application, but currently that code runs at the wrapper level rather
      * than the context level.
      *
      * @param response The response we are creating
      */
-    private void notFound(HttpServletResponse response) {
+    private void error(HttpServletResponse response, int status) {
 
         try {
-            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            response.sendError(status);
         } catch (IllegalStateException e) {
             // Ignore
         } catch (IOException e) {
index 8a0a00c..74e0a4d 100644 (file)
@@ -171,22 +171,6 @@ final class StandardWrapperValve
             request.setComet(true);
         }
         
-        // Acknowledge the request
-        try {
-            response.sendAcknowledgement();
-        } catch (IOException e) {
-            container.getLogger().warn(sm.getString("standardWrapper.acknowledgeException",
-                             wrapper.getName()), e);
-            throwable = e;
-            exception(request, response, e);
-        } catch (Throwable e) {
-            ExceptionUtils.handleThrowable(e);
-            container.getLogger().error(sm.getString("standardWrapper.acknowledgeException",
-                             wrapper.getName()), e);
-            throwable = e;
-            exception(request, response, e);
-            servlet = null;
-        }
         MessageBytes requestPathMB = request.getRequestPathMB();
         DispatcherType dispatcherType = DispatcherType.REQUEST;
         if (request.getDispatcherType()==DispatcherType.ASYNC) dispatcherType = DispatcherType.ASYNC; 
index 30bcb4e..f1e9be8 100644 (file)
         Fix an issue with the CrawlerSessionManagerValve that meant sessions
         were not always correctly tracked. (markt)
       </fix>
+      <fix>
+        <bug>51436</bug>: Send 100 (Continue) response earlier to enable
+        ServletRequestListener implementations to read the request body. Based
+        on a patch by Simon Olofsson. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">