Beefing up GzipFilter tests

This commit is contained in:
Joakim Erdfelt 2011-08-11 13:20:31 -07:00
parent d496a4f80a
commit da8f5052a3
47 changed files with 1083 additions and 391 deletions

View File

@ -0,0 +1,146 @@
package org.eclipse.jetty.servlets;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Servlet;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.servlets.gzip.TestServletLengthTypeStreamWrite;
import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWrite;
import org.eclipse.jetty.servlets.gzip.TestServletStreamTypeLengthWrite;
import org.eclipse.jetty.servlets.gzip.TestServletTypeLengthStreamWrite;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Test the GzipFilter support for Content-Length setting variations.
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@RunWith(Parameterized.class)
public class GzipFilterContentLengthTest
{
/**
* These are the junit parameters for running this test.
* <p>
* We have 4 test servlets, that arrange the content-length/content-type/get stream in different orders so as to
* simulate the real world scenario that caused the bug in <a
* href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
* <p>
* This test case will be run with each entry in the array below as setup parameters for the test case.
*
* @return the junit parameters
*/
@Parameters
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]
{
{ TestServletLengthTypeStreamWrite.class },
{ TestServletStreamLengthTypeWrite.class },
{ TestServletStreamTypeLengthWrite.class },
{ TestServletTypeLengthStreamWrite.class } });
}
private static final int LARGE = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 8;
private static final int MEDIUM = GzipResponseWrapper.DEFAULT_BUFFER_SIZE;
private static final int SMALL = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
@Rule
public TestingDir testingdir = new TestingDir();
private Class<? extends Servlet> testServlet;
public GzipFilterContentLengthTest(Class<? extends Servlet> testServlet)
{
this.testServlet = testServlet;
}
private void assertIsGzipCompressed(Class<? extends Servlet> servletClass, int filesize) throws Exception
{
GzipTester tester = new GzipTester(testingdir);
// Test content that is smaller than the buffer.
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(servletClass);
holder.setInitParameter("mimeTypes","text/plain");
try
{
tester.start();
tester.assertIsResponseGzipCompressed("file.txt");
}
finally
{
tester.stop();
}
}
private void assertIsNotGzipCompressed(Class<? extends Servlet> servletClass, int filesize) throws Exception
{
GzipTester tester = new GzipTester(testingdir);
// Test content that is smaller than the buffer.
tester.prepareServerFile("file.mp3",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
try
{
tester.start();
tester.assertIsResponseNotGzipCompressed("file.mp3",filesize);
}
finally
{
tester.stop();
}
}
@Test
public void testIsGzipCompressedTiny() throws Exception
{
assertIsGzipCompressed(testServlet,SMALL);
}
/**
* Tests for Length>Type>Stream>Write problems encountered in GzipFilter
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsGzipCompressedMedium() throws Exception
{
assertIsGzipCompressed(testServlet,MEDIUM);
}
/**
* Tests for Length>Type>Stream>Write problems encountered in GzipFilter
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsGzipCompressedLarge() throws Exception
{
assertIsGzipCompressed(testServlet,LARGE);
}
/**
* Tests for Length>Type>Stream>Write problems encountered in GzipFilter
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@Test
public void testIsNotGzipCompressed() throws Exception
{
assertIsNotGzipCompressed(TestServletLengthTypeStreamWrite.class,LARGE);
}
}

View File

@ -0,0 +1,101 @@
package org.eclipse.jetty.servlets;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
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.Parameters;
/**
* Tests {@link GzipFilter} in combination with {@link DefaultServlet} for
* ability to configure {@link GzipFilter} to ignore recompress situations
* from upstream.
*/
@RunWith(Parameterized.class)
public class GzipFilterDefaultNoRecompressTest
{
@Parameters
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]
{
// Some already compressed files
{ "test_quotes.gz" },
{ "test_quotes.bz2" },
{ "test_quotes.zip" },
{ "test_quotes.rar" },
// Some images (common first)
{ "jetty_logo.png" },
{ "jetty_logo.gif" },
{ "jetty_logo.jpeg" },
{ "jetty_logo.jpg" },
// Lesser encountered images (usually found being requested from non-browser clients)
{ "jetty_logo.bmp" },
{ "jetty_logo.tga" },
{ "jetty_logo.tif" },
{ "jetty_logo.tiff" },
{ "jetty_logo.xcf" },
{ "jetty_logo.jp2" } });
}
@Rule
public TestingDir testingdir = new TestingDir();
private String alreadyCompressedFilename;
public GzipFilterDefaultNoRecompressTest(String testFilename) {
this.alreadyCompressedFilename = testFilename;
}
@Test
@Ignore("Cannot find a configuration that would allow this to pass")
public void testNotGzipFiltered_Default_AlreadyCompressed() throws Exception
{
GzipTester tester = new GzipTester(testingdir);
copyTestFileToServer(alreadyCompressedFilename);
// Using DefaultServlet, with default GzipFilter setup
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
// TODO: find a configuration of the GzipFilter to allow
// each of these test cases to pass.
StringBuilder mimeTypes = new StringBuilder();
mimeTypes.append("images/png");
mimeTypes.append(",images/jpeg");
mimeTypes.append(",images/gif");
mimeTypes.append(",images/jp2");
holder.setInitParameter("mimeTypes", mimeTypes.toString());
try
{
tester.start();
tester.assertIsResponseNotGzipFiltered(alreadyCompressedFilename,
alreadyCompressedFilename + ".sha1");
}
finally
{
tester.stop();
}
}
private void copyTestFileToServer(String testFilename) throws IOException
{
File testFile = MavenTestingUtils.getTestResourceFile(testFilename);
File outFile = testingdir.getFile(testFilename);
IO.copy(testFile,outFile);
}
}

View File

@ -0,0 +1,87 @@
package org.eclipse.jetty.servlets;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Rule;
import org.junit.Test;
/**
* Test the GzipFilter support built into the {@link DefaultServlet}
*/
public class GzipFilterDefaultTest
{
@Rule
public TestingDir testingdir = new TestingDir();
@Test
public void testIsGzipCompressedTiny() throws Exception
{
GzipTester tester = new GzipTester(testingdir);
// Test content that is smaller than the buffer.
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
try
{
tester.start();
tester.assertIsResponseGzipCompressed("file.txt");
}
finally
{
tester.stop();
}
}
@Test
public void testIsGzipCompressedLarge() throws Exception
{
GzipTester tester = new GzipTester(testingdir);
// Test content that is smaller than the buffer.
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
try
{
tester.start();
tester.assertIsResponseGzipCompressed("file.txt");
}
finally
{
tester.stop();
}
}
@Test
public void testIsNotGzipCompressed() throws Exception
{
GzipTester tester = new GzipTester(testingdir);
// Test content that is smaller than the buffer.
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
tester.prepareServerFile("file.mp3",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
try
{
tester.start();
tester.assertIsResponseNotGzipCompressed("file.mp3", filesize);
}
finally
{
tester.stop();
}
}
}

View File

@ -1,171 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class GzipFilterTest
{
public static String __content;
static
{
// The size of content must be greater then
// buffer size in GzipResponseWrapper class.
StringBuilder builder = new StringBuilder();
do
{
builder.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. ");
builder.append("Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque ");
builder.append("habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ");
builder.append("Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam ");
builder.append("at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate ");
builder.append("velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum. ");
builder.append("Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum ");
builder.append("eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa ");
builder.append("sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam ");
builder.append("consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque. ");
builder.append("Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse ");
builder.append("et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.");
}
while (builder.length() < GzipResponseWrapper.DEFAULT_BUFFER_SIZE);
__content = builder.toString();
}
@Rule
public TestingDir testdir = new TestingDir();
protected ServletTester tester;
@Before
public void setUp() throws Exception
{
testdir.ensureEmpty();
File testFile = testdir.getFile("file.txt");
BufferedOutputStream testOut = new BufferedOutputStream(new FileOutputStream(testFile));
ByteArrayInputStream testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
testFile = testdir.getFile("file.mp3");
testOut = new BufferedOutputStream(new FileOutputStream(testFile));
testIn = new ByteArrayInputStream(__content.getBytes("ISO8859_1"));
IO.copy(testIn,testOut);
testOut.close();
tester=new ServletTester();
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
tester.addServlet(getServletClass(), "/");
FilterHolder holder = tester.addFilter(GzipFilter.class,"/*",0);
holder.setInitParameter("mimeTypes","text/plain");
tester.start();
}
@After
public void tearDown() throws Exception
{
tester.stop();
IO.delete(testdir.getDir());
}
public Class<?> getServletClass()
{
return org.eclipse.jetty.servlet.DefaultServlet.class;
}
@Test
public void testGzip() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.txt");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertNotNull("Content-Length header is missing", response.getHeader("Content-Length"));
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
@Test
public void testNotGzip() throws Exception
{
// generated and parsed test
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("accept-encoding","gzip");
request.setURI("/context/file.mp3");
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
ByteArrayBuffer respBuff = tester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
assertTrue(response.getMethod()==null);
assertNotNull("Content-Length header is missing", response.getHeader("Content-Length"));
assertEquals(__content.getBytes().length, Integer.parseInt(response.getHeader("Content-Length")));
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
InputStream testIn = new ByteArrayInputStream(response.getContentBytes());
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
IO.copy(testIn,testOut);
assertEquals(__content, testOut.toString("ISO8859_1"));
}
}

View File

@ -1,56 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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 java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipFilterTest1 extends GzipFilterTest
{
@Override
public Class<?> getServletClass()
{
return TestServlet.class;
}
public static class TestServlet extends HttpServlet
{
private static final long serialVersionUID = -3603297003496724934L;
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
byte[] dataBytes = GzipFilterTest.__content.getBytes("ISO8859_1");
ServletOutputStream out = response.getOutputStream();
response.setContentLength(dataBytes.length);
String fileName = request.getServletPath();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
out.write(dataBytes);
}
}
}

View File

@ -1,54 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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 java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipFilterTest2 extends GzipFilterTest
{
@Override
public Class<?> getServletClass()
{
return TestServlet.class;
}
public static class TestServlet extends HttpServlet
{
private static final long serialVersionUID = -3603297003496724934L;
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
byte[] dataBytes = GzipFilterTest.__content.getBytes("ISO8859_1");
response.setContentLength(dataBytes.length);
String fileName = request.getServletPath();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
ServletOutputStream out = response.getOutputStream();
out.write(dataBytes);
}
}
}

View File

@ -1,56 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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 java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipFilterTest3 extends GzipFilterTest
{
@Override
public Class<?> getServletClass()
{
return TestServlet.class;
}
public static class TestServlet extends HttpServlet
{
private static final long serialVersionUID = -3603297003496724934L;
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
byte[] dataBytes = GzipFilterTest.__content.getBytes("ISO8859_1");
ServletOutputStream out = response.getOutputStream();
String fileName = request.getServletPath();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setContentLength(dataBytes.length);
out.write(dataBytes);
}
}
}

View File

@ -1,54 +0,0 @@
// ========================================================================
// Copyright (c) 2004-2009 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 java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GzipFilterTest4 extends GzipFilterTest
{
@Override
public Class<?> getServletClass()
{
return TestServlet.class;
}
public static class TestServlet extends HttpServlet
{
private static final long serialVersionUID = -3603297003496724934L;
/* ------------------------------------------------------------ */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
byte[] dataBytes = GzipFilterTest.__content.getBytes("ISO8859_1");
String fileName = request.getServletPath();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setContentLength(dataBytes.length);
ServletOutputStream out = response.getOutputStream();
out.write(dataBytes);
}
}
}

View File

@ -0,0 +1,369 @@
package org.eclipse.jetty.servlets.gzip;
import static org.hamcrest.Matchers.*;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Assert;
public class GzipTester
{
private String encoding = "ISO8859_1";
private ServletTester servletTester;
private TestingDir testdir;
public GzipTester(TestingDir testingdir)
{
this.testdir = testingdir;
// Make sure we start with a clean testing directory.
this.testdir.ensureEmpty();
}
public void assertIsResponseGzipCompressed(String filename) throws Exception
{
assertIsResponseGzipCompressed(filename,filename);
}
public void assertIsResponseGzipCompressed(String requestedFilename, String serverFilename) throws Exception
{
System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename);
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding","gzip");
request.setURI("/context/" + requestedFilename);
// Issue the request
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
// Collect the response(s)
ByteArrayBuffer respBuff = servletTester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
// Assert the response headers
Assert.assertThat("Response.method",response.getMethod(),nullValue());
Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue());
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString("gzip"));
// Assert that the decompressed contents are what we expect.
File serverFile = testdir.getFile(serverFilename);
String expected = IO.readToString(serverFile);
String actual = null;
ByteArrayInputStream bais = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try
{
bais = new ByteArrayInputStream(response.getContentBytes());
in = new GZIPInputStream(bais);
out = new ByteArrayOutputStream();
IO.copy(in,out);
actual = out.toString(encoding);
Assert.assertEquals("Uncompressed contents",expected,actual);
}
finally
{
IO.close(out);
IO.close(in);
IO.close(bais);
}
}
/**
* 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.
*
* @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.
*/
public void assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum) throws Exception
{
System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename);
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding","gzip");
request.setURI("/context/" + requestedFilename);
// Issue the request
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
// Collect the response(s)
ByteArrayBuffer respBuff = servletTester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
dumpHeaders(requestedFilename + " / Response Headers",response);
// Assert the response headers
Assert.assertThat(requestedFilename + " / Response.method",response.getMethod(),nullValue());
Assert.assertThat(requestedFilename + " / Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
Assert.assertThat(requestedFilename + " / Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue());
Assert.assertThat(requestedFilename + " / Response.header[Content-Encoding] (should not be recompressed by GzipFilter)",
response.getHeader("Content-Encoding"),nullValue());
Assert.assertThat(requestedFilename + " / Response.header[Content-Type] (should have a Content-Type associated with it)",
response.getHeader("Content-Type"),notNullValue());
ByteArrayInputStream bais = null;
DigestOutputStream digester = null;
try
{
MessageDigest digest = MessageDigest.getInstance("SHA1");
bais = new ByteArrayInputStream(response.getContentBytes());
digester = new DigestOutputStream(new NoOpOutputStream(),digest);
IO.copy(bais,digester);
String actualSha1Sum = Hex.asHex(digest.digest());
String expectedSha1Sum = loadExpectedSha1Sum(testResourceSha1Sum);
Assert.assertEquals(requestedFilename + " / SHA1Sum of content",expectedSha1Sum,actualSha1Sum);
}
finally
{
IO.close(digester);
IO.close(bais);
}
}
private void dumpHeaders(String prefix, HttpTester http)
{
System.out.println(prefix);
@SuppressWarnings("unchecked")
Enumeration<String> names = http.getHeaderNames();
while (names.hasMoreElements())
{
String name = names.nextElement();
String value = http.getHeader(name);
System.out.printf(" [%s] = %s%n",name,value);
}
}
private String loadExpectedSha1Sum(String testResourceSha1Sum) throws IOException
{
File sha1File = MavenTestingUtils.getTestResourceFile(testResourceSha1Sum);
String contents = IO.readToString(sha1File);
Pattern pat = Pattern.compile("^[0-9A-Fa-f]*");
Matcher mat = pat.matcher(contents);
Assert.assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find());
return mat.group();
}
/**
* 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)
* @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)
* @throws Exception
*/
public void assertIsResponseNotGzipCompressed(String filename, int expectedFilesize) throws Exception
{
System.err.printf("[GzipTester] requesting /context/%s%n",filename);
HttpTester request = new HttpTester();
HttpTester response = new HttpTester();
request.setMethod("GET");
request.setVersion("HTTP/1.0");
request.setHeader("Host","tester");
request.setHeader("Accept-Encoding","gzip");
request.setURI("/context/" + filename);
// Issue the request
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
// Collect the response(s)
ByteArrayBuffer respBuff = servletTester.getResponses(reqsBuff);
response.parse(respBuff.asArray());
// Assert the response headers
Assert.assertThat("Response.method",response.getMethod(),nullValue());
Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
if (expectedFilesize != (-1))
{
Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue());
int serverLength = Integer.parseInt(response.getHeader("Content-Length"));
Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize));
}
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString("gzip")));
// Assert that the contents are what we expect.
File serverFile = testdir.getFile(filename);
String expected = IO.readToString(serverFile);
String actual = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try
{
in = new ByteArrayInputStream(response.getContentBytes());
out = new ByteArrayOutputStream();
IO.copy(in,out);
actual = out.toString(encoding);
Assert.assertEquals("Server contents",expected,actual);
}
finally
{
IO.close(out);
IO.close(in);
}
}
/**
* Generate string content of arbitrary length.
*
* @param length
* the length of the string to generate.
* @return the string content.
*/
public String generateContent(int length)
{
StringBuilder builder = new StringBuilder();
do
{
builder.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc.\n");
builder.append("Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque\n");
builder.append("habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\n");
builder.append("Vestibulum sit amet felis augue, vel convallis dolor. Cras accumsan vehicula diam\n");
builder.append("at faucibus. Etiam in urna turpis, sed congue mi. Morbi et lorem eros. Donec vulputate\n");
builder.append("velit in risus suscipit lobortis. Aliquam id urna orci, nec sollicitudin ipsum.\n");
builder.append("Cras a orci turpis. Donec suscipit vulputate cursus. Mauris nunc tellus, fermentum\n");
builder.append("eu auctor ut, mollis at diam. Quisque porttitor ultrices metus, vitae tincidunt massa\n");
builder.append("sollicitudin a. Vivamus porttitor libero eget purus hendrerit cursus. Integer aliquam\n");
builder.append("consequat mauris quis luctus. Cras enim nibh, dignissim eu faucibus ac, mollis nec neque.\n");
builder.append("Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse\n");
builder.append("et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.\n");
}
while (builder.length() < length);
// Make sure we are exactly at requested length. (truncate the extra)
if (builder.length() > length)
{
builder.setLength(length);
}
return builder.toString();
}
public String getEncoding()
{
return encoding;
}
/**
* Create a file on the server resource path of a specified filename and size.
*
* @param filename
* the filename to create
* @param filesize
* the file size to create (Note: this isn't suitable for creating large multi-megabyte files)
*/
public void prepareServerFile(String filename, int filesize) throws IOException
{
File testFile = testdir.getFile(filename);
FileOutputStream fos = null;
BufferedOutputStream out = null;
ByteArrayInputStream in = null;
try
{
fos = new FileOutputStream(testFile,false);
out = new BufferedOutputStream(fos);
in = new ByteArrayInputStream(generateContent(filesize).getBytes(encoding));
IO.copy(in,out);
}
finally
{
IO.close(in);
IO.close(out);
IO.close(fos);
}
}
/**
* Set the servlet that provides content for the GzipFilter in being tested.
*
* @param servletClass
* the servlet that will provide content.
* @return the FilterHolder for configuring the GzipFilter's initParameters with
*/
public FilterHolder setContentServlet(Class<? extends Servlet> servletClass) throws IOException
{
servletTester = new ServletTester();
servletTester.setContextPath("/context");
servletTester.setResourceBase(testdir.getDir().getCanonicalPath());
ServletHolder servletHolder = servletTester.addServlet(servletClass,"/");
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
FilterHolder holder = servletTester.addFilter(GzipFilter.class,"/*",0);
return holder;
}
public void setEncoding(String encoding)
{
this.encoding = encoding;
}
public void start() throws Exception
{
Assert.assertThat("No servlet defined yet. Did you use #setContentServlet()?",servletTester,notNullValue());
servletTester.dump();
servletTester.start();
}
public void stop()
{
// NOTE: Do not cleanup the testdir. Failures can't be diagnosed if you do that.
// IO.delete(testdir.getDir()):
try
{
servletTester.stop();
}
catch (Exception e)
{
// Don't toss this out into Junit as this would be the last exception
// that junit will report as being the cause of the test failure.
// when in reality, the earlier setup issue is the real cause.
e.printStackTrace(System.err);
}
}
}

View File

@ -0,0 +1,58 @@
package org.eclipse.jetty.servlets.gzip;
public final class Hex
{
private static final char[] hexcodes = "0123456789abcdef".toCharArray();
public static byte[] asByteArray(String id, int size)
{
if ((id.length() < 0) || (id.length() > (size * 2)))
{
throw new IllegalArgumentException(String.format("Invalid ID length of <%d> expected range of <0> to <%d>",id.length(),(size * 2)));
}
byte buf[] = new byte[size];
byte hex;
int len = id.length();
int idx = (int)Math.floor(((size * 2) - (double)len) / 2);
int i = 0;
if ((len % 2) != 0)
{ // deal with odd numbered chars
i -= 1;
}
for (; i < len; i++)
{
hex = 0;
if (i >= 0)
{
hex = (byte)(Character.digit(id.charAt(i),16) << 4);
}
i++;
hex += (byte)(Character.digit(id.charAt(i),16));
buf[idx] = hex;
idx++;
}
return buf;
}
public static String asHex(byte buf[])
{
int len = buf.length;
char out[] = new char[len * 2];
for (int i = 0; i < len; i++)
{
out[i * 2] = hexcodes[(buf[i] & 0xF0) >> 4];
out[(i * 2) + 1] = hexcodes[(buf[i] & 0x0F)];
}
return String.valueOf(out);
}
private Hex()
{
/* prevent instantiation */
}
}

View File

@ -0,0 +1,40 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.IOException;
import java.io.OutputStream;
/**
* Stream that does nothing. (Used by SHA1SUM routines)
*/
public class NoOpOutputStream extends OutputStream
{
@Override
public void close() throws IOException
{
/* noop */
}
@Override
public void flush() throws IOException
{
/* noop */
}
@Override
public void write(byte[] b) throws IOException
{
/* noop */
}
@Override
public void write(byte[] b, int off, int len) throws IOException
{
/* noop */
}
@Override
public void write(int b) throws IOException
{
/* noop */
}
}

View File

@ -0,0 +1,56 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.util.IO;
@SuppressWarnings("serial")
public class TestDirContentServlet extends HttpServlet
{
private File basedir;
@Override
public void init(ServletConfig config) throws ServletException
{
basedir = new File(config.getInitParameter("baseDir"));
}
public File getTestFile(String filename)
{
File testfile = new File(basedir,filename);
PathAssert.assertFileExists("Content File should exist",testfile);
return testfile;
}
protected byte[] loadContentFileBytes(final String fileName) throws IOException
{
String relPath = fileName;
relPath = relPath.replaceFirst("^/context/","");
relPath = relPath.replaceFirst("^/","");
File contentFile = getTestFile(relPath);
FileInputStream in = null;
ByteArrayOutputStream out = null;
try
{
in = new FileInputStream(contentFile);
out = new ByteArrayOutputStream();
IO.copy(in,out);
return out.toByteArray();
}
finally
{
IO.close(out);
IO.close(in);
}
}
}

View File

@ -0,0 +1,46 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
*
* Using a real-world pattern of:
*
* <pre>
* 1) set content length
* 2) set content type
* 3) get stream
* 4) write
* </pre>
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@SuppressWarnings("serial")
public class TestServletLengthTypeStreamWrite extends TestDirContentServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
ServletOutputStream out = response.getOutputStream();
out.write(dataBytes);
}
}

View File

@ -0,0 +1,47 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
*
* Using a real-world pattern of:
*
* <pre>
* 1) get stream
* 2) set content length
* 3) set content type
* 4) write
* </pre>
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@SuppressWarnings("serial")
public class TestServletStreamLengthTypeWrite extends TestDirContentServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
ServletOutputStream out = response.getOutputStream();
response.setContentLength(dataBytes.length);
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
out.write(dataBytes);
}
}

View File

@ -0,0 +1,47 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
*
* Using a real-world pattern of:
*
* <pre>
* 1) get stream
* 2) set content type
* 2) set content length
* 4) write
* </pre>
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@SuppressWarnings("serial")
public class TestServletStreamTypeLengthWrite extends TestDirContentServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
ServletOutputStream out = response.getOutputStream();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setContentLength(dataBytes.length);
out.write(dataBytes);
}
}

View File

@ -0,0 +1,46 @@
package org.eclipse.jetty.servlets.gzip;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
*
* Using a real-world pattern of:
*
* <pre>
* 1) set content type
* 2) set content length
* 3) get stream
* 4) write
* </pre>
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@SuppressWarnings("serial")
public class TestServletTypeLengthStreamWrite extends TestDirContentServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setContentLength(dataBytes.length);
ServletOutputStream out = response.getOutputStream();
out.write(dataBytes);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -0,0 +1 @@
6d51985fd71ae74564202f98cf993e0390fae3fe jetty_logo.bmp

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1 @@
3bceab0485ead22e90af4f077c10684addd5dcb5 jetty_logo.gif

Binary file not shown.

View File

@ -0,0 +1 @@
c6f62de568243be3afbb7f489ce9096dc1808859 jetty_logo.jp2

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1 @@
c00ce14c7b266640544dc527277995e25d0c91b8 jetty_logo.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1 @@
c00ce14c7b266640544dc527277995e25d0c91b8 jetty_logo.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1 @@
813bfd8bfa2fb8381cc4b296f3b962a24797ed8f jetty_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -0,0 +1 @@
2603caf728690e1fddaf747a3eef8b5cfe20eee4 jetty_logo.tga

Binary file not shown.

View File

@ -0,0 +1 @@
35bbf5d78d6834531d4c43c686bdc49cded4c982 jetty_logo.tif

Binary file not shown.

View File

@ -0,0 +1 @@
3f7fa94449b96c4670b8754850ec8fbe526db3f6 jetty_logo.tiff

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1 @@
3ec782dc77c0b81420317d8d445f8d8c1ec25d84 jetty_logo.xcf

Binary file not shown.

View File

@ -0,0 +1 @@
1f8b327125e1ba9c25804734730dfe5367093216 test_quotes.bz2

Binary file not shown.

View File

@ -0,0 +1 @@
f43ed550786662ba8a245a1769dfaa330c49fdcc test_quotes.gz

Binary file not shown.

View File

@ -0,0 +1 @@
8071787493e74d60a273bc0787d3666968dc9eb9 test_quotes.rar

View File

@ -0,0 +1,19 @@
Quotes attributed to Mark Twain:
+ A person with a new idea is a crank until the idea succeeds.
+ A person who won't read has no advantage over one who can't read.
+ Action speaks louder than words but not nearly as often.
+ Buy land, they're not making it anymore.
+ Good friends, good books and a sleepy conscience: this is the ideal life.
+ It's no wonder that truth is stranger than fiction. Fiction has to make sense
+ My books are like water; those of the great geniuses are wine. (Fortunately) everybody drinks water.
+ My mother had a great deal of trouble with me, but I think she enjoyed it.
+ Name the greatest of all inventors. Accident.
+ Necessity is the mother of taking chances.
+ Never put off till tomorrow what you can do the day after tomorrow.
+ Only one thing is impossible for God: To find any sense in any copyright law on the planet.
+ Part of the secret of a success in life is to eat what you like and let the food fight it out inside.
+ There are lies, damned lies and statistics.

View File

@ -0,0 +1 @@
7dfe23b2baa0ad8fd1673bcbc9b981c4a564492a test_quotes.txt

Binary file not shown.

View File

@ -0,0 +1 @@
bd1edce4dfc9e57b8e55314ee9ac29e3fbb3f671 test_quotes.zip

View File

@ -80,6 +80,12 @@ public class ServletTester
}
}
/* ------------------------------------------------------------ */
public void dump()
{
_server.dump();
}
/* ------------------------------------------------------------ */
public void start() throws Exception
{