From f4c51ae2a797fe856cda9dfed5f4ae06b7a0ee53 Mon Sep 17 00:00:00 2001 From: markt Date: Wed, 30 Mar 2011 12:04:48 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1086918 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/connector/ResponseFacade.java | 10 +++++++ .../apache/catalina/servlets/DefaultServlet.java | 34 ++++++++++++++++++---- webapps/docs/changelog.xml | 7 +++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/java/org/apache/catalina/connector/ResponseFacade.java b/java/org/apache/catalina/connector/ResponseFacade.java index 989ebb358..0f5d79461 100644 --- a/java/org/apache/catalina/connector/ResponseFacade.java +++ b/java/org/apache/catalina/connector/ResponseFacade.java @@ -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 diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index 6086fb179..4fd55912f 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -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.StreamSource; 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); + } } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 09e61a3d9..2df4ab1b8 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -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) + + 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) + -- 2.11.0