Author: markt
Date: Wed Mar 30 12:04:48 2011
New Revision: 1086918

URL: http://svn.apache.org/viewvc?rev=1086918&view=rev
Log:
Protect the DefaultServlet against Filters etc writing to the response which 
will a) break partial get support and b) mean setting on content length will 
result in a truncated response.
This also fixers some TCK failures since the TCK sometimes writes to the 
response with a filter.

Modified:
    tomcat/trunk/java/org/apache/catalina/connector/ResponseFacade.java
    tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/connector/ResponseFacade.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/ResponseFacade.java?rev=1086918&r1=1086917&r2=1086918&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/ResponseFacade.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/ResponseFacade.java Wed Mar 
30 12:04:48 2011
@@ -163,6 +163,16 @@ public class ResponseFacade 
     }
 
 
+    public long getContentWritten() {
+
+        if (response == null) {
+            throw new IllegalStateException(
+                            sm.getString("responseFacade.nullResponse"));
+        }
+
+        return response.getContentWritten();
+    }
+
     // ------------------------------------------------ ServletResponse Methods
 
 

Modified: tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1086918&r1=1086917&r2=1086918&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Wed Mar 
30 12:04:48 2011
@@ -47,6 +47,8 @@ import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
 import javax.servlet.UnavailableException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -60,6 +62,7 @@ import javax.xml.transform.stream.Stream
 
 import org.apache.catalina.Globals;
 import org.apache.catalina.connector.RequestFacade;
+import org.apache.catalina.connector.ResponseFacade;
 import org.apache.catalina.util.RequestUtil;
 import org.apache.catalina.util.ServerInfo;
 import org.apache.catalina.util.URLEncoder;
@@ -885,6 +888,21 @@ public class DefaultServlet
 
         }
 
+        // Check to see if a Filter, Valve of wrapper has written some content.
+        // If it has, disable range requests and setting of a content length
+        // since neither can be done reliably.
+        ServletResponse r = response;
+        long contentWritten = 0;
+        while (r instanceof ServletResponseWrapper) {
+            r = ((ServletResponseWrapper) r).getResponse();
+        }
+        if (r instanceof ResponseFacade) {
+            contentWritten = ((ResponseFacade) r).getContentWritten();
+        }
+        if (contentWritten > 0) {
+            ranges = FULL;
+        }
+        
         if ( (cacheEntry.context != null)
                 || isError
                 || ( ((ranges == null) || (ranges.isEmpty()))
@@ -903,11 +921,17 @@ public class DefaultServlet
                 if (debug > 0)
                     log("DefaultServlet.serveFile:  contentLength=" +
                         contentLength);
-                if (contentLength < Integer.MAX_VALUE) {
-                    response.setContentLength((int) contentLength);
-                } else {
-                    // Set the content-length as String to be able to use a 
long
-                    response.setHeader("content-length", "" + contentLength);
+                // Don't set a content length if something else has already
+                // written to the response.
+                if (contentWritten > 0) {
+                    if (contentLength < Integer.MAX_VALUE) {
+                        response.setContentLength((int) contentLength);
+                    } else {
+                        // Set the content-length as String to be able to use a
+                        // long
+                        response.setHeader("content-length",
+                                "" + contentLength);
+                    }
                 }
             }
 

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1086918&r1=1086917&r2=1086918&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Mar 30 12:04:48 2011
@@ -103,6 +103,13 @@
         HTTP range requests cannot be reliably served when a Writer is in use 
so
         prevent the DefaultServlet from attempting to do so. (kkolinko)
       </fix>
+      <fix>
+        Protect the DefaultServlet from Valves, Filters and Wrappers that write
+        content to the response. Prevent partial responses to partial GET
+        requests in this case since the range cannot be reliably determined.
+        Also prevent the DefaultServlet from setting a content length header
+        since this too cannot be reliably determined. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



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

Reply via email to