Merge branch 'jetty-9.2.x'

Conflicts:
	jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipContentLengthTest.java
	jetty-servlets/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipTester.java
	jetty-servlets/src/test/resources/jetty-logging.properties
This commit is contained in:
Joakim Erdfelt 2014-11-10 16:43:38 -07:00
commit d9d94ec1d2
10 changed files with 933 additions and 252 deletions

View File

@ -34,11 +34,16 @@ import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
public class ServletTester extends ContainerLifeCycle
{
private static final Logger LOG = Log.getLogger(ServletTester.class);
private final Server _server=new Server();
private final LocalConnector _connector=new LocalConnector(_server);
private final ServletContextHandler _context;
@ -163,8 +168,6 @@ public class ServletTester extends ContainerLifeCycle
_context.setResourceBase(resourceBase);
}
private final ServletHandler _handler;
public ServletTester()
{
this("/",ServletContextHandler.SECURITY|ServletContextHandler.SESSIONS);
@ -178,7 +181,6 @@ public class ServletTester extends ContainerLifeCycle
public ServletTester(String contextPath,int options)
{
_context=new ServletContextHandler(_server,contextPath,options);
_handler=_context.getServletHandler();
_server.setConnectors(new Connector[]{_connector});
addBean(_server);
}
@ -190,25 +192,40 @@ public class ServletTester extends ContainerLifeCycle
public String getResponses(String request) throws Exception
{
if (LOG.isDebugEnabled())
{
LOG.debug("Request: {}",request);
}
return _connector.getResponses(request);
}
public String getResponses(String request, long idleFor,TimeUnit units) throws Exception
{
if (LOG.isDebugEnabled())
{
LOG.debug("Request: {}",request);
}
return _connector.getResponses(request, idleFor, units);
}
public ByteBuffer getResponses(ByteBuffer request) throws Exception
{
if (LOG.isDebugEnabled())
{
LOG.debug("Request (Buffer): {}",BufferUtil.toUTF8String(request));
}
return _connector.getResponses(request);
}
public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
{
if (LOG.isDebugEnabled())
{
LOG.debug("Requests (Buffer): {}",BufferUtil.toUTF8String(requestsBuffer));
}
return _connector.getResponses(requestsBuffer, idleFor, units);
}
/* ------------------------------------------------------------ */
/** Create a port based connector.
* This methods adds a port connector to the server
* @return A URL to access the server via the connector.

View File

@ -0,0 +1,103 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
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 org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* Filter that merely manipulates the AsyncContext.
* <p>
* The pattern of manipulation is modeled after how DOSFilter behaves. The purpose of this filter is to test arbitrary filter chains that could see unintended
* side-effects of async context manipulation.
*/
public class AsyncManipFilter implements Filter, AsyncListener
{
private static final Logger LOG = Log.getLogger(AsyncManipFilter.class);
private static final String MANIP_KEY = AsyncManipFilter.class.getName();
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
LOG.debug("doFilter() - {}", chain);
AsyncContext ctx = (AsyncContext)request.getAttribute(MANIP_KEY);
if (ctx == null)
{
LOG.debug("Initial pass through: {}", chain);
ctx = request.startAsync();
ctx.addListener(this);
ctx.setTimeout(1000);
LOG.debug("AsyncContext: {}", ctx);
request.setAttribute(MANIP_KEY,ctx);
return;
}
else
{
LOG.debug("Second pass through: {}", chain);
chain.doFilter(request,response);
}
}
@Override
public void destroy()
{
}
@Override
public void onComplete(AsyncEvent event) throws IOException
{
LOG.debug("onComplete() {}",event);
}
@Override
public void onTimeout(AsyncEvent event) throws IOException
{
LOG.debug("onTimeout() {}",event.getAsyncContext());
event.getAsyncContext().dispatch();
}
@Override
public void onError(AsyncEvent event) throws IOException
{
LOG.debug("onError()",event.getThrowable());
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException
{
LOG.debug("onTimeout() {}",event);
}
}

View File

@ -0,0 +1,89 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class AsyncTimeoutDispatchBasedWrite extends TestDirContentServlet implements AsyncListener
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
AsyncContext ctx = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
if (ctx == null)
{
// First pass through
ctx = request.startAsync();
ctx.addListener(this);
ctx.setTimeout(200);
request.setAttribute(AsyncContext.class.getName(),ctx);
}
else
{
// second pass through, as result of timeout -> dispatch
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
ServletOutputStream out = response.getOutputStream();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","W/etag-" + fileName);
out.write(dataBytes);
// no need to call AsyncContext.complete() from here
// in fact, it will cause an IllegalStateException if we do
// ctx.complete();
}
}
@Override
public void onComplete(AsyncEvent event) throws IOException
{
}
@Override
public void onTimeout(AsyncEvent event) throws IOException
{
event.getAsyncContext().dispatch();
}
@Override
public void onError(AsyncEvent event) throws IOException
{
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException
{
}
}

View File

@ -18,6 +18,9 @@
package org.eclipse.jetty.server.handler.gzip;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import javax.servlet.AsyncContext;
@ -34,11 +37,8 @@ public class AsyncTimeoutWrite extends TestDirContentServlet implements AsyncLis
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
if (request.getAttribute("filename")!=null)
throw new IllegalStateException();
assertThat("'filename' request attribute shouldn't be declared", request.getAttribute("filename"), nullValue());
ServletOutputStream out = response.getOutputStream();
AsyncContext ctx = (AsyncContext)request.getAttribute(AsyncContext.class.getName());
ctx = request.startAsync();
String fileName = request.getServletPath();

View File

@ -18,24 +18,32 @@
package org.eclipse.jetty.server.handler.gzip;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import javax.servlet.Servlet;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.handler.gzip.GzipTester.ContentMetadata;
import org.eclipse.jetty.servlet.FilterHolder;
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.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
@ -48,100 +56,91 @@ public class GzipContentLengthTest
{
@Rule
public final TestTracker tracker = new TestTracker();
/**
* These are the junit parameters for running this test.
* <p>
* In addition to Jetty's DefaultServlet we have multiple test
* servlets that arrange content-length/content-type/get stream
* in different order so as to simulate the real world scenario
* that caused the bug in Eclipse <a href="Bug 354014">http://bugs.eclipse.org/354014</a>
* <p>
* This test case will be run with each of the entries in
* the array below as setup parameters for the test case.
*
* @return the junit parameters
*/
@Parameters(name="{2}/{1} {0}")
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]
{
{ TestServletLengthStreamTypeWrite.class},
{ TestServletLengthTypeStreamWrite.class},
{ AsyncTimeoutWrite.class},
{ AsyncScheduledWrite.class},
{ TestServletStreamLengthTypeWrite.class},
{ TestServletStreamLengthTypeWriteWithFlush.class },
{ TestServletStreamTypeLengthWrite.class},
{ TestServletTypeLengthStreamWrite.class},
{ TestServletTypeStreamLengthWrite.class},
{ TestServletBufferTypeLengthWrite.class},
//{ GzipFilter.class, AsyncTimeoutWrite.class, GzipFilter.GZIP },
//{ GzipFilter.class, AsyncScheduledWrite.class, GzipFilter.GZIP },
{ TestServletLengthStreamTypeWrite.class},
{ TestServletLengthTypeStreamWrite.class},
{ TestServletStreamLengthTypeWrite.class},
{ TestServletStreamLengthTypeWriteWithFlush.class},
{ TestServletStreamTypeLengthWrite.class},
{ TestServletTypeLengthStreamWrite.class},
{ TestServletTypeStreamLengthWrite.class},
});
}
@Rule
public TestingDir testingdir = new TestingDir();
private static final HttpConfiguration defaultHttp = new HttpConfiguration();
private static final int LARGE = defaultHttp.getOutputBufferSize() * 8;
private static final int MEDIUM = defaultHttp.getOutputBufferSize();
private static final int SMALL = defaultHttp.getOutputBufferSize() / 4;
private static final int TINY = GzipHandler.DEFAULT_MIN_GZIP_SIZE / 2;
private static final boolean EXPECT_COMPRESSED = true;
private String compressionType;
public GzipContentLengthTest(Class<? extends Servlet> testServlet)
@Parameters(name = "{0} bytes - {1} - compressed({2}) - type({3}) - filter({4})")
public static List<Object[]> data()
{
this.testServlet = testServlet;
this.compressionType = GzipHandler.GZIP;
List<Object[]> ret = new ArrayList<Object[]>();
String compressionTypes[] = new String[] { GzipHandler.GZIP, GzipHandler.DEFLATE };
Class<?> gzipFilters[] = new Class<?>[] { GzipFilter.class, AsyncGzipFilter.class };
for(String compressionType: compressionTypes)
{
for(Class<?> gzipFilter: gzipFilters)
{
ret.add(new Object[] { 0, "empty.txt", !EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { TINY, "file-tiny.txt", !EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { SMALL, "file-small.txt", EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { SMALL, "file-small.mp3", !EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { MEDIUM, "file-med.txt", EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { MEDIUM, "file-medium.mp3", !EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { LARGE, "file-large.txt", EXPECT_COMPRESSED, compressionType, gzipFilter });
ret.add(new Object[] { LARGE, "file-large.mp3", !EXPECT_COMPRESSED, compressionType, gzipFilter });
}
}
return ret;
}
@Rule
public TestingDir testingdir = new TestingDir();
private Class<? extends Servlet> testServlet;
private void assertIsGzipCompressed(String filename, int filesize) throws Exception
@Parameter(0)
public int fileSize;
@Parameter(1)
public String fileName;
@Parameter(2)
public boolean expectCompressed;
@Parameter(3)
public String compressionType;
@Parameter(4)
public Class<? extends GzipFilter> gzipFilterClass;
private void testWithGzip(Class<? extends TestDirContentServlet> contentServlet) throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
tester.setContentServlet(testServlet);
GzipTester tester = new GzipTester(testingdir, GzipHandler.GZIP);
// Add AsyncGzip Filter
FilterHolder gzipHolder = new FilterHolder(gzipFilterClass);
gzipHolder.setAsyncSupported(true);
tester.addFilter(gzipHolder,"*.txt",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
tester.addFilter(gzipHolder,"*.mp3",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
gzipHolder.setInitParameter("mimeTypes","text/plain");
// Add content servlet
tester.setContentServlet(contentServlet);
try
{
String testFilename = String.format("%s-%s-%s", gzipFilterClass.getSimpleName(), contentServlet.getSimpleName(), fileName);
File testFile = tester.prepareServerFile(testFilename,fileSize);
tester.start();
tester.assertIsResponseGzipCompressed("GET",testfile.getName());
}
finally
{
tester.stop();
}
}
private void assertIsNotGzipCompressed(String filename, int filesize) throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
tester.setContentServlet(testServlet);
try
{
tester.start();
HttpTester.Response response = tester.assertIsResponseNotGzipCompressed("GET",testfile.getName(),filesize,HttpStatus.OK_200);
Assert.assertThat(response.get("ETAG"),Matchers.startsWith("W/etag-"));
HttpTester.Response response = tester.executeRequest("GET","/context/" + testFile.getName(),2,TimeUnit.SECONDS);
assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200));
if (expectCompressed)
{
// Must be gzip compressed
assertThat("Content-Encoding",response.get("Content-Encoding"),containsString(GzipHandler.GZIP));
} else
{
assertThat("Content-Encoding",response.get("Content-Encoding"),not(containsString(GzipHandler.GZIP)));
}
// Uncompressed content Size
ContentMetadata content = tester.getResponseMetadata(response);
assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
}
finally
{
@ -150,86 +149,148 @@ public class GzipContentLengthTest
}
/**
* Tests gzip compression of a small size file
* Test with content servlet that does:
* AsyncContext create -> timeout -> onTimeout -> write-response -> complete
*/
@Test
public void testEmpty() throws Exception
@Ignore
public void testAsyncTimeoutWrite() throws Exception
{
assertIsNotGzipCompressed("empty.txt",0);
testWithGzip(AsyncTimeoutWrite.class);
}
/**
* Tests gzip compression of a small size file
* Test with content servlet that does:
* AsyncContext create -> timeout -> onTimeout -> dispatch -> write-response
*/
@Test
public void testIsGzipCompressedSmall() throws Exception
@Ignore
public void testAsyncTimeoutDispatchBasedWrite() throws Exception
{
assertIsGzipCompressed("file-small.txt",SMALL);
testWithGzip(AsyncTimeoutWrite.class);
}
/**
* Tests gzip compression of a medium size file
*/
@Test
public void testIsGzipCompressedMedium() throws Exception
{
assertIsGzipCompressed("file-med.txt",MEDIUM);
}
/**
* Tests gzip compression of a large size file
*/
@Test
public void testIsGzipCompressedLarge() throws Exception
{
assertIsGzipCompressed("file-large.txt",LARGE);
}
/**
* Tests for problems with Content-Length header on small size files
* that are not being compressed encountered when using GzipHandler
*
* Test with content servlet that does:
* 1) setHeader(content-length)
* 2) getOutputStream()
* 3) setHeader(content-type)
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsNotGzipCompressedTiny() throws Exception
public void testServletLengthStreamTypeWrite() throws Exception
{
assertIsNotGzipCompressed("file-tiny.txt",TINY);
testWithGzip(TestServletLengthStreamTypeWrite.class);
}
/**
* Tests for problems with Content-Length header on small size files
* that are not being compressed encountered when using GzipHandler
*
* Test with content servlet that does:
* 1) setHeader(content-length)
* 2) setHeader(content-type)
* 3) getOutputStream()
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsNotGzipCompressedSmall() throws Exception
public void testServletLengthTypeStreamWrite() throws Exception
{
assertIsNotGzipCompressed("file-small.mp3",SMALL);
testWithGzip(TestServletLengthTypeStreamWrite.class);
}
/**
* Tests for problems with Content-Length header on medium size files
* that are not being compressed encountered when using GzipHandler
*
* Test with content servlet that does:
* 1) getOutputStream()
* 2) setHeader(content-length)
* 3) setHeader(content-type)
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsNotGzipCompressedMedium() throws Exception
public void testServletStreamLengthTypeWrite() throws Exception
{
assertIsNotGzipCompressed("file-medium.mp3",MEDIUM);
testWithGzip(TestServletStreamLengthTypeWrite.class);
}
/**
* Tests for problems with Content-Length header on large size files
* that were not being compressed encountered when using GzipHandler
*
* Test with content servlet that does:
* 1) getOutputStream()
* 2) setHeader(content-length)
* 3) setHeader(content-type)
* 4) outputStream.write() (with frequent response flush)
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsNotGzipCompressedLarge() throws Exception
public void testServletStreamLengthTypeWriteWithFlush() throws Exception
{
assertIsNotGzipCompressed("file-large.mp3",LARGE);
testWithGzip(TestServletStreamLengthTypeWriteWithFlush.class);
}
/**
* Test with content servlet that does:
* 1) getOutputStream()
* 2) setHeader(content-type)
* 3) setHeader(content-length)
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testServletStreamTypeLengthWrite() throws Exception
{
testWithGzip(TestServletStreamTypeLengthWrite.class);
}
/**
* Test with content servlet that does:
* 1) setHeader(content-type)
* 2) setHeader(content-length)
* 3) getOutputStream()
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testServletTypeLengthStreamWrite() throws Exception
{
testWithGzip(TestServletTypeLengthStreamWrite.class);
}
/**
* Test with content servlet that does:
* 1) setHeader(content-type)
* 2) getOutputStream()
* 3) setHeader(content-length)
* 4) outputStream.write()
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testServletTypeStreamLengthWrite() throws Exception
{
testWithGzip(TestServletTypeStreamLengthWrite.class);
}
/**
* Test with content servlet that does:
* 2) getOutputStream()
* 1) setHeader(content-type)
* 3) setHeader(content-length)
* 4) (unwrapped) HttpOutput.write(ByteBuffer)
*
* This is done to demonstrate a bug with using HttpOutput.write()
* while also using GzipFilter
*
* @see <a href="Eclipse Bug 450873">http://bugs.eclipse.org/450873</a>
*/
@Test
@Ignore
public void testHttpOutputWrite() throws Exception
{
testWithGzip(TestServletBufferTypeLengthWrite.class);
}
}

View File

@ -614,7 +614,7 @@ public class GzipDefaultTest
try
{
tester.start();
tester.assertIsResponseNotGziped("test.svgz", "test.svgz.sha1", "image/svg+xml", "gzip");
tester.assertIsResponseNotGzipFiltered("test.svgz", "test.svgz.sha1", "image/svg+xml", "gzip");
}
finally
{

View File

@ -18,13 +18,8 @@
package org.eclipse.jetty.server.handler.gzip;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -35,20 +30,26 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.DateGenerator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.HttpTester.Response;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletTester;
@ -63,7 +64,20 @@ import org.junit.Assert;
public class GzipTester
{
private static final Logger LOG = Log.getLogger(GzipTester.class);
public static class ContentMetadata
{
public final long size;
public final String sha1;
public ContentMetadata(long size, String sha1checksum)
{
this.size = size;
this.sha1 = sha1checksum;
}
}
private Class<? extends Filter> gzipFilterClass = null;
private String encoding = "ISO8859_1";
private String userAgent = null;
private final ServletTester tester = new ServletTester("/context",ServletContextHandler.GZIP);
@ -76,15 +90,15 @@ public class GzipTester
{
this.testdir = testingdir;
this.compressionType = compressionType;
this.accept=accept;
this.accept = accept;
}
public GzipTester(TestingDir testingdir, String compressionType)
{
this.testdir = testingdir;
this.compressionType = compressionType;
this.accept=compressionType;
this.accept = compressionType;
}
public GzipHandler getGzipHandler()
@ -97,11 +111,62 @@ public class GzipTester
return tester.getConnector().getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().getOutputBufferSize();
}
public ContentMetadata getResponseMetadata(Response response) throws Exception
{
long size = response.getContentBytes().length;
String contentEncoding = response.get("Content-Encoding");
ByteArrayInputStream bais = null;
InputStream in = null;
DigestOutputStream digester = null;
ByteArrayOutputStream uncompressedStream = null;
try
{
MessageDigest digest = MessageDigest.getInstance("SHA1");
bais = new ByteArrayInputStream(response.getContentBytes());
if (contentEncoding == null)
{
LOG.debug("No response content-encoding");
in = new PassThruInputStream(bais);
}
else if (contentEncoding.contains(GzipHandler.GZIP))
{
in = new GZIPInputStream(bais);
}
else if (contentEncoding.contains(GzipHandler.DEFLATE))
{
in = new InflaterInputStream(bais,new Inflater(true));
}
else
{
assertThat("Unexpected response content-encoding", contentEncoding, isEmptyOrNullString());
}
uncompressedStream = new ByteArrayOutputStream((int)size);
digester = new DigestOutputStream(uncompressedStream,digest);
IO.copy(in,digester);
byte output[] = uncompressedStream.toByteArray();
String actualSha1Sum = Hex.asHex(digest.digest());
return new ContentMetadata(output.length,actualSha1Sum);
}
finally
{
IO.close(digester);
IO.close(in);
IO.close(bais);
IO.close(uncompressedStream);
}
}
public HttpTester.Response assertIsResponseGzipCompressed(String method, String filename) throws Exception
{
return assertIsResponseGzipCompressed(method,filename,filename,-1);
}
public HttpTester.Response assertIsResponseGzipCompressed(String method, String filename, long ifmodifiedsince) throws Exception
{
return assertIsResponseGzipCompressed(method,filename,filename,ifmodifiedsince);
@ -121,25 +186,25 @@ public class GzipTester
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding",accept);
if (this.userAgent != null)
request.setHeader("User-Agent", this.userAgent);
request.setHeader("User-Agent",this.userAgent);
request.setURI("/context/" + path);
// Issue the request
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
int qindex = compressionType.indexOf(";");
if (qindex < 0)
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),containsString(compressionType));
else
Assert.assertThat("Response.header[Content-Encoding]", response.get("Content-Encoding"),containsString(compressionType.substring(0,qindex)));
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),containsString(compressionType.substring(0,qindex)));
ByteArrayInputStream bais = null;
InputStream in = null;
ByteArrayOutputStream out = null;
String actual = null;
ByteArrayInputStream bais = null;
InputStream in = null;
ByteArrayOutputStream out = null;
String actual = null;
try
{
bais = new ByteArrayInputStream(response.getContentBytes());
@ -149,7 +214,7 @@ public class GzipTester
}
else if (compressionType.startsWith(GzipHandler.DEFLATE))
{
in = new InflaterInputStream(bais, new Inflater(true));
in = new InflaterInputStream(bais,new Inflater(true));
}
out = new ByteArrayOutputStream();
IO.copy(in,out);
@ -163,12 +228,12 @@ public class GzipTester
IO.close(in);
IO.close(bais);
}
return response;
}
public HttpTester.Response assertIsResponseGzipCompressed(String method, String requestedFilename, String serverFilename, long ifmodifiedsince) throws Exception
public HttpTester.Response assertIsResponseGzipCompressed(String method, String requestedFilename, String serverFilename, long ifmodifiedsince)
throws Exception
{
HttpTester.Request request = HttpTester.newRequest();
HttpTester.Response response;
@ -177,39 +242,36 @@ public class GzipTester
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding",compressionType);
if (ifmodifiedsince>0)
if (ifmodifiedsince > 0)
request.setHeader(HttpHeader.IF_MODIFIED_SINCE.asString(),DateGenerator.formatDate(ifmodifiedsince));
if (this.userAgent != null)
request.setHeader("User-Agent", this.userAgent);
request.setHeader("User-Agent",this.userAgent);
request.setURI("/context/" + requestedFilename);
// Issue the request
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
// Assert the response headers
// Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
// Response headers should have either a Transfer-Encoding indicating chunked OR a Content-Length
/* TODO need to check for the 3rd option of EOF content. To do this properly you might need to look at both HTTP/1.1 and HTTP/1.0 requests
String contentLength = response.get("Content-Length");
String transferEncoding = response.get("Transfer-Encoding");
boolean chunked = (transferEncoding != null) && (transferEncoding.indexOf("chunk") >= 0);
if(!chunked) {
Assert.assertThat("Response.header[Content-Length]",contentLength,notNullValue());
} else {
Assert.assertThat("Response.header[Transfer-Encoding]",transferEncoding,notNullValue());
}
*/
/*
* TODO need to check for the 3rd option of EOF content. To do this properly you might need to look at both HTTP/1.1 and HTTP/1.0 requests String
* contentLength = response.get("Content-Length"); String transferEncoding = response.get("Transfer-Encoding");
*
* boolean chunked = (transferEncoding != null) && (transferEncoding.indexOf("chunk") >= 0); if(!chunked) {
* Assert.assertThat("Response.header[Content-Length]",contentLength,notNullValue()); } else {
* Assert.assertThat("Response.header[Transfer-Encoding]",transferEncoding,notNullValue()); }
*/
int qindex = compressionType.indexOf(";");
if (qindex < 0)
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),containsString(compressionType));
else
Assert.assertThat("Response.header[Content-Encoding]", response.get("Content-Encoding"),containsString(compressionType.substring(0,qindex)));
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),containsString(compressionType.substring(0,qindex)));
Assert.assertThat(response.get("ETag"),Matchers.startsWith("W/"));
// Assert that the decompressed contents are what we expect.
File serverFile = testdir.getFile(serverFilename);
String expected = IO.readToString(serverFile);
@ -227,7 +289,7 @@ public class GzipTester
}
else if (compressionType.startsWith(GzipHandler.DEFLATE))
{
in = new InflaterInputStream(bais, new Inflater(true));
in = new InflaterInputStream(bais,new Inflater(true));
}
out = new ByteArrayOutputStream();
IO.copy(in,out);
@ -241,11 +303,10 @@ public class GzipTester
IO.close(in);
IO.close(bais);
}
return response;
}
public HttpTester.Response assertIsResponseNotModified(String method, String requestedFilename, long ifmodifiedsince) throws Exception
{
HttpTester.Request request = HttpTester.newRequest();
@ -255,10 +316,10 @@ public class GzipTester
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding",compressionType);
if (ifmodifiedsince>0)
if (ifmodifiedsince > 0)
request.setHeader(HttpHeader.IF_MODIFIED_SINCE.asString(),DateGenerator.formatDate(ifmodifiedsince));
if (this.userAgent != null)
request.setHeader("User-Agent", this.userAgent);
request.setHeader("User-Agent",this.userAgent);
request.setURI("/context/" + requestedFilename);
// Issue the request
@ -266,47 +327,45 @@ public class GzipTester
Assert.assertThat(response.getStatus(),Matchers.equalTo(304));
Assert.assertThat(response.get("ETag"),Matchers.startsWith("W/"));
return response;
}
/**
* Makes sure that the response contains an unfiltered file contents.
* <p>
* This is used to test exclusions and passthroughs in the GzipHandler.
* <p>
* An example is to test that it is possible to configure GzipHandler to not recompress content that shouldn't be
* compressed by the GzipHandler.
* An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be compressed by the GzipFilter.
*
* @param requestedFilename
* the filename used to on the GET request,.
* @param testResourceSha1Sum
* the sha1sum file that contains the SHA1SUM checksum that will be used to verify that the response
* contents are what is intended.
* the sha1sum file that contains the SHA1SUM checksum that will be used to verify that the response contents are what is intended.
* @param expectedContentType
*/
public void assertIsResponseNotGziped(String requestedFilename, String testResourceSha1Sum, String expectedContentType) throws Exception
{
assertIsResponseNotGziped(requestedFilename, testResourceSha1Sum, expectedContentType,null);
assertIsResponseNotGzipFiltered(requestedFilename,testResourceSha1Sum,expectedContentType,null);
}
/**
* Makes sure that the response contains an unfiltered file contents.
* <p>
* This is used to test exclusions and passthroughs in the GzipHandler.
* <p>
* An example is to test that it is possible to configure GzipHandler to not recompress content that shouldn't be
* compressed by the GzipHandler.
* An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be compressed by the GzipFilter.
*
* @param requestedFilename
* the filename used to on the GET request,.
* @param testResourceSha1Sum
* the sha1sum file that contains the SHA1SUM checksum that will be used to verify that the response
* contents are what is intended.
* the sha1sum file that contains the SHA1SUM checksum that will be used to verify that the response contents are what is intended.
* @param expectedContentType
* @param expectedContentEncoding can be non-null in some circumstances, eg when dealing with pre-gzipped .svgz files
* @param expectedContentEncoding
* can be non-null in some circumstances, eg when dealing with pre-gzipped .svgz files
*/
public void assertIsResponseNotGziped(String requestedFilename, String testResourceSha1Sum, String expectedContentType, String expectedContentEncoding) throws Exception
public void assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum, String expectedContentType, String expectedContentEncoding)
throws Exception
{
HttpTester.Request request = HttpTester.newRequest();
HttpTester.Response response;
@ -316,7 +375,7 @@ public class GzipTester
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding",compressionType);
if (this.userAgent != null)
request.setHeader("User-Agent", this.userAgent);
request.setHeader("User-Agent",this.userAgent);
request.setURI("/context/" + requestedFilename);
// Issue the request
@ -329,14 +388,14 @@ public class GzipTester
Assert.assertThat(prefix + ".status",response.getStatus(),is(HttpServletResponse.SC_OK));
Assert.assertThat(prefix + ".header[Content-Length]",response.get("Content-Length"),notNullValue());
Assert.assertThat(prefix + ".header[Content-Encoding] (should not be recompressed by GzipHandler)",response.get("Content-Encoding"),
expectedContentEncoding == null? nullValue() : notNullValue());
expectedContentEncoding == null?nullValue():notNullValue());
if (expectedContentEncoding != null)
Assert.assertThat(prefix + ".header[Content-Encoding]",response.get("Content-Encoding"),is(expectedContentEncoding));
Assert.assertThat(prefix + ".header[Content-Type] (should have a Content-Type associated with it)",response.get("Content-Type"),notNullValue());
Assert.assertThat(prefix + ".header[Content-Type]",response.get("Content-Type"),is(expectedContentType));
Assert.assertThat(response.get("ETAG"),Matchers.startsWith("W/"));
ByteArrayInputStream bais = null;
DigestOutputStream digester = null;
try
@ -359,7 +418,7 @@ public class GzipTester
private void dumpHeaders(String prefix, HttpTester.Message message)
{
LOG.debug("dumpHeaders: {}", prefix);
LOG.debug("dumpHeaders: {}",prefix);
Enumeration<String> names = message.getFieldNames();
while (names.hasMoreElements())
{
@ -380,21 +439,20 @@ public class GzipTester
}
/**
* Asserts that the requested filename results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
* Asserts that the requested filename results in a properly structured GzipFilter response, where the content is not compressed, and the content-length is
* returned appropriately.
*
* @param filename
* the filename used for the request, and also used to compare the response to the server file, assumes
* that the file is suitable for {@link Assert#assertEquals(Object, Object)} use. (in other words, the
* contents of the file are text)
* the filename used for the request, and also used to compare the response to the server file, assumes that the file is suitable for
* {@link Assert#assertEquals(Object, Object)} use. (in other words, the contents of the file are text)
* @param expectedFilesize
* the expected filesize to be specified on the Content-Length portion of the response headers. (note:
* passing -1 will disable the Content-Length assertion)
* the expected filesize to be specified on the Content-Length portion of the response headers. (note: passing -1 will disable the Content-Length
* assertion)
* @throws Exception
*/
public HttpTester.Response assertIsResponseNotGzipCompressed(String method, String filename, int expectedFilesize, int status) throws Exception
{
String uri = "/context/"+filename;
String uri = "/context/" + filename;
HttpTester.Response response = executeRequest(method,uri);
assertResponseHeaders(expectedFilesize,status,response);
// Assert that the contents are what we expect.
@ -406,23 +464,23 @@ public class GzipTester
String actual = readResponse(response);
Assert.assertEquals("Expected response equals actual response",expectedResponse,actual);
}
return response;
}
/**
* Asserts that the request results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
* Asserts that the request results in a properly structured GzipFilter response, where the content is not compressed, and the content-length is returned
* appropriately.
*
* @param expectedResponse
* the expected response body string
* @param expectedFilesize
* the expected filesize to be specified on the Content-Length portion of the response headers. (note:
* passing -1 will disable the Content-Length assertion)
* the expected filesize to be specified on the Content-Length portion of the response headers. (note: passing -1 will disable the Content-Length
* assertion)
* @throws Exception
*/
public void assertIsResponseNotGzipCompressedAndEqualToExpectedString(String method,String expectedResponse, int expectedFilesize, int status) throws Exception
public void assertIsResponseNotGzipCompressedAndEqualToExpectedString(String method, String expectedResponse, int expectedFilesize, int status)
throws Exception
{
String uri = "/context/";
HttpTester.Response response = executeRequest(method,uri);
@ -433,15 +491,15 @@ public class GzipTester
}
/**
* Asserts that the request results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
* Asserts that the request results in a properly structured GzipFilter response, where the content is not compressed, and the content-length is returned
* appropriately.
*
* @param expectedFilesize
* the expected filesize to be specified on the Content-Length portion of the response headers. (note:
* passing -1 will disable the Content-Length assertion)
* the expected filesize to be specified on the Content-Length portion of the response headers. (note: passing -1 will disable the Content-Length
* assertion)
* @throws Exception
*/
public void assertIsResponseNotGzipCompressed(String method,int expectedFilesize, int status) throws Exception
public void assertIsResponseNotGzipCompressed(String method, int expectedFilesize, int status) throws Exception
{
String uri = "/context/";
HttpTester.Response response = executeRequest(method,uri);
@ -455,35 +513,44 @@ public class GzipTester
if (expectedFilesize != (-1))
{
Assert.assertEquals(expectedFilesize,response.getContentBytes().length);
String cl=response.get("Content-Length");
if (cl!=null)
String cl = response.get("Content-Length");
if (cl != null)
{
int serverLength = Integer.parseInt(response.get("Content-Length"));
Assert.assertEquals(serverLength,expectedFilesize);
}
if (status>=200 && status<300)
Assert.assertThat(response.get("ETAG"),Matchers.startsWith("W/"));
if (status >= 200 && status < 300)
Assert.assertThat(response.get("ETAG"),Matchers.startsWith("W/"));
}
Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),not(containsString(compressionType)));
}
private HttpTester.Response executeRequest(String method, String uri) throws IOException, Exception
public HttpTester.Response executeRequest(String method, String path, int idleFor, TimeUnit idleUnit) throws Exception
{
HttpTester.Request request = HttpTester.newRequest();
HttpTester.Response response;
request.setMethod(method);
request.setVersion("HTTP/1.0");
request.setVersion("HTTP/1.1");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding",compressionType);
if (this.userAgent != null)
request.setHeader("User-Agent", this.userAgent);
request.setHeader("Accept-Encoding",accept);
request.setHeader("Connection","close");
request.setURI(uri);
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
return response;
if (this.userAgent != null)
{
request.setHeader("User-Agent",this.userAgent);
}
request.setURI(path);
// Issue the request
return HttpTester.parseResponse(tester.getResponses(request.generate(),idleFor,idleUnit));
}
private HttpTester.Response executeRequest(String method, String path) throws IOException, Exception
{
return executeRequest(method,path,2,TimeUnit.SECONDS);
}
private String readResponse(HttpTester.Response response) throws IOException, UnsupportedEncodingException
@ -493,11 +560,11 @@ public class GzipTester
ByteArrayOutputStream out = null;
try
{
byte[] content=response.getContentBytes();
if (content!=null)
actual=new String(response.getContentBytes(),encoding);
byte[] content = response.getContentBytes();
if (content != null)
actual = new String(response.getContentBytes(),encoding);
else
actual="";
actual = "";
}
finally
{
@ -507,7 +574,6 @@ public class GzipTester
return actual;
}
/**
* Generate string content of arbitrary length.
*
@ -580,7 +646,7 @@ public class GzipTester
finally
{
IO.close(in);
IO.close(fos);
IO.close(fos);
}
}
@ -611,6 +677,12 @@ public class GzipTester
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
servletHolder.setInitParameter("etags","true");
if (gzipFilterClass != null)
{
FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.of(DispatcherType.REQUEST));
holder.setInitParameter("vary","Accept-Encoding");
}
}
public void setEncoding(String encoding)
@ -622,22 +694,41 @@ public class GzipTester
{
this.userAgent = ua;
}
public void addMimeType (String extension, String mimetype)
public void addMimeType(String extension, String mimetype)
{
this.tester.getContext().getMimeTypes().addMimeMapping(extension, mimetype);
this.tester.getContext().getMimeTypes().addMimeMapping(extension,mimetype);
}
/**
* Add an arbitrary filter to the test case.
*
* @param holder
* the filter to add
* @param pathSpec
* the path spec for this filter
* @param dispatches
* the set of {@link DispatcherType} to associate with this filter
*/
public void addFilter(FilterHolder holder, String pathSpec, EnumSet<DispatcherType> dispatches) throws IOException
{
tester.addFilter(holder,pathSpec,dispatches);
}
public void start() throws Exception
{
Assert.assertThat("No servlet defined yet. Did you use #setContentServlet()?",tester,notNullValue());
tester.dump();
if (LOG.isDebugEnabled())
{
tester.dumpStdErr();
}
tester.start();
}
public void stop()
{
// NOTE: Do not cleanup the testdir. Failures can't be diagnosed if you do that.
// NOTE: Do not cleanup the testdir. Failures can't be diagnosed if you do that.
// IO.delete(testdir.getDir()):
try
{
@ -651,4 +742,5 @@ public class GzipTester
e.printStackTrace(System.err);
}
}
}

View File

@ -0,0 +1,36 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler.gzip;
import java.io.FilterInputStream;
import java.io.InputStream;
/**
* A simple pass-through input stream.
* <p>
* Used in some test cases where a proper resource open/close is needed for
* some potentially optional layers of the input stream.
*/
public class PassThruInputStream extends FilterInputStream
{
public PassThruInputStream(InputStream in)
{
super(in);
}
}

View File

@ -0,0 +1,283 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.servlets;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.handler.gzip.AsyncManipFilter;
import org.eclipse.jetty.server.handler.gzip.AsyncTimeoutDispatchBasedWrite;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.server.handler.gzip.GzipTester;
import org.eclipse.jetty.server.handler.gzip.GzipTester.ContentMetadata;
import org.eclipse.jetty.server.handler.gzip.TestServletLengthStreamTypeWrite;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
* Test the GzipFilter support when under several layers of Filters.
*/
@RunWith(Parameterized.class)
public class GzipFilterLayeredTest
{
@Rule
public final TestTracker tracker = new TestTracker();
private static final HttpConfiguration defaultHttp = new HttpConfiguration();
private static final int LARGE = defaultHttp.getOutputBufferSize() * 8;
private static final int SMALL = defaultHttp.getOutputBufferSize() / 4;
private static final int TINY = GzipHandler.DEFAULT_MIN_GZIP_SIZE / 2;
private static final boolean EXPECT_COMPRESSED = true;
@Parameters(name = "{0} bytes - {1} - compressed({2})")
public static List<Object[]> data()
{
List<Object[]> ret = new ArrayList<Object[]>();
ret.add(new Object[] { 0, "empty.txt", !EXPECT_COMPRESSED });
ret.add(new Object[] { TINY, "file-tiny.txt", !EXPECT_COMPRESSED });
ret.add(new Object[] { SMALL, "file-small.txt", EXPECT_COMPRESSED });
ret.add(new Object[] { LARGE, "file-large.txt", EXPECT_COMPRESSED });
ret.add(new Object[] { LARGE, "file-large.mp3", !EXPECT_COMPRESSED });
return ret;
}
@Parameter(0)
public int fileSize;
@Parameter(1)
public String fileName;
@Parameter(2)
public boolean expectCompressed;
@Rule
public TestingDir testingdir = new TestingDir();
@Test
@Ignore
public void testGzipDosNormal() throws Exception
{
GzipTester tester = new GzipTester(testingdir, GzipHandler.GZIP);
// Add Gzip Filter first
FilterHolder gzipHolder = new FilterHolder(AsyncGzipFilter.class);
gzipHolder.setAsyncSupported(true);
tester.addFilter(gzipHolder,"*.txt",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
tester.addFilter(gzipHolder,"*.mp3",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
gzipHolder.setInitParameter("mimeTypes","text/plain");
// Add (DoSFilter-like) manip filter (in chain of Gzip)
FilterHolder manipHolder = new FilterHolder(AsyncManipFilter.class);
manipHolder.setAsyncSupported(true);
tester.addFilter(manipHolder,"/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
// Add normal content servlet
tester.setContentServlet(TestServletLengthStreamTypeWrite.class);
try
{
File testFile = tester.prepareServerFile("GzipDosNormal-" + fileName,fileSize);
tester.start();
HttpTester.Response response = tester.executeRequest("GET","/context/" + testFile.getName(),2,TimeUnit.SECONDS);
assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200));
if (expectCompressed)
{
// Must be gzip compressed
assertThat("Content-Encoding",response.get("Content-Encoding"),containsString(GzipHandler.GZIP));
}
// Uncompressed content Size
ContentMetadata content = tester.getResponseMetadata(response);
assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
}
finally
{
tester.stop();
}
}
@Test
@Ignore
public void testGzipDosAsync() throws Exception
{
GzipTester tester = new GzipTester(testingdir, GzipHandler.GZIP);
// Add Gzip Filter first
FilterHolder gzipHolder = new FilterHolder(AsyncGzipFilter.class);
gzipHolder.setAsyncSupported(true);
tester.addFilter(gzipHolder,"*.txt",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
tester.addFilter(gzipHolder,"*.mp3",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
gzipHolder.setInitParameter("mimeTypes","text/plain");
// Add (DoSFilter-like) manip filter (in chain of Gzip)
FilterHolder manipHolder = new FilterHolder(AsyncManipFilter.class);
manipHolder.setAsyncSupported(true);
tester.addFilter(manipHolder,"/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
// Add normal content servlet
tester.setContentServlet(AsyncTimeoutDispatchBasedWrite.class);
try
{
File testFile = tester.prepareServerFile("GzipDosAsync-" + fileName,fileSize);
tester.start();
HttpTester.Response response = tester.executeRequest("GET","/context/" + testFile.getName(),2,TimeUnit.SECONDS);
assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200));
if (expectCompressed)
{
// Must be gzip compressed
assertThat("Content-Encoding",response.get("Content-Encoding"),containsString(GzipHandler.GZIP));
}
// Uncompressed content Size
ContentMetadata content = tester.getResponseMetadata(response);
assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
}
finally
{
tester.stop();
}
}
@Test
public void testDosGzipNormal() throws Exception
{
GzipTester tester = new GzipTester(testingdir, GzipHandler.GZIP);
// Add (DoSFilter-like) manip filter
FilterHolder manipHolder = new FilterHolder(AsyncManipFilter.class);
manipHolder.setAsyncSupported(true);
tester.addFilter(manipHolder,"/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
// Add Gzip Filter first (in chain of DosFilter)
FilterHolder gzipHolder = new FilterHolder(AsyncGzipFilter.class);
gzipHolder.setAsyncSupported(true);
tester.addFilter(gzipHolder,"*.txt",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
tester.addFilter(gzipHolder,"*.mp3",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
gzipHolder.setInitParameter("mimeTypes","text/plain");
// Add normal content servlet
tester.setContentServlet(TestServletLengthStreamTypeWrite.class);
try
{
File testFile = tester.prepareServerFile("DosGzipNormal-" + fileName,fileSize);
tester.start();
HttpTester.Response response = tester.executeRequest("GET","/context/" + testFile.getName(),2,TimeUnit.SECONDS);
assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200));
if (expectCompressed)
{
// Must be gzip compressed
assertThat("Content-Encoding",response.get("Content-Encoding"),containsString(GzipHandler.GZIP));
} else
{
assertThat("Content-Encoding",response.get("Content-Encoding"),not(containsString(GzipHandler.GZIP)));
}
// Uncompressed content Size
ContentMetadata content = tester.getResponseMetadata(response);
assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
}
finally
{
tester.stop();
}
}
@Test
@Ignore
public void testDosGzipAsync() throws Exception
{
GzipTester tester = new GzipTester(testingdir, GzipHandler.GZIP);
// Add (DoSFilter-like) manip filter
FilterHolder manipHolder = new FilterHolder(AsyncManipFilter.class);
manipHolder.setAsyncSupported(true);
tester.addFilter(manipHolder,"/*",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
// Add Gzip Filter first (in chain of DosFilter)
FilterHolder gzipHolder = new FilterHolder(AsyncGzipFilter.class);
gzipHolder.setAsyncSupported(true);
tester.addFilter(gzipHolder,"*.txt",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
tester.addFilter(gzipHolder,"*.mp3",EnumSet.of(DispatcherType.REQUEST,DispatcherType.ASYNC));
gzipHolder.setInitParameter("mimeTypes","text/plain");
// Add normal content servlet
tester.setContentServlet(AsyncTimeoutDispatchBasedWrite.class);
try
{
File testFile = tester.prepareServerFile("DosGzipAsync-" + fileName,fileSize);
tester.start();
HttpTester.Response response = tester.executeRequest("GET","/context/" + testFile.getName(),2,TimeUnit.SECONDS);
assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200));
if (expectCompressed)
{
// Must be gzip compressed
assertThat("Content-Encoding",response.get("Content-Encoding"),containsString(GzipHandler.GZIP));
} else
{
assertThat("Content-Encoding",response.get("Content-Encoding"),not(containsString(GzipHandler.GZIP)));
}
// Uncompressed content Size
ContentMetadata content = tester.getResponseMetadata(response);
assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
}
finally
{
tester.stop();
}
}
}

View File

@ -1,6 +1,6 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.servlets.LEVEL=DEBUG
org.eclipse.jetty.server.handler.gzip.GzipHandler.LEVEL=DEBUG
#org.eclipse.jetty.servlet.ServletTester.LEVEL=DEBUG
#org.eclipse.jetty.servlets.QoSFilter.LEVEL=DEBUG
#org.eclipse.jetty.servlets.DoSFilter.LEVEL=DEBUG