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
This commit is contained in:
Greg Wilkins 2010-09-09 03:46:20 +00:00
parent 2c16ef1fc1
commit 51d5da4bbc
5 changed files with 73 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -54,6 +54,12 @@ public class HttpOutput extends ServletOutputStream
_generator=generator;
_maxIdleTime=maxIdleTime;
}
/* ------------------------------------------------------------ */
public boolean isWritten()
{
return _generator.isContentWritten();
}
/* ------------------------------------------------------------ */
/*

View File

@ -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();

View File

@ -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;