Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Erdfelt2014-11-10 13:22:22 -0500
committerJoakim Erdfelt2014-11-10 13:22:22 -0500
commit9e8a776c3eff2ba8acbbf2b1735cc01b8c161b2e (patch)
treeecc75041890a281de99ce3980586d574d16e8260 /jetty-servlets
parente4cc9ea5de9102a5f8ac4548ff43f29e8360a0ed (diff)
downloadorg.eclipse.jetty.project-9e8a776c3eff2ba8acbbf2b1735cc01b8c161b2e.tar.gz
org.eclipse.jetty.project-9e8a776c3eff2ba8acbbf2b1735cc01b8c161b2e.tar.xz
org.eclipse.jetty.project-9e8a776c3eff2ba8acbbf2b1735cc01b8c161b2e.zip
450855 - GZipFilter declaration order can result in MIGHT_COMPRESS
+ Adding testcase GzipFilterLayeredTest to demonstrate this bug + Some cleanup of Gzip testing behavior to be easier to follow (less reliance on GzipTester utility class)
Diffstat (limited to 'jetty-servlets')
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterLayeredTest.java184
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/AsyncManipFilter.java103
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java325
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/PassThruInputStream.java36
-rw-r--r--jetty-servlets/src/test/resources/jetty-logging.properties1
5 files changed, 539 insertions, 110 deletions
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterLayeredTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterLayeredTest.java
new file mode 100644
index 0000000000..c36ac1a546
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterLayeredTest.java
@@ -0,0 +1,184 @@
+//
+// ========================================================================
+// 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.servlet.FilterHolder;
+import org.eclipse.jetty.servlets.gzip.AsyncManipFilter;
+import org.eclipse.jetty.servlets.gzip.GzipTester;
+import org.eclipse.jetty.servlets.gzip.GzipTester.ContentMetadata;
+import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite;
+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 = AsyncGzipFilter.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, GzipFilter.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.issueRequest("GET","/" + 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(GzipFilter.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, GzipFilter.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.issueRequest("GET",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(GzipFilter.GZIP));
+ } else
+ {
+ assertThat("Content-Encoding",response.get("Content-Encoding"),not(containsString(GzipFilter.GZIP)));
+ }
+
+ // Uncompressed content Size
+ ContentMetadata content = tester.getResponseMetadata(response);
+ assertThat("(Uncompressed) Content Length", content.size, is((long)fileSize));
+ }
+ finally
+ {
+ tester.stop();
+ }
+ }
+}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/AsyncManipFilter.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/AsyncManipFilter.java
new file mode 100644
index 0000000000..1c76234ff9
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/AsyncManipFilter.java
@@ -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.servlets.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);
+ }
+}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
index ed202b076f..d627c3afaf 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java
@@ -18,13 +18,8 @@
package org.eclipse.jetty.servlets.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;
@@ -37,6 +32,7 @@ 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;
@@ -51,6 +47,7 @@ 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.ServletHolder;
@@ -67,8 +64,20 @@ import org.junit.Assert;
public class GzipTester
{
private static final Logger LOG = Log.getLogger(GzipTester.class);
-
- private Class<? extends Filter> gzipFilterClass = GzipFilter.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();;
@@ -80,14 +89,14 @@ 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 int getOutputBufferSize()
@@ -95,11 +104,88 @@ public class GzipTester
return tester.getConnector().getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().getOutputBufferSize();
}
+ public HttpTester.Response issueRequest(String method, String path) throws Exception
+ {
+ return issueRequest(method, path, 2, TimeUnit.SECONDS);
+ }
+
+ public HttpTester.Response issueRequest(String method, String path, int idleFor, TimeUnit idleUnit) throws Exception
+ {
+ HttpTester.Request request = HttpTester.newRequest();
+
+ request.setMethod(method);
+ request.setVersion("HTTP/1.1");
+ request.setHeader("Host","tester");
+ request.setHeader("Accept-Encoding",accept);
+ request.setHeader("Connection","close");
+
+ if (this.userAgent != null)
+ {
+ request.setHeader("User-Agent",this.userAgent);
+ }
+
+ request.setURI("/context/" + path);
+
+ // Issue the request
+ return HttpTester.parseResponse(tester.getResponses(request.generate(),idleFor,idleUnit));
+ }
+
+ 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(GzipFilter.GZIP))
+ {
+ in = new GZIPInputStream(bais);
+ }
+ else if (contentEncoding.contains(GzipFilter.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);
@@ -109,7 +195,6 @@ public class GzipTester
{
return assertIsResponseGzipCompressed(method,requestedFilename,serverFilename,-1);
}
-
public HttpTester.Response assertNonStaticContentIsResponseGzipCompressed(String method, String path, String expected) throws Exception
{
@@ -120,25 +205,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());
@@ -148,7 +233,7 @@ public class GzipTester
}
else if (compressionType.startsWith(GzipFilter.DEFLATE))
{
- in = new InflaterInputStream(bais, new Inflater(true));
+ in = new InflaterInputStream(bais,new Inflater(true));
}
out = new ByteArrayOutputStream();
IO.copy(in,out);
@@ -162,12 +247,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;
@@ -176,39 +261,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);
@@ -226,7 +308,7 @@ public class GzipTester
}
else if (compressionType.startsWith(GzipFilter.DEFLATE))
{
- in = new InflaterInputStream(bais, new Inflater(true));
+ in = new InflaterInputStream(bais,new Inflater(true));
}
out = new ByteArrayOutputStream();
IO.copy(in,out);
@@ -240,11 +322,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();
@@ -254,10 +335,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
@@ -265,47 +346,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 GzipFilter.
* <p>
- * An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be
- * compressed by the GzipFilter.
+ * 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 assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum, String expectedContentType) throws Exception
{
- assertIsResponseNotGzipFiltered(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 GzipFilter.
* <p>
- * An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be
- * compressed by the GzipFilter.
+ * 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 assertIsResponseNotGzipFiltered(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;
@@ -315,7 +394,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
@@ -328,14 +407,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 GzipFilter)",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
@@ -358,7 +437,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())
{
@@ -379,21 +458,20 @@ public class GzipTester
}
/**
- * 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.
+ * 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.
@@ -405,23 +483,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 GzipFilter 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);
@@ -432,15 +510,15 @@ public class GzipTester
}
/**
- * Asserts that the request results in a properly structured GzipFilter 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);
@@ -454,16 +532,16 @@ 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)));
}
@@ -478,7 +556,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(uri);
response = HttpTester.parseResponse(tester.getResponses(request.generate()));
@@ -492,11 +570,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
{
@@ -506,7 +584,6 @@ public class GzipTester
return actual;
}
-
/**
* Generate string content of arbitrary length.
*
@@ -579,7 +656,7 @@ public class GzipTester
finally
{
IO.close(in);
- IO.close(fos);
+ IO.close(fos);
}
}
@@ -611,9 +688,17 @@ public class GzipTester
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
servletHolder.setInitParameter("etags","true");
- FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.of(DispatcherType.REQUEST));
- holder.setInitParameter("vary","Accept-Encoding");
- return holder;
+
+ if (gzipFilterClass != null)
+ {
+ FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.of(DispatcherType.REQUEST));
+ holder.setInitParameter("vary","Accept-Encoding");
+ return holder;
+ }
+ else
+ {
+ return null;
+ }
}
public Class<? extends Filter> getGzipFilterClass()
@@ -635,22 +720,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
{
@@ -664,4 +768,5 @@ public class GzipTester
e.printStackTrace(System.err);
}
}
+
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/PassThruInputStream.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/PassThruInputStream.java
new file mode 100644
index 0000000000..3b4af548e3
--- /dev/null
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/PassThruInputStream.java
@@ -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.servlets.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);
+ }
+}
diff --git a/jetty-servlets/src/test/resources/jetty-logging.properties b/jetty-servlets/src/test/resources/jetty-logging.properties
index a280c75884..65026397c6 100644
--- a/jetty-servlets/src/test/resources/jetty-logging.properties
+++ b/jetty-servlets/src/test/resources/jetty-logging.properties
@@ -1,6 +1,7 @@
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.servlet.ServletTester.LEVEL=DEBUG
#org.eclipse.jetty.servlets.GzipFilter.LEVEL=DEBUG
#org.eclipse.jetty.servlets.QoSFilter.LEVEL=DEBUG
#org.eclipse.jetty.servlets.DoSFilter.LEVEL=DEBUG

Back to the top