Merge remote-tracking branch 'origin/jetty-9.2.x'

Conflicts:
	jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java
	jetty-servlets/src/main/java/org/eclipse/jetty/servlets/AsyncGzipFilter.java
	jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipContentLengthTest.java

Added Interceptor chain so that double gzip interception can be prevented.
This commit is contained in:
Greg Wilkins 2014-11-12 12:36:56 +11:00
commit dfe799d04c
7 changed files with 39 additions and 9 deletions

View File

@ -641,6 +641,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_written+=BufferUtil.length(content);
sendResponse(null,content,complete,callback);
}
public HttpOutput.Interceptor getNextInterceptor()
{
return null;
}
protected void execute(Runnable task)
{

View File

@ -57,6 +57,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
public interface Interceptor
{
void write(ByteBuffer content, boolean complete, Callback callback);
Interceptor getNextInterceptor();
}
private static Logger LOG = Log.getLogger(HttpOutput.class);

View File

@ -311,6 +311,21 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
String path = context==null?baseRequest.getRequestURI():URIUtil.addPaths(baseRequest.getServletPath(),baseRequest.getPathInfo());
LOG.debug("{} handle {} in {}",this,baseRequest,context);
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpOutput out = channel.getResponse().getHttpOutput();
// Are we already being gzipped?
HttpOutput.Interceptor interceptor = out.getInterceptor();
while (interceptor!=null)
{
if (interceptor instanceof GzipHttpOutputInterceptor)
{
LOG.debug("{} already intercepting {}",this,request);
_handler.handle(target,baseRequest, request, response);
return;
}
interceptor=interceptor.getNextInterceptor();
}
// If not a supported method - no Vary because no matter what client, this URI is always excluded
if (!_includedMethods.contains(baseRequest.getMethod()))
{
@ -366,12 +381,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
request.setAttribute(ETAG,etag.replace(ETAG_GZIP,""));
}
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpOutput out = channel.getResponse().getHttpOutput();
HttpOutput.Interceptor interceptor = out.getInterceptor();
if (!(interceptor instanceof GzipHttpOutputInterceptor))
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,channel,interceptor));
// install interceptor and handle
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,channel,out.getInterceptor()));
_handler.handle(target,baseRequest, request, response);
}

View File

@ -79,6 +79,11 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
_bufferSize=bufferSize;
}
public HttpOutput.Interceptor getNextInterceptor()
{
return _interceptor;
}
@Override
public void write(ByteBuffer content, boolean complete, Callback callback)
{
@ -261,6 +266,10 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
}
}
public boolean mightCompress()
{
return _state.get()==GZState.MIGHT_COMPRESS;
}
private class GzipArrayCB extends IteratingNestedCallback
{
private final boolean _complete;

View File

@ -90,7 +90,7 @@ public abstract class AsyncTimeoutCompleteWrite extends TestDirContentServlet im
String fileName = request.getServletPath();
request.setAttribute("filename",fileName);
ctx.addListener(this);
ctx.setTimeout(200);
ctx.setTimeout(20);
// Setup indication of a redispatch (which this scenario shouldn't do)
request.setAttribute(this.getClass().getName(),ctx);

View File

@ -38,6 +38,7 @@ import org.eclipse.jetty.servlets.AsyncGzipFilter;
import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@ -155,6 +156,8 @@ public class GzipContentLengthTest
@Test
public void testAsyncTimeoutCompleteWrite_Default() throws Exception
{
if (expectCompressed && gzipFilterClass==GzipFilter.class)
return; // Default startAsync will never work with GzipFilter, which needs wrapping
testWithGzip(AsyncTimeoutCompleteWrite.Default.class);
}
@ -326,9 +329,10 @@ public class GzipContentLengthTest
* @see <a href="Eclipse Bug 450873">http://bugs.eclipse.org/450873</a>
*/
@Test
@Ignore
public void testHttpOutputWrite() throws Exception
{
if (gzipFilterClass == GzipFilter.class)
return; // Can't downcaste output stream when wrapper is used
testWithGzip(TestServletBufferTypeLengthWrite.class);
}
}

View File

@ -61,7 +61,7 @@ public class TestServletBufferTypeLengthWrite extends TestDirContentServlet
response.setHeader("ETag","W/etag-"+fileName);
response.setContentLength(dataBytes.length);
((HttpOutput)out).write(ByteBuffer.wrap(dataBytes).asReadOnlyBuffer());
}
}