--- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ a/java/org/apache/catalina/servlets/DefaultServlet.java @@ -39,6 +39,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.StringTokenizer; +import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -415,8 +416,9 @@ public class DefaultServlet extends HttpServlet { HttpServletResponse response) throws IOException, ServletException { - // Serve the requested resource, without the data content - serveResource(request, response, false, fileEncoding); + // Serve the requested resource, without the data content unless we are being included + boolean serveContent = DispatcherType.INCLUDE.equals(request.getDispatcherType()); + serveResource(request, response, serveContent, fileEncoding); } --- a/test/org/apache/catalina/servlets/TestDefaultServlet.java +++ a/test/org/apache/catalina/servlets/TestDefaultServlet.java @@ -23,6 +23,7 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -35,6 +36,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.junit.Assert; import org.junit.Test; import static org.apache.catalina.startup.SimpleHttpClient.CRLF; @@ -340,6 +342,32 @@ public class TestDefaultServlet extends TomcatBaseTest { assertTrue(client.isResponse404()); } + /** + * Verifies that the same Content-Length is returned for both GET and HEAD operations when a + * static resource served by the DefaultServlet is included. + */ + @Test + public void testBug57601() throws Exception { + Tomcat tomcat = getTomcatInstanceTestWebapp(false, true); + + Map> resHeaders= new HashMap<>(); + String path = "http://localhost:" + getPort() + "/test/bug5nnnn/bug57601.jsp"; + ByteChunk out = new ByteChunk(); + + int rc = getUrl(path, out, resHeaders); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); + String length = resHeaders.get("Content-Length").get(0); + Assert.assertEquals(Long.parseLong(length), out.getLength()); + out.recycle(); + + rc = headUrl(path, out, resHeaders); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); + Assert.assertEquals(0, out.getLength()); + Assert.assertEquals(length, resHeaders.get("Content-Length").get(0)); + + tomcat.stop(); + } + public static int getUrl(String path, ByteChunk out, Map> resHead) throws IOException { out.recycle(); --- a/test/webapp/bug5nnnn/bug57601.jsp +++ a/test/webapp/bug5nnnn/bug57601.jsp @@ -0,0 +1,18 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --%> +Outer + --- a/test/webapp/bug5nnnn/bug57601.txt +++ a/test/webapp/bug5nnnn/bug57601.txt @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Inner