diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java new file mode 100644 index 00000000000..f0498fbb18d --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java @@ -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 http://bugs.eclipse.org/354014 + */ +@RunWith(Parameterized.class) +public class GzipFilterContentLengthTest +{ + /** + * These are the junit parameters for running this test. + *

+ * 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 http://bugs.eclipse.org/354014 + *

+ * 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 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 testServlet; + + public GzipFilterContentLengthTest(Class testServlet) + { + this.testServlet = testServlet; + } + + private void assertIsGzipCompressed(Class 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 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 http://bugs.eclipse.org/354014 + */ + @Test + public void testIsGzipCompressedMedium() throws Exception + { + assertIsGzipCompressed(testServlet,MEDIUM); + } + + /** + * Tests for Length>Type>Stream>Write problems encountered in GzipFilter + * + * @see http://bugs.eclipse.org/354014 + */ + @Test + public void testIsGzipCompressedLarge() throws Exception + { + assertIsGzipCompressed(testServlet,LARGE); + } + + /** + * Tests for Length>Type>Stream>Write problems encountered in GzipFilter + * + * @see http://bugs.eclipse.org/354014 + */ + @Test + public void testIsNotGzipCompressed() throws Exception + { + assertIsNotGzipCompressed(TestServletLengthTypeStreamWrite.class,LARGE); + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java new file mode 100644 index 00000000000..88139bcfffe --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultNoRecompressTest.java @@ -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 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); + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java new file mode 100644 index 00000000000..e597c139b1c --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -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(); + } + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java deleted file mode 100644 index feb70a449ed..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest.java +++ /dev/null @@ -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")); - } -} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest1.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest1.java deleted file mode 100644 index bb9a1e20077..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest1.java +++ /dev/null @@ -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); - } - } -} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest2.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest2.java deleted file mode 100644 index 62d6d9cda12..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest2.java +++ /dev/null @@ -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); - } - } -} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest3.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest3.java deleted file mode 100644 index 9fb89e0a17f..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest3.java +++ /dev/null @@ -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); - } - } -} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest4.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest4.java deleted file mode 100644 index b64233319e2..00000000000 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterTest4.java +++ /dev/null @@ -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); - } - } -} 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 new file mode 100644 index 00000000000..f34eb3423b7 --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -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. + *

+ * This is used to test exclusions and passthroughs in 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. + */ + 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 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 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); + } + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/Hex.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/Hex.java new file mode 100644 index 00000000000..ee17583c92b --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/Hex.java @@ -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 */ + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/NoOpOutputStream.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/NoOpOutputStream.java new file mode 100644 index 00000000000..0a3c857a0ab --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/NoOpOutputStream.java @@ -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 */ + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestDirContentServlet.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestDirContentServlet.java new file mode 100644 index 00000000000..440528b332b --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestDirContentServlet.java @@ -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); + } + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java new file mode 100644 index 00000000000..4cf6a4acafe --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletLengthTypeStreamWrite.java @@ -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: + * + *

+ *  1) set content length
+ *  2) set content type
+ *  3) get stream
+ *  4) write
+ * 
+ * + * @see http://bugs.eclipse.org/354014 + */ +@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); + } +} \ No newline at end of file diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java new file mode 100644 index 00000000000..f10d5305ce3 --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamLengthTypeWrite.java @@ -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: + * + *
+ *  1) get stream
+ *  2) set content length
+ *  3) set content type
+ *  4) write
+ * 
+ * + * @see http://bugs.eclipse.org/354014 + */ +@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); + } +} \ No newline at end of file diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java new file mode 100644 index 00000000000..efd5bcdc12e --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletStreamTypeLengthWrite.java @@ -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: + * + *
+ *  1) get stream
+ *  2) set content type
+ *  2) set content length
+ *  4) write
+ * 
+ * + * @see http://bugs.eclipse.org/354014 + */ +@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); + } +} \ No newline at end of file diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java new file mode 100644 index 00000000000..7551d4d4a6a --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/TestServletTypeLengthStreamWrite.java @@ -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: + * + *
+ *  1) set content type
+ *  2) set content length
+ *  3) get stream
+ *  4) write
+ * 
+ * + * @see http://bugs.eclipse.org/354014 + */ +@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); + } +} \ No newline at end of file diff --git a/jetty-servlets/src/test/resources/jetty_logo.bmp b/jetty-servlets/src/test/resources/jetty_logo.bmp new file mode 100644 index 00000000000..461ab66e7a8 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.bmp differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.bmp.sha1 b/jetty-servlets/src/test/resources/jetty_logo.bmp.sha1 new file mode 100644 index 00000000000..b91711fcee4 --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.bmp.sha1 @@ -0,0 +1 @@ +6d51985fd71ae74564202f98cf993e0390fae3fe jetty_logo.bmp diff --git a/jetty-servlets/src/test/resources/jetty_logo.gif b/jetty-servlets/src/test/resources/jetty_logo.gif new file mode 100644 index 00000000000..2baf7e17fe3 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.gif differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.gif.sha1 b/jetty-servlets/src/test/resources/jetty_logo.gif.sha1 new file mode 100644 index 00000000000..38e6dec7b7f --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.gif.sha1 @@ -0,0 +1 @@ +3bceab0485ead22e90af4f077c10684addd5dcb5 jetty_logo.gif diff --git a/jetty-servlets/src/test/resources/jetty_logo.jp2 b/jetty-servlets/src/test/resources/jetty_logo.jp2 new file mode 100644 index 00000000000..271e1142cc5 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.jp2 differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.jp2.sha1 b/jetty-servlets/src/test/resources/jetty_logo.jp2.sha1 new file mode 100644 index 00000000000..b4fe6cd387c --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.jp2.sha1 @@ -0,0 +1 @@ +c6f62de568243be3afbb7f489ce9096dc1808859 jetty_logo.jp2 diff --git a/jetty-servlets/src/test/resources/jetty_logo.jpeg b/jetty-servlets/src/test/resources/jetty_logo.jpeg new file mode 100644 index 00000000000..ea5294349e9 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.jpeg differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.jpeg.sha1 b/jetty-servlets/src/test/resources/jetty_logo.jpeg.sha1 new file mode 100644 index 00000000000..d3801650d8c --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.jpeg.sha1 @@ -0,0 +1 @@ +c00ce14c7b266640544dc527277995e25d0c91b8 jetty_logo.jpeg diff --git a/jetty-servlets/src/test/resources/jetty_logo.jpg b/jetty-servlets/src/test/resources/jetty_logo.jpg new file mode 100644 index 00000000000..ea5294349e9 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.jpg differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.jpg.sha1 b/jetty-servlets/src/test/resources/jetty_logo.jpg.sha1 new file mode 100644 index 00000000000..bc2a2f2d49d --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.jpg.sha1 @@ -0,0 +1 @@ +c00ce14c7b266640544dc527277995e25d0c91b8 jetty_logo.jpg diff --git a/jetty-servlets/src/test/resources/jetty_logo.png b/jetty-servlets/src/test/resources/jetty_logo.png new file mode 100644 index 00000000000..1683ab41555 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.png differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.png.sha1 b/jetty-servlets/src/test/resources/jetty_logo.png.sha1 new file mode 100644 index 00000000000..4d47123e93a --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.png.sha1 @@ -0,0 +1 @@ +813bfd8bfa2fb8381cc4b296f3b962a24797ed8f jetty_logo.png diff --git a/jetty-servlets/src/test/resources/jetty_logo.tga b/jetty-servlets/src/test/resources/jetty_logo.tga new file mode 100644 index 00000000000..c6f771a68be Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.tga differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.tga.sha1 b/jetty-servlets/src/test/resources/jetty_logo.tga.sha1 new file mode 100644 index 00000000000..2406e565929 --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.tga.sha1 @@ -0,0 +1 @@ +2603caf728690e1fddaf747a3eef8b5cfe20eee4 jetty_logo.tga diff --git a/jetty-servlets/src/test/resources/jetty_logo.tif b/jetty-servlets/src/test/resources/jetty_logo.tif new file mode 100644 index 00000000000..6b33ac27801 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.tif differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.tif.sha1 b/jetty-servlets/src/test/resources/jetty_logo.tif.sha1 new file mode 100644 index 00000000000..61ce10a4e96 --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.tif.sha1 @@ -0,0 +1 @@ +35bbf5d78d6834531d4c43c686bdc49cded4c982 jetty_logo.tif diff --git a/jetty-servlets/src/test/resources/jetty_logo.tiff b/jetty-servlets/src/test/resources/jetty_logo.tiff new file mode 100644 index 00000000000..2f5b3971f4c Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.tiff differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.tiff.sha1 b/jetty-servlets/src/test/resources/jetty_logo.tiff.sha1 new file mode 100644 index 00000000000..1550704d40d --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.tiff.sha1 @@ -0,0 +1 @@ +3f7fa94449b96c4670b8754850ec8fbe526db3f6 jetty_logo.tiff diff --git a/jetty-servlets/src/test/resources/jetty_logo.xcf b/jetty-servlets/src/test/resources/jetty_logo.xcf new file mode 100644 index 00000000000..02d91e95277 Binary files /dev/null and b/jetty-servlets/src/test/resources/jetty_logo.xcf differ diff --git a/jetty-servlets/src/test/resources/jetty_logo.xcf.sha1 b/jetty-servlets/src/test/resources/jetty_logo.xcf.sha1 new file mode 100644 index 00000000000..d679a8081a6 --- /dev/null +++ b/jetty-servlets/src/test/resources/jetty_logo.xcf.sha1 @@ -0,0 +1 @@ +3ec782dc77c0b81420317d8d445f8d8c1ec25d84 jetty_logo.xcf diff --git a/jetty-servlets/src/test/resources/test_quotes.bz2 b/jetty-servlets/src/test/resources/test_quotes.bz2 new file mode 100644 index 00000000000..8c01840b38b Binary files /dev/null and b/jetty-servlets/src/test/resources/test_quotes.bz2 differ diff --git a/jetty-servlets/src/test/resources/test_quotes.bz2.sha1 b/jetty-servlets/src/test/resources/test_quotes.bz2.sha1 new file mode 100644 index 00000000000..5008ed045a9 --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.bz2.sha1 @@ -0,0 +1 @@ +1f8b327125e1ba9c25804734730dfe5367093216 test_quotes.bz2 diff --git a/jetty-servlets/src/test/resources/test_quotes.gz b/jetty-servlets/src/test/resources/test_quotes.gz new file mode 100644 index 00000000000..2a0d8e4fcae Binary files /dev/null and b/jetty-servlets/src/test/resources/test_quotes.gz differ diff --git a/jetty-servlets/src/test/resources/test_quotes.gz.sha1 b/jetty-servlets/src/test/resources/test_quotes.gz.sha1 new file mode 100644 index 00000000000..1b32785746b --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.gz.sha1 @@ -0,0 +1 @@ +f43ed550786662ba8a245a1769dfaa330c49fdcc test_quotes.gz diff --git a/jetty-servlets/src/test/resources/test_quotes.rar b/jetty-servlets/src/test/resources/test_quotes.rar new file mode 100644 index 00000000000..c5ab6a053a2 Binary files /dev/null and b/jetty-servlets/src/test/resources/test_quotes.rar differ diff --git a/jetty-servlets/src/test/resources/test_quotes.rar.sha1 b/jetty-servlets/src/test/resources/test_quotes.rar.sha1 new file mode 100644 index 00000000000..6aa4f4a6ed4 --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.rar.sha1 @@ -0,0 +1 @@ +8071787493e74d60a273bc0787d3666968dc9eb9 test_quotes.rar diff --git a/jetty-servlets/src/test/resources/test_quotes.txt b/jetty-servlets/src/test/resources/test_quotes.txt new file mode 100644 index 00000000000..04e2b04d658 --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.txt @@ -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. + + + diff --git a/jetty-servlets/src/test/resources/test_quotes.txt.sha1 b/jetty-servlets/src/test/resources/test_quotes.txt.sha1 new file mode 100644 index 00000000000..fd2f9e96f87 --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.txt.sha1 @@ -0,0 +1 @@ +7dfe23b2baa0ad8fd1673bcbc9b981c4a564492a test_quotes.txt diff --git a/jetty-servlets/src/test/resources/test_quotes.zip b/jetty-servlets/src/test/resources/test_quotes.zip new file mode 100644 index 00000000000..57befe77ac4 Binary files /dev/null and b/jetty-servlets/src/test/resources/test_quotes.zip differ diff --git a/jetty-servlets/src/test/resources/test_quotes.zip.sha1 b/jetty-servlets/src/test/resources/test_quotes.zip.sha1 new file mode 100644 index 00000000000..02f3b00de79 --- /dev/null +++ b/jetty-servlets/src/test/resources/test_quotes.zip.sha1 @@ -0,0 +1 @@ +bd1edce4dfc9e57b8e55314ee9ac29e3fbb3f671 test_quotes.zip diff --git a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java index 8b3958981ac..47cb401bd60 100644 --- a/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java +++ b/test-jetty-servlet/src/main/java/org/eclipse/jetty/testing/ServletTester.java @@ -80,6 +80,12 @@ public class ServletTester } } + /* ------------------------------------------------------------ */ + public void dump() + { + _server.dump(); + } + /* ------------------------------------------------------------ */ public void start() throws Exception {