From 51d5da4bbc19ab6301d44af90c12e7432de951cb Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 9 Sep 2010 03:46:20 +0000 Subject: [PATCH] 324679 Don't set content length if filter has written content. git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2265 7e9141cc-0065-0410-87d8-b60c137991c4 --- VERSION.txt | 1 + .../eclipse/jetty/server/HttpConnection.java | 2 +- .../org/eclipse/jetty/server/HttpOutput.java | 6 ++ .../eclipse/jetty/servlet/DefaultServlet.java | 10 +++- .../jetty/servlet/DefaultServletTest.java | 57 +++++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 4c88a467a07..05db01c41e9 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -28,6 +28,7 @@ jetty-7.2-SNAPSHOT + 324379 Change content type after getWriter + 324501 Fire RequestListener.requestDestroyed in last-to-first order. + 324601 Check session expiry on access + + 324679 Allow filter to write before static content + 324811 NPE in Server.dump + 324812 restore WebAppContext constructor used by geronimo integration + JETTY-912 added per exchange timeout api diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 704e4b78448..aac10dd46d3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -1162,7 +1162,7 @@ public class HttpConnection implements Connection if (_closed) throw new IOException("Closed"); - if (super._generator.getContentWritten() > 0) + if (super._generator.isContentWritten()) throw new IllegalStateException("!empty"); // Convert HTTP content to contentl diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index e7190a7b193..670c5e04220 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -54,6 +54,12 @@ public class HttpOutput extends ServletOutputStream _generator=generator; _maxIdleTime=maxIdleTime; } + + /* ------------------------------------------------------------ */ + public boolean isWritten() + { + return _generator.isContentWritten(); + } /* ------------------------------------------------------------ */ /* diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index b3c12fa153d..49945e5576e 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -41,6 +41,7 @@ import org.eclipse.jetty.io.WriterOutputStream; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.InclusiveByteRange; import org.eclipse.jetty.server.ResourceCache; import org.eclipse.jetty.server.Response; @@ -772,8 +773,13 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory } else { + // has a filter already written to the response? + boolean written = out instanceof HttpOutput + ? !((HttpOutput)out).isWritten() + : HttpConnection.getCurrentConnection().getGenerator().isContentWritten(); + // See if a direct methods can be used? - if (out instanceof HttpConnection.Output && content!=null) + if (content!=null && !written && out instanceof HttpOutput) { if (response instanceof Response) { @@ -798,7 +804,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory else { // Write headers normally - writeHeaders(response,content,content_length); + writeHeaders(response,content,written?-1:content_length); // Write content normally Buffer buffer = (content==null)?null:content.getIndirectBuffer(); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index ce2f6f924ad..7598bc3a858 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -4,6 +4,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + import junit.framework.AssertionFailedError; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; @@ -498,6 +505,56 @@ public class DefaultServletTest assertTrue(body.endsWith(boundary+"--\r\n")); } + @Test + public void testFiltered() throws Exception + { + File testDir = new File("target/tests/" + DefaultServletTest.class.getSimpleName()); + prepareEmptyTestDir(testDir); + File resBase = new File(testDir, "docroot"); + assertTrue(resBase.mkdirs()); + File file0 = new File(resBase, "data0.txt"); + createFile(file0, "Hello Text 0"); + + String resBasePath = resBase.getAbsolutePath(); + + ServletHolder defholder = context.addServlet(DefaultServlet.class,"/"); + defholder.setInitParameter("dirAllowed","false"); + defholder.setInitParameter("redirectWelcome","false"); + defholder.setInitParameter("welcomeServlets","false"); + defholder.setInitParameter("gzip","false"); + defholder.setInitParameter("resourceBase",resBasePath); + + ServletHolder jspholder = context.addServlet(NoJspServlet.class,"*.jsp"); + + String response = connector.getResponses("GET /context/data0.txt HTTP/1.1\r\nHost:localhost:8080\r\n\r\n"); + assertResponseContains("Content-Length: 12",response); + assertResponseNotContains("Extra Info",response); + + context.addFilter(AddingFilter.class,"/*",0); + response = connector.getResponses("GET /context/data0.txt HTTP/1.1\r\nHost:localhost:8080\r\n\r\n"); + System.err.println(response); + assertResponseContains("Content-Length: 24",response); + assertResponseContains("Extra Info",response); + assertResponseNotContains("Content-Length: 12",response); + } + + public static class AddingFilter implements Filter + { + public void init(FilterConfig filterConfig) throws ServletException + { + } + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException + { + response.getOutputStream().println("Extra Info"); + chain.doFilter(request,response); + } + + public void destroy() + { + } + } + private void createFile(File file, String str) throws IOException { FileOutputStream out = null;