From cf0c4a2b07df7373397aabade6af1f3f2c7aa86c Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 10 Nov 2022 15:25:22 -0600 Subject: [PATCH] Move GzipDefaultServletTest to jetty-core/jetty-server tests --- .../server/handler/gzip/GzipHandlerTest.java | 939 +++++++- .../jetty-server/src/test/resources/test.svg | 2069 +++++++++++++++++ .../jetty-server/src/test/resources/test.svgz | Bin 0 -> 6916 bytes .../ee10/servlets/GzipDefaultServletTest.java | 1002 -------- 4 files changed, 2946 insertions(+), 1064 deletions(-) create mode 100644 jetty-core/jetty-server/src/test/resources/test.svg create mode 100644 jetty-core/jetty-server/src/test/resources/test.svgz delete mode 100644 jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipDefaultServletTest.java diff --git a/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java b/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java index ac9e8179088..543eacf7ee7 100644 --- a/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java +++ b/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java @@ -15,39 +15,60 @@ package org.eclipse.jetty.server.handler.gzip; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; import org.eclipse.jetty.http.CompressedContentFormat; +import org.eclipse.jetty.http.DateGenerator; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpTester; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.Content; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.toolchain.test.FS; +import org.eclipse.jetty.toolchain.test.MavenPaths; +import org.eclipse.jetty.toolchain.test.Sha1Sum; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.LifeCycle; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; @@ -56,7 +77,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; @@ -65,12 +88,15 @@ import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; public class GzipHandlerTest { - private static final String __content = + protected static final int DEFAULT_OUTPUT_BUFFER_SIZE = new HttpConfiguration().getOutputBufferSize(); + + private static final String CONTENT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. " + "Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque " + "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. " + @@ -84,19 +110,19 @@ public class GzipHandlerTest "Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse " + "et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque."; - private static final byte[] __bytes = __content.getBytes(StandardCharsets.UTF_8); + private static final byte[] CONTENT_BYTES = CONTENT.getBytes(StandardCharsets.UTF_8); - private static final String __micro = __content.substring(0, 10); + private static final String MICRO = CONTENT.substring(0, 10); - private static final String __contentETag = String.format("W/\"%x\"", __content.hashCode()); - private static final String __contentETagGzip = String.format("W/\"%x" + CompressedContentFormat.GZIP.getEtagSuffix() + "\"", __content.hashCode()); - private static final String __icontent = "BEFORE" + __content + "AFTER"; + private static final String CONTENT_ETAG = String.format("W/\"%x\"", CONTENT.hashCode()); + private static final String CONTENT_ETAG_GZIP = String.format("W/\"%x" + CompressedContentFormat.GZIP.getEtagSuffix() + "\"", CONTENT.hashCode()); - private static final MimeTypes __mimeTypes = new MimeTypes(); + private static final MimeTypes MIME_TYPES = new MimeTypes(); + public WorkDir _workDir; private Server _server; private LocalConnector _connector; - private GzipHandler _gziphandler; + private GzipHandler _gzipHandler; private ContextHandler _contextHandler; @BeforeEach @@ -109,13 +135,13 @@ public class GzipHandlerTest CheckHandler checkHandler = new CheckHandler(); _server.setHandler(checkHandler); - _gziphandler = new GzipHandler(); - _gziphandler.setMinGzipSize(16); - _gziphandler.setInflateBufferSize(4096); - checkHandler.setHandler(_gziphandler); + _gzipHandler = new GzipHandler(); + _gzipHandler.setMinGzipSize(16); + _gzipHandler.setInflateBufferSize(4096); + checkHandler.setHandler(_gzipHandler); _contextHandler = new ContextHandler("/ctx"); - _gziphandler.setHandler(_contextHandler); + _gzipHandler.setHandler(_contextHandler); } public static class MicroHandler extends Handler.Processor @@ -123,13 +149,13 @@ public class GzipHandlerTest @Override public void process(Request request, Response response, Callback callback) throws Exception { - response.getHeaders().put("ETag", __contentETag); + response.getHeaders().put("ETag", CONTENT_ETAG); String ifnm = request.getHeaders().get("If-None-Match"); - if (ifnm != null && ifnm.equals(__contentETag)) + if (ifnm != null && ifnm.equals(CONTENT_ETAG)) Response.writeError(request, response, callback, 304); else { - Content.Sink.write(response, true, __micro, callback); + Content.Sink.write(response, true, MICRO, callback); } } } @@ -139,7 +165,7 @@ public class GzipHandlerTest @Override public void process(Request request, Response response, Callback callback) throws Exception { - Content.Sink.write(response, false, __micro, callback); + Content.Sink.write(response, false, MICRO, callback); } } @@ -162,7 +188,7 @@ public class GzipHandlerTest // TODO get mime type from context. Context context = request.getContext(); - String contentType = __mimeTypes.getMimeByExtension(filename); + String contentType = MIME_TYPES.getMimeByExtension(filename); if (contentType != null) return contentType; return defaultContentType; @@ -183,18 +209,18 @@ public class GzipHandlerTest Fields parameters = Request.extractQueryParameters(request); if (parameters.get("vary") != null) response.getHeaders().add("Vary", parameters.get("vary").getValue()); - response.getHeaders().put("ETag", __contentETag); + response.getHeaders().put("ETag", CONTENT_ETAG); String ifnm = request.getHeaders().get("If-None-Match"); - if (ifnm != null && ifnm.equals(__contentETag)) + if (ifnm != null && ifnm.equals(CONTENT_ETAG)) Response.writeError(request, response, callback, HttpStatus.NOT_MODIFIED_304); else - Content.Sink.write(response, true, __content, callback); + Content.Sink.write(response, true, CONTENT, callback); } void doDelete(Request request, Response response, Callback callback) throws IOException { String ifm = request.getHeaders().get("If-Match"); - if (ifm != null && ifm.equals(__contentETag)) + if (ifm != null && ifm.equals(CONTENT_ETAG)) Response.writeError(request, response, callback, HttpStatus.NO_CONTENT_204); else Response.writeError(request, response, callback, HttpStatus.NOT_MODIFIED_304); @@ -211,15 +237,15 @@ public class GzipHandlerTest byte[] bytes; String size = parameters.getValue("bufferSize"); if (size == null) - bytes = __bytes; + bytes = CONTENT_BYTES; else { int s = Integer.parseInt(size); bytes = new byte[s]; while (s > 0) { - int l = Math.min(__bytes.length, s); - System.arraycopy(__bytes, 0, bytes, bytes.length - s, l); + int l = Math.min(CONTENT_BYTES.length, s); + System.arraycopy(CONTENT_BYTES, 0, bytes, bytes.length - s, l); s = s - l; } } @@ -263,13 +289,19 @@ public class GzipHandlerTest public static class BufferHandler extends Handler.Processor { + private final ByteBuffer byteBuffer; + + public BufferHandler(byte[] bytes) + { + this.byteBuffer = BufferUtil.toBuffer(bytes).asReadOnlyBuffer(); + } + @Override public void process(Request request, Response response, Callback callback) throws Exception { - ByteBuffer buffer = BufferUtil.toBuffer(__bytes).asReadOnlyBuffer(); - response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, buffer.remaining()); + response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, byteBuffer.remaining()); response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain"); - response.write(true, buffer, callback); + response.write(true, byteBuffer, callback); } } @@ -306,8 +338,133 @@ public class GzipHandlerTest @AfterEach public void destroy() throws Exception { - _server.stop(); - _server.join(); + LifeCycle.stop(_server); + } + + /** + * Generate semi-realistic text content of arbitrary length. + *

+ * Note: We don't just create a single string of repeating characters + * as that doesn't test the gzip behavior very well. (too efficient) + * We also don't just generate a random byte array as that is the opposite + * extreme of gzip handling (terribly inefficient). + *

+ * + * @param length the length of the content to generate. + * @return the content. + */ + private byte[] generateContent(int length) + { + StringBuilder builder = new StringBuilder(); + do + { + builder.append(CONTENT); + } + 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().getBytes(UTF_8); + } + + public static class UncompressedMetadata + { + public byte[] uncompressedContent; + public int contentLength; + public String uncompressedSha1Sum; + public int uncompressedSize; + + public String getContentUTF8() + { + return new String(uncompressedContent, UTF_8); + } + } + + protected FilterInputStream newContentEncodingFilterInputStream(String contentEncoding, InputStream inputStream) throws IOException + { + if (contentEncoding == null) + { + return new FilterInputStream(inputStream) {}; + } + else if (contentEncoding.contains(GzipHandler.GZIP)) + { + return new GZIPInputStream(inputStream); + } + else if (contentEncoding.contains(GzipHandler.DEFLATE)) + { + return new InflaterInputStream(inputStream, new Inflater(true)); + } + throw new RuntimeException("Unexpected response content-encoding: " + contentEncoding); + } + + protected UncompressedMetadata parseResponseContent(HttpTester.Response response) throws NoSuchAlgorithmException, IOException + { + UncompressedMetadata metadata = new UncompressedMetadata(); + metadata.contentLength = response.getContentBytes().length; + + String contentEncoding = response.get("Content-Encoding"); + MessageDigest digest = MessageDigest.getInstance("SHA1"); + + try (ByteArrayInputStream bais = new ByteArrayInputStream(response.getContentBytes()); + FilterInputStream streamFilter = newContentEncodingFilterInputStream(contentEncoding, bais); + ByteArrayOutputStream uncompressedStream = new ByteArrayOutputStream(metadata.contentLength); + DigestOutputStream digester = new DigestOutputStream(uncompressedStream, digest)) + { + org.eclipse.jetty.toolchain.test.IO.copy(streamFilter, digester); + metadata.uncompressedContent = uncompressedStream.toByteArray(); + metadata.uncompressedSize = metadata.uncompressedContent.length; + metadata.uncompressedSha1Sum = StringUtil.toHexString(digest.digest()).toUpperCase(Locale.ENGLISH); + return metadata; + } + } + + @ParameterizedTest + @ValueSource(strings = {"POST", "WIBBLE", "GET", "HEAD"}) + public void testIsGzipByMethod(String method) throws Exception + { + _gzipHandler.setIncludedMethods("POST", "WIBBLE", "GET", "HEAD"); + + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 8; + byte[] buffer = generateContent(fileSize); + _contextHandler.setHandler(new BufferHandler(buffer)); + String expectedSha1Sum = Sha1Sum.calculate(buffer); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod(method); // The point of this test + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Content-Length]", response.get("Content-Length"), is(nullValue())); + + // A HEAD request should have similar headers, but no body + if (!method.equals("HEAD")) + { + assertThat("Response[Content-Length]", response.get("Content-Length"), is(nullValue())); + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } } @Test @@ -329,14 +486,14 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), not(equalToIgnoringCase("gzip"))); - assertThat(response.get("ETag"), is(__contentETag)); - assertThat(response.getCSV("Vary", false), Matchers.contains("Other", "Accept-Encoding")); + assertThat(response.get("ETag"), is(CONTENT_ETAG)); + assertThat(response.getCSV("Vary", false), contains("Other", "Accept-Encoding")); InputStream testIn = new ByteArrayInputStream(response.getContentBytes()); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__content, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(CONTENT, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -359,14 +516,14 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.get("ETag"), is(__contentETagGzip)); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding", "Other")); + assertThat(response.get("ETag"), is(CONTENT_ETAG_GZIP)); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding", "Other")); InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__content, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(CONTENT, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -389,19 +546,19 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding")); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__content, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(CONTENT, testOut.toString(StandardCharsets.UTF_8)); } @Test public void testBufferResponse() throws Exception { - _contextHandler.setHandler(new BufferHandler()); + _contextHandler.setHandler(new BufferHandler(CONTENT_BYTES)); _server.start(); // generated and parsed test @@ -418,13 +575,13 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding")); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__content, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(CONTENT, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -448,7 +605,7 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding")); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); @@ -458,7 +615,7 @@ public class GzipHandlerTest for (int i = 0; i < writes; i++) { - assertEquals(__content, new String(Arrays.copyOfRange(bytes, i * __bytes.length, (i + 1) * __bytes.length), StandardCharsets.UTF_8), "chunk " + i); + assertEquals(CONTENT, new String(Arrays.copyOfRange(bytes, i * CONTENT_BYTES.length, (i + 1) * CONTENT_BYTES.length), StandardCharsets.UTF_8), "chunk " + i); } } @@ -517,7 +674,7 @@ public class GzipHandlerTest if (gzipped) { assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding")); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); ByteArrayInputStream rawContentStream = new ByteArrayInputStream(response.getContentBytes()); InputStream testIn = new GZIPInputStream(rawContentStream); @@ -534,8 +691,8 @@ public class GzipHandlerTest int remaining = bufferSize; while (remaining > 0) { - int len = Math.min(__bytes.length, remaining); - System.arraycopy(__bytes, 0, expectedBuffer, bufferSize - remaining, len); + int len = Math.min(CONTENT_BYTES.length, remaining); + System.arraycopy(CONTENT_BYTES, 0, expectedBuffer, bufferSize - remaining, len); remaining -= len; } @@ -558,7 +715,7 @@ public class GzipHandlerTest _server.start(); int writes = 0; - _gziphandler.setMinGzipSize(0); + _gzipHandler.setMinGzipSize(0); // generated and parsed test HttpTester.Request request = HttpTester.newRequest(); @@ -574,7 +731,665 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding")); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); + } + + /** + * Gzip when the produced response body content is zero bytes in length. + */ + @Test + public void testIsGzipCompressedEmpty() throws Exception + { + _contextHandler.setHandler(new BufferHandler(new byte[0])); + _server.start(); + + // don't set minGzipSize, use default + + // generated and parsed test + HttpTester.Request request = HttpTester.newRequest(); + HttpTester.Response response; + + request.setMethod("GET"); + request.setURI("/ctx/empty"); + request.setVersion("HTTP/1.1"); + request.setHeader("Connection", "close"); + request.setHeader("Host", "tester"); + request.setHeader("Accept-Encoding", "gzip"); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(), is(200)); + assertThat(response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding")); + } + + public static Stream compressibleSizesSource() + { + return Stream.of( + DEFAULT_OUTPUT_BUFFER_SIZE / 4, + DEFAULT_OUTPUT_BUFFER_SIZE, + DEFAULT_OUTPUT_BUFFER_SIZE * 4); + } + + @ParameterizedTest + @MethodSource("compressibleSizesSource") + public void testIsGzipCompressed(int fileSize) throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @ParameterizedTest + @MethodSource("compressibleSizesSource") + public void testIsGzipCompressedIfModifiedSince(int fileSize) throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + Instant fourSecondsAgo = Instant.now().minusSeconds(4); + request.setHeader("If-Modified-Since", DateGenerator.formatDate(fourSecondsAgo.toEpochMilli())); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[ETag]", response.get("ETag"), startsWith("W/")); + assertThat("Response[ETag]", response.get("ETag"), containsString(CompressedContentFormat.GZIP.getEtagSuffix())); + assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testGzippedIfSVG() throws Exception + { + _gzipHandler.addIncludedMimeTypes("image/svg+xml"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + Path testResource = MavenPaths.findTestResourceFile("test.svg"); + Path file = contextDir.resolve("test.svg"); + Files.copy(testResource, file); + String expectedSha1Sum = Sha1Sum.calculate(testResource); + int fileSize = (int)Files.size(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/test.svg"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + /** + * Test what happens if GzipHandler encounters content that is already compressed by + * a handler that isn't GzipHandler. + * + *

+ * We use ResourceHandler and the precompressed content behaviors to simulate this + * condition. + *

+ */ + @Test + public void testIsNotGzipCompressedSVGZ() throws Exception + { + _gzipHandler.addIncludedMimeTypes("image/svg+xml"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + resourceHandler.setGzipEquivalentFileExtensions(List.of(".svgz")); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File (a precompressed file) + Path testResource = MavenPaths.findTestResourceFile("test.svgz"); + Path file = contextDir.resolve("test.svgz"); + Files.copy(testResource, file); + int fileSize = (int)Files.size(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/test.svgz"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Header checks + assertThat("Response[Content-Type]", response.get("Content-Type"), containsString("image/svg+xml")); + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + } + + /** + * Gzip incorrectly gzips when {@code Accept-Encoding: gzip; q=0}. + * + *

+ * A quality of 0 results in no compression. + *

+ * + * See: Bugzilla #388072 + */ + @Test + public void testIsNotGzipCompressedWithZeroQ() throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE / 4; + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip; q=0"); // TESTING THIS + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testIsGzipCompressedWithQ() throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE / 4; + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "something; q=0.1, gzip; q=0.5"); // TESTING THIS + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testIsNotGzipCompressedByContentType() throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; + Path file = Files.write(contextDir.resolve("file.mp3"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.mp3"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testIsNotGzipCompressedByExcludedContentType() throws Exception + { + _gzipHandler.addExcludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testIsNotGzipCompressedByExcludedContentTypeWithCharset() throws Exception + { + _gzipHandler.addExcludedMimeTypes("text/plain"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; + Path file = Files.write(contextDir.resolve("test_quotes.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/test_quotes.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testExcludePaths() throws Exception + { + _gzipHandler.addIncludedMimeTypes("text/plain"); + _gzipHandler.setExcludedPaths("*.txt"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); + } + + @Test + public void testIncludedPaths() throws Exception + { + _gzipHandler.setExcludedPaths("/ctx/bad.txt"); + _gzipHandler.setIncludedPaths("*.txt"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + Path fileGood = Files.write(contextDir.resolve("file.txt"), generateContent(DEFAULT_OUTPUT_BUFFER_SIZE * 4)); + Path fileBad = Files.write(contextDir.resolve("bad.txt"), generateContent(DEFAULT_OUTPUT_BUFFER_SIZE * 2)); + String expectedGoodSha1Sum = Sha1Sum.calculate(fileGood); + String expectedBadSha1Sum = Sha1Sum.calculate(fileBad); + + _server.start(); + + // Test Request 1 + { + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); + assertThat("Response[Vary]", response.get("Vary"), is("Accept-Encoding")); + + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is((int)Files.size(fileGood))); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedGoodSha1Sum)); + } + + // Test Request 2 + { + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/bad.txt"); + + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + UncompressedMetadata metadata = parseResponseContent(response); + int fileSize = (int)Files.size(fileBad); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedBadSha1Sum)); + } + } + + @Test + public void testUpperCaseMimeType() throws Exception + { + _gzipHandler.addExcludedMimeTypes("text/PLAIN"); + + Path contextDir = _workDir.getEmptyPathDir().resolve("context"); + FS.ensureDirExists(contextDir); + + _contextHandler.setBaseResourceAsPath(contextDir); + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setEtags(true); + _contextHandler.setHandler(resourceHandler); + + // Prepare Server File + int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; + Path file = Files.write(contextDir.resolve("file.txt"), generateContent(fileSize)); + String expectedSha1Sum = Sha1Sum.calculate(file); + + _server.start(); + + // Setup request + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setVersion(HttpVersion.HTTP_1_1); + request.setHeader("Host", "tester"); + request.setHeader("Connection", "close"); + request.setHeader("Accept-Encoding", "gzip"); + request.setURI("/ctx/file.txt"); + + // Issue request + ByteBuffer rawResponse = _connector.getResponse(request.generate(), 5, TimeUnit.SECONDS); + + // Parse response + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); + + // Response Content-Encoding check + assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); + assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); + + // Response Content checks + UncompressedMetadata metadata = parseResponseContent(response); + assertThat("Response Content Length", metadata.contentLength, is(fileSize)); + assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); + assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); } @Test @@ -598,14 +1413,14 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), Matchers.equalToIgnoringCase("gzip")); - assertThat(response.get("ETag"), is(__contentETagGzip)); - assertThat(response.getCSV("Vary", false), Matchers.contains("Accept-Encoding", "Other")); + assertThat(response.get("ETag"), is(CONTENT_ETAG_GZIP)); + assertThat(response.getCSV("Vary", false), contains("Accept-Encoding", "Other")); InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes())); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__content, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(CONTENT, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -628,14 +1443,14 @@ public class GzipHandlerTest assertThat(response.getStatus(), is(200)); assertThat(response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat(response.get("ETag"), is(__contentETag)); + assertThat(response.get("ETag"), is(CONTENT_ETAG)); assertThat(response.get("Vary"), is("Accept-Encoding")); InputStream testIn = new ByteArrayInputStream(response.getContentBytes()); ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__micro, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(MICRO, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -667,7 +1482,7 @@ public class GzipHandlerTest ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn, testOut); - assertEquals(__micro, testOut.toString(StandardCharsets.UTF_8)); + assertEquals(MICRO, testOut.toString(StandardCharsets.UTF_8)); } @Test @@ -684,14 +1499,14 @@ public class GzipHandlerTest request.setURI("/ctx/content"); request.setVersion("HTTP/1.0"); request.setHeader("Host", "tester"); - request.setHeader("If-None-Match", __contentETag); + request.setHeader("If-None-Match", CONTENT_ETAG); request.setHeader("accept-encoding", "gzip"); response = HttpTester.parseResponse(_connector.getResponse(request.generate())); assertThat(response.getStatus(), is(304)); assertThat(response.get("Content-Encoding"), not(Matchers.equalToIgnoringCase("gzip"))); - assertThat(response.get("ETag"), is(__contentETag)); + assertThat(response.get("ETag"), is(CONTENT_ETAG)); } @Test @@ -708,14 +1523,14 @@ public class GzipHandlerTest request.setURI("/ctx/content"); request.setVersion("HTTP/1.0"); request.setHeader("Host", "tester"); - request.setHeader("If-None-Match", __contentETagGzip); + request.setHeader("If-None-Match", CONTENT_ETAG_GZIP); request.setHeader("accept-encoding", "gzip"); response = HttpTester.parseResponse(_connector.getResponse(request.generate())); assertThat(response.getStatus(), is(304)); assertThat(response.get("Content-Encoding"), not(Matchers.equalToIgnoringCase("gzip"))); - assertThat(response.get("ETag"), is(__contentETagGzip)); + assertThat(response.get("ETag"), is(CONTENT_ETAG_GZIP)); } @Test @@ -744,7 +1559,7 @@ public class GzipHandlerTest request.setURI("/ctx/content"); request.setVersion("HTTP/1.0"); request.setHeader("Host", "tester"); - request.setHeader("If-Match", __contentETagGzip); + request.setHeader("If-Match", CONTENT_ETAG_GZIP); request.setHeader("accept-encoding", "gzip"); response = HttpTester.parseResponse(_connector.getResponse(request.generate())); @@ -759,8 +1574,8 @@ public class GzipHandlerTest _contextHandler.setHandler(new EchoHandler()); _server.start(); - _gziphandler.addExcludedInflationPaths("/ctx/echo/exclude"); - _gziphandler.addIncludedInflationPaths("/ctx/echo/include"); + _gzipHandler.addExcludedInflationPaths("/ctx/echo/exclude"); + _gzipHandler.addIncludedInflationPaths("/ctx/echo/include"); String message = "hello world"; byte[] gzippedMessage = gzipContent(message); @@ -954,7 +1769,7 @@ public class GzipHandlerTest // setting all excluded mime-types to a mimetype new mime-type // Note: this mime-type does not exist in MimeTypes object. - _gziphandler.setExcludedMimeTypes("image/webfoo"); + _gzipHandler.setExcludedMimeTypes("image/webfoo"); // generated and parsed test HttpTester.Request request = HttpTester.newRequest(); diff --git a/jetty-core/jetty-server/src/test/resources/test.svg b/jetty-core/jetty-server/src/test/resources/test.svg new file mode 100644 index 00000000000..6f65269c10b --- /dev/null +++ b/jetty-core/jetty-server/src/test/resources/test.svg @@ -0,0 +1,2069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-core/jetty-server/src/test/resources/test.svgz b/jetty-core/jetty-server/src/test/resources/test.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c4d595ffd0a9ec7e5a8d7d86c51b3121ac1cd921 GIT binary patch literal 6916 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 K{07oO76AZ9pm`(! literal 0 HcmV?d00001 diff --git a/jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipDefaultServletTest.java b/jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipDefaultServletTest.java deleted file mode 100644 index 3a5ca01015f..00000000000 --- a/jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipDefaultServletTest.java +++ /dev/null @@ -1,1002 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.servlets; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Instant; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee10.servlet.DefaultServlet; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.http.CompressedContentFormat; -import org.eclipse.jetty.http.DateGenerator; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.HttpTester; -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.LocalConnector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.eclipse.jetty.toolchain.test.FS; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.Sha1Sum; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.component.LifeCycle; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.Matchers.startsWith; - -/** - * Test the GzipHandler support when working with the {@link DefaultServlet}. - */ -@Disabled // TODO move to core -public class GzipDefaultServletTest extends AbstractGzipTest -{ - private Server server; - - @AfterEach - public void stopServer() - { - LifeCycle.stop(server); - } - - @ParameterizedTest - @ValueSource(strings = {"POST", "WIBBLE", "GET", "HEAD"}) - public void testIsGzipByMethod(String method) throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.setIncludedMethods("POST", "WIBBLE", "GET", "HEAD"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", WibbleDefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 8; - - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod(method); // The point of this test - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[ETag]", response.get("ETag"), startsWith("W/")); - assertThat("Response[ETag]", response.get("ETag"), containsString(CompressedContentFormat.GZIP.getEtagSuffix())); - - assertThat("Response[Content-Length]", response.get("Content-Length"), is(nullValue())); - - // A HEAD request should have similar headers, but no body - if (!method.equals("HEAD")) - { - assertThat("Response[Content-Length]", response.get("Content-Length"), is(nullValue())); - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - } - - public static class WibbleDefaultServlet extends DefaultServlet - { - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - // Disregard the method given, use GET instead. - if ("WIBBLE".equals(req.getMethod())) - { - doGet(req, resp); - } - else - { - super.service(req, resp); - } - } - } - - @Test - public void testIsGzipCompressedEmpty() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = 0; - createFile(contextDir, "file.txt", fileSize); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(0)); - } - - public static Stream compressibleSizes() - { - return Stream.of( - DEFAULT_OUTPUT_BUFFER_SIZE / 4, - DEFAULT_OUTPUT_BUFFER_SIZE, - DEFAULT_OUTPUT_BUFFER_SIZE * 4); - } - - @ParameterizedTest - @MethodSource("compressibleSizes") - public void testIsGzipCompressed(int fileSize) throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @ParameterizedTest - @MethodSource("compressibleSizes") - public void testIsGzipCompressedIfModifiedSince(int fileSize) throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - Instant fourSecondsAgo = Instant.now().minusSeconds(4); - request.setHeader("If-Modified-Since", DateGenerator.formatDate(fourSecondsAgo.toEpochMilli())); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[ETag]", response.get("ETag"), startsWith("W/")); - assertThat("Response[ETag]", response.get("ETag"), containsString(CompressedContentFormat.GZIP.getEtagSuffix())); - assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testGzippedIfSVG() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("image/svg+xml"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - Path testResource = MavenTestingUtils.getTestResourcePath("test.svg"); - Path file = contextDir.resolve("test.svg"); - IO.copy(testResource.toFile(), file.toFile()); - String expectedSha1Sum = Sha1Sum.calculate(testResource); - int fileSize = (int)Files.size(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/test.svg"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testNotGzipedIfNotModified() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - createFile(contextDir, "file.txt", fileSize); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - long fiveMinutesLater = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5); - request.setHeader("If-Modified-Since", DateGenerator.formatDate(fiveMinutesLater)); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.NOT_MODIFIED_304)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[ETag]", response.get("ETag"), startsWith("W/")); - assertThat("Response[ETag]", response.get("ETag"), not(containsString(CompressedContentFormat.GZIP.getEtagSuffix()))); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(0)); - } - - /** - * Gzip incorrectly gzips when {@code Accept-Encoding: gzip; q=0}. - * - *

- * A quality of 0 results in no compression. - *

- * - * See: Bugzilla #388072 - */ - @Test - public void testIsNotGzipCompressedWithZeroQ() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE / 4; - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip; q=0"); // TESTING THIS - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testIsGzipCompressedWithQ() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE / 4; - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "something; q=0.1, gzip; q=0.5"); // TESTING THIS - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[Vary]", response.get("Vary"), containsString("Accept-Encoding")); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testIsNotGzipCompressedByContentType() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - Path file = createFile(contextDir, "file.mp3", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.mp3"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testIsNotGzipCompressedByExcludedContentType() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addExcludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testIsNotGzipCompressedByExcludedContentTypeWithCharset() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addExcludedMimeTypes("text/plain"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - servletContextHandler.getMimeTypes().addMimeMapping("txt", "text/plain;charset=UTF-8"); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - Path file = createFile(contextDir, "test_quotes.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/test_quotes.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testExcludePaths() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addIncludedMimeTypes("text/plain"); - gzipHandler.setExcludedPaths("*.txt"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } - - @Test - public void testIncludedPaths() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.setExcludedPaths("/bad.txt"); - gzipHandler.setIncludedPaths("*.txt"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - Path fileGood = createFile(contextDir, "file.txt", DEFAULT_OUTPUT_BUFFER_SIZE * 4); - Path fileBad = createFile(contextDir, "bad.txt", DEFAULT_OUTPUT_BUFFER_SIZE * 2); - String expectedGoodSha1Sum = Sha1Sum.calculate(fileGood); - String expectedBadSha1Sum = Sha1Sum.calculate(fileBad); - - server.start(); - - // Test Request 1 - { - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[Vary]", response.get("Vary"), is("Accept-Encoding")); - - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is((int)Files.size(fileGood))); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedGoodSha1Sum)); - } - - // Test Request 2 - { - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/bad.txt"); - - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - UncompressedMetadata metadata = parseResponseContent(response); - int fileSize = (int)Files.size(fileBad); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedBadSha1Sum)); - } - } - - @Test - public void testIsNotGzipCompressedSVGZ() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - Path testResource = MavenTestingUtils.getTestResourcePath("test.svgz"); - Path file = contextDir.resolve("test.svgz"); - IO.copy(testResource.toFile(), file.toFile()); - int fileSize = (int)Files.size(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/test.svgz"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Header checks - assertThat("Response[Content-Type]", response.get("Content-Type"), containsString("image/svg+xml")); - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), containsString("gzip")); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - } - - @Test - public void testUpperCaseMimeType() throws Exception - { - GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.addExcludedMimeTypes("text/PLAIN"); - - server = new Server(); - LocalConnector localConnector = new LocalConnector(server); - server.addConnector(localConnector); - - Path contextDir = workDir.resolve("context"); - FS.ensureDirExists(contextDir); - - ServletContextHandler servletContextHandler = new ServletContextHandler(); - servletContextHandler.setContextPath("/context"); - servletContextHandler.setBaseResourceAsPath(contextDir); - ServletHolder holder = new ServletHolder("default", DefaultServlet.class); - holder.setInitParameter("etags", "true"); - servletContextHandler.addServlet(holder, "/"); - servletContextHandler.insertHandler(gzipHandler); - - server.setHandler(servletContextHandler); - - // Prepare Server File - int fileSize = DEFAULT_OUTPUT_BUFFER_SIZE * 4; - Path file = createFile(contextDir, "file.txt", fileSize); - String expectedSha1Sum = Sha1Sum.calculate(file); - - server.start(); - - // Setup request - HttpTester.Request request = HttpTester.newRequest(); - request.setMethod("GET"); - request.setVersion(HttpVersion.HTTP_1_1); - request.setHeader("Host", "tester"); - request.setHeader("Connection", "close"); - request.setHeader("Accept-Encoding", "gzip"); - request.setURI("/context/file.txt"); - - // Issue request - ByteBuffer rawResponse = localConnector.getResponse(request.generate(), 5, TimeUnit.SECONDS); - - // Parse response - HttpTester.Response response = HttpTester.parseResponse(rawResponse); - - assertThat("Response status", response.getStatus(), is(HttpStatus.OK_200)); - - // Response Content-Encoding check - assertThat("Response[Content-Encoding]", response.get("Content-Encoding"), not(containsString("gzip"))); - assertThat("Response[Vary]", response.get("Vary"), is(nullValue())); - - // Response Content checks - UncompressedMetadata metadata = parseResponseContent(response); - assertThat("Response Content Length", metadata.contentLength, is(fileSize)); - assertThat("(Uncompressed) Content Length", metadata.uncompressedSize, is(fileSize)); - assertThat("(Uncompressed) Content Hash", metadata.uncompressedSha1Sum, is(expectedSha1Sum)); - } -}