From 1bdb69dc0761e614abf5a163d3a6272ba15e0750 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 27 Jul 2021 11:36:56 -0500 Subject: [PATCH 1/5] Issue #6544 - Fixing broken `jetty.gzip.excludedMimeTypeList` property support + Adding GzipHandler tests + Adding Gzip module tests + Updating jetty-gzip.xml for includedMimeTypesList and excludedMimeTypesList behavior + Adding GzipHandler support for setIncludedMimeTypesList(String) and setExcludedMimeTypesList(String Signed-off-by: Joakim Erdfelt --- .../src/main/webapp/WEB-INF/web.xml | 5 + .../src/main/webapp/jetty.png | Bin 0 -> 5465 bytes .../src/main/webapp/jetty.webp | Bin 0 -> 3534 bytes .../src/main/config/etc/jetty-gzip.xml | 4 +- .../server/handler/gzip/GzipHandler.java | 22 +++ .../jetty/servlet/GzipHandlerTest.java | 103 ++++++++++-- .../tests/distribution/GzipModuleTests.java | 147 ++++++++++++++++++ 7 files changed, 265 insertions(+), 16 deletions(-) create mode 100644 demos/demo-simple-webapp/src/main/webapp/jetty.png create mode 100644 demos/demo-simple-webapp/src/main/webapp/jetty.webp create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java diff --git a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml index da1263c1b8d7..1aebcaace5ce 100644 --- a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml +++ b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -6,4 +6,9 @@ Simple Web Application + + webp + image/webp + + diff --git a/demos/demo-simple-webapp/src/main/webapp/jetty.png b/demos/demo-simple-webapp/src/main/webapp/jetty.png new file mode 100644 index 0000000000000000000000000000000000000000..d579fffddfe176f020f7f74bdc663195fd39697f GIT binary patch literal 5465 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 P00000NkvXXu0mjf*FjSZ literal 0 HcmV?d00001 diff --git a/demos/demo-simple-webapp/src/main/webapp/jetty.webp b/demos/demo-simple-webapp/src/main/webapp/jetty.webp new file mode 100644 index 0000000000000000000000000000000000000000..2d1bfea3ef792ce55a4c1f518947a93d29468bd7 GIT binary patch literal 3534 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 I1ONa40I<~Z`v3p{ literal 0 HcmV?d00001 diff --git a/jetty-server/src/main/config/etc/jetty-gzip.xml b/jetty-server/src/main/config/etc/jetty-gzip.xml index 7659b2a195d0..933f2ef4893e 100644 --- a/jetty-server/src/main/config/etc/jetty-gzip.xml +++ b/jetty-server/src/main/config/etc/jetty-gzip.xml @@ -18,8 +18,8 @@ - - + + diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index 9df6291acf4d..1a2cfd921284 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -768,6 +768,17 @@ public void setExcludedMimeTypes(String... types) _mimeTypes.exclude(types); } + /** + * Set the excluded filter list of MIME types (replacing any previously set) + * + * @param csvTypes The list of mime types to exclude (without charset or other parameters), CSV format + * @see #setIncludedMimeTypesList(String) + */ + public void setExcludedMimeTypesList(String csvTypes) + { + setExcludedMimeTypes(StringUtil.csvSplit(csvTypes)); + } + /** * Set the excluded filter list of Path specs (replacing any previously set) * @@ -819,6 +830,17 @@ public void setIncludedMimeTypes(String... types) _mimeTypes.include(types); } + /** + * Set the included filter list of MIME types (replacing any previously set) + * + * @param csvTypes The list of mime types to include (without charset or other parameters), CSV format + * @see #setExcludedMimeTypesList(String) + */ + public void setIncludedMimeTypesList(String csvTypes) + { + setIncludedMimeTypes(StringUtil.csvSplit(csvTypes)); + } + /** * Set the included filter list of Path specs (replacing any previously set) * diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index 43d3f031f854..e27d87ab6974 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -61,7 +61,6 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; -@SuppressWarnings("serial") public class GzipHandlerTest { private static final String __content = @@ -88,6 +87,8 @@ public class GzipHandlerTest private Server _server; private LocalConnector _connector; + private GzipHandler gzipHandler; + private ServletContextHandler context; @BeforeEach public void init() throws Exception @@ -96,25 +97,25 @@ public void init() throws Exception _connector = new LocalConnector(_server); _server.addConnector(_connector); - GzipHandler gzipHandler = new GzipHandler(); + gzipHandler = new GzipHandler(); gzipHandler.setMinGzipSize(16); gzipHandler.setInflateBufferSize(4096); - ServletContextHandler context = new ServletContextHandler(gzipHandler, "/ctx"); - ServletHandler servlets = context.getServletHandler(); + context = new ServletContextHandler(gzipHandler, "/ctx"); _server.setHandler(gzipHandler); gzipHandler.setHandler(context); - servlets.addServletWithMapping(MicroServlet.class, "/micro"); - servlets.addServletWithMapping(MicroChunkedServlet.class, "/microchunked"); - servlets.addServletWithMapping(TestServlet.class, "/content"); - servlets.addServletWithMapping(ForwardServlet.class, "/forward"); - servlets.addServletWithMapping(IncludeServlet.class, "/include"); - servlets.addServletWithMapping(EchoServlet.class, "/echo/*"); - servlets.addServletWithMapping(DumpServlet.class, "/dump/*"); - servlets.addServletWithMapping(AsyncServlet.class, "/async/*"); - servlets.addServletWithMapping(BufferServlet.class, "/buffer/*"); - servlets.addFilterWithMapping(CheckFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); + context.addServlet(MicroServlet.class, "/micro"); + context.addServlet(MicroChunkedServlet.class, "/microchunked"); + context.addServlet(TestServlet.class, "/content"); + context.addServlet(MimeTypeContentServlet.class, "/mimetypes/*"); + context.addServlet(ForwardServlet.class, "/forward"); + context.addServlet(IncludeServlet.class, "/include"); + context.addServlet(EchoServlet.class, "/echo/*"); + context.addServlet(DumpServlet.class, "/dump/*"); + context.addServlet(AsyncServlet.class, "/async/*"); + context.addServlet(BufferServlet.class, "/buffer/*"); + context.addFilter(CheckFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); _server.start(); } @@ -147,6 +148,34 @@ protected void doGet(HttpServletRequest req, HttpServletResponse response) throw } } + public static class MimeTypeContentServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + String pathInfo = req.getPathInfo(); + resp.setContentType(getContentTypeFromRequest(pathInfo, req)); + resp.getWriter().println("This is content for " + pathInfo); + } + + private String getContentTypeFromRequest(String filename, HttpServletRequest req) + { + String defaultContentType = "application/octet-stream"; + if (req.getParameter("type") != null) + defaultContentType = req.getParameter("type"); + + ServletContextHandler servletContextHandler = ServletContextHandler.getServletContextHandler(getServletContext()); + if (servletContextHandler == null) + return defaultContentType; + String contentType = servletContextHandler.getMimeTypes().getMimeByExtension(filename); + if (contentType != null) + { + return contentType; + } + return defaultContentType; + } + } + public static class TestServlet extends HttpServlet { @Override @@ -797,6 +826,52 @@ public void testGzipBomb() throws Exception assertThat(response.getContentBytes().length, is(512 * 1024)); } + @Test + public void testGzipExcludeNewMimeType() throws Exception + { + // 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"); + + // generated and parsed test + HttpTester.Request request = HttpTester.newRequest(); + HttpTester.Response response; + + // Request something that is not present on MimeTypes and is also + // excluded by GzipHandler configuration + request.setMethod("GET"); + request.setURI("/ctx/mimetypes/foo.webfoo?type=image/webfoo"); + request.setVersion("HTTP/1.1"); + request.setHeader("Host", "tester"); + request.setHeader("Accept", "*/*"); + request.setHeader("Accept-Encoding", "gzip"); // allow compressed responses + request.setHeader("Connection", "close"); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(), is(200)); + assertThat("Should not be compressed with gzip", response.get("Content-Encoding"), nullValue()); + assertThat(response.get("ETag"), nullValue()); + assertThat(response.get("Vary"), nullValue()); + + // Request something that is present on MimeTypes and is also compressible + // by the GzipHandler configuration + request.setMethod("GET"); + request.setURI("/ctx/mimetypes/zed.txt"); + request.setVersion("HTTP/1.1"); + request.setHeader("Host", "tester"); + request.setHeader("Accept", "*/*"); + request.setHeader("Accept-Encoding", "gzip"); // allow compressed responses + request.setHeader("Connection", "close"); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(), is(200)); + assertThat(response.get("Content-Encoding"), containsString("gzip")); + assertThat(response.get("ETag"), nullValue()); + assertThat(response.get("Vary"), is("Accept-Encoding")); + } + public static class CheckFilter implements Filter { @Override diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java new file mode 100644 index 000000000000..64cd664d2b13 --- /dev/null +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 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.tests.distribution; + +import java.io.File; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.junit.jupiter.api.Test; + +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.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class GzipModuleTests extends AbstractJettyHomeTest +{ + @Test + public void testGzipDefault() throws Exception + { + Path jettyBase = newTestJettyBaseDirectory(); + String jettyVersion = System.getProperty("jettyVersion"); + JettyHomeTester distribution = JettyHomeTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(jettyBase) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + int httpsPort = distribution.freePort(); + assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); + + String[] argsConfig = { + "--add-modules=gzip", + "--add-modules=deploy,webapp,http" + }; + + try (JettyHomeTester.Run runConfig = distribution.start(argsConfig)) + { + assertTrue(runConfig.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, runConfig.getExitValue()); + + String[] argsStart = { + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpsPort, + "jetty.ssl.port=" + httpsPort + }; + + File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "demo"); + + try (JettyHomeTester.Run runStart = distribution.start(argsStart)) + { + assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/index.html"); + assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); + assertThat("Ensure that gzip is working", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), containsString("gzip")); + } + } + } + + @Test + public void testGzipExcludeMimeType() throws Exception + { + Path jettyBase = newTestJettyBaseDirectory(); + String jettyVersion = System.getProperty("jettyVersion"); + JettyHomeTester distribution = JettyHomeTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(jettyBase) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + int httpsPort = distribution.freePort(); + assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); + + String[] argsConfig = { + "--add-modules=gzip", + "--add-modules=deploy,webapp,http" + }; + + try (JettyHomeTester.Run runConfig = distribution.start(argsConfig)) + { + assertTrue(runConfig.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, runConfig.getExitValue()); + + String[] argsStart = { + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpsPort, + "jetty.ssl.port=" + httpsPort, + "jetty.gzip.excludedMimeTypeList=image/webp" + }; + + File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "demo"); + + try (JettyHomeTester.Run runStart = distribution.start(argsStart)) + { + assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/jetty.webp"); + assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); + assertThat("Ensure that gzip exclusion worked", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); + } + } + } + + private static class ResponseDetails implements Supplier + { + private final ContentResponse response; + + public ResponseDetails(ContentResponse response) + { + this.response = response; + } + + @Override + public String get() + { + StringBuilder ret = new StringBuilder(); + ret.append(response.toString()).append(System.lineSeparator()); + ret.append(response.getHeaders().toString()).append(System.lineSeparator()); + ret.append(response.getContentAsString()).append(System.lineSeparator()); + return ret.toString(); + } + } +} From 72fc018cc56adc8971900a449de7e3331fbfc650 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 30 Jul 2021 07:25:03 -0500 Subject: [PATCH 2/5] Issue #6544 - Updates based on review Signed-off-by: Joakim Erdfelt --- .../src/main/webapp/WEB-INF/web.xml | 4 +- .../src/main/webapp/jetty.icon | Bin 0 -> 6586 bytes .../tests/distribution/GzipModuleTests.java | 60 ++++++++++++++---- 3 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 demos/demo-simple-webapp/src/main/webapp/jetty.icon diff --git a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml index 1aebcaace5ce..8ce8b679a5a0 100644 --- a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml +++ b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -7,8 +7,8 @@ Simple Web Application - webp - image/webp + icon + image/vnd.microsoft.icon diff --git a/demos/demo-simple-webapp/src/main/webapp/jetty.icon b/demos/demo-simple-webapp/src/main/webapp/jetty.icon new file mode 100644 index 0000000000000000000000000000000000000000..54e2e6104332729142765d92f2a8168ca4a84891 GIT binary patch literal 6586 zcmZQzU}Rur5D;Jh(h3Y2EDQ``3=9kk3QRygBZC1W1H(R`n1KP5&&XYLHY5)R|{v06fC&|E|0i=OaKoN*IkYZo}nu8AhkAl$<7!83D8v^L%0jYdYIimo? z4nPbluRx#yOhO1IAO*r801RXh9#8;r$-t4I@G=161R#co7bMt#B9O4c3@>ol0mE&S zh9n;Pg#$QJMu`Cn0Z@Kv0ND=ABe49!zyT6~fWcP23~1ptYWZjgjE2By2#kinXb6nZ z5P-D{M(NQI7!85Z5Eu=C(GVC7fsqpeodJICyj)UTKp*pZdbk9E2M%B(2PK?SPXi^4 zJzX3_GVZ-SwGcR{z{8~Qzdp)8BDTS&szZUJ2^%`}-r)14hnGTf=DLGI($m$?Wt~$( F697q|!wUca literal 0 HcmV?d00001 diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java index 64cd664d2b13..af1755687e38 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java @@ -25,7 +25,6 @@ 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.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,8 +43,6 @@ public void testGzipDefault() throws Exception .build(); int httpPort = distribution.freePort(); - int httpsPort = distribution.freePort(); - assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { "--add-modules=gzip", @@ -59,8 +56,7 @@ public void testGzipDefault() throws Exception String[] argsStart = { "jetty.http.port=" + httpPort, - "jetty.httpConfig.port=" + httpsPort, - "jetty.ssl.port=" + httpsPort + "jetty.httpConfig.port=" + httpPort }; File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion); @@ -79,7 +75,7 @@ public void testGzipDefault() throws Exception } @Test - public void testGzipExcludeMimeType() throws Exception + public void testGzipDefaultExcludedMimeType() throws Exception { Path jettyBase = newTestJettyBaseDirectory(); String jettyVersion = System.getProperty("jettyVersion"); @@ -90,8 +86,6 @@ public void testGzipExcludeMimeType() throws Exception .build(); int httpPort = distribution.freePort(); - int httpsPort = distribution.freePort(); - assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { "--add-modules=gzip", @@ -105,9 +99,7 @@ public void testGzipExcludeMimeType() throws Exception String[] argsStart = { "jetty.http.port=" + httpPort, - "jetty.httpConfig.port=" + httpsPort, - "jetty.ssl.port=" + httpsPort, - "jetty.gzip.excludedMimeTypeList=image/webp" + "jetty.httpConfig.port=" + httpPort }; File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion); @@ -120,11 +112,57 @@ public void testGzipExcludeMimeType() throws Exception startHttpClient(); ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/jetty.webp"); assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); + assertThat("Correct Content-Type", response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/webp")); assertThat("Ensure that gzip exclusion worked", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); } } } + @Test + public void testGzipAddWebappSpecificExcludeMimeType() throws Exception + { + Path jettyBase = newTestJettyBaseDirectory(); + String jettyVersion = System.getProperty("jettyVersion"); + JettyHomeTester distribution = JettyHomeTester.Builder.newInstance() + .jettyVersion(jettyVersion) + .jettyBase(jettyBase) + .mavenLocalRepository(System.getProperty("mavenRepoPath")) + .build(); + + int httpPort = distribution.freePort(); + + String[] argsConfig = { + "--add-modules=gzip", + "--add-modules=deploy,webapp,http" + }; + + try (JettyHomeTester.Run runConfig = distribution.start(argsConfig)) + { + assertTrue(runConfig.awaitFor(5, TimeUnit.SECONDS)); + assertEquals(0, runConfig.getExitValue()); + + String[] argsStart = { + "jetty.http.port=" + httpPort, + "jetty.httpConfig.port=" + httpPort, + "jetty.gzip.excludedMimeTypeList=image/vnd.microsoft.icon" + }; + + File war = distribution.resolveArtifact("org.eclipse.jetty.demos:demo-simple-webapp:war:" + jettyVersion); + distribution.installWarFile(war, "demo"); + + try (JettyHomeTester.Run runStart = distribution.start(argsStart)) + { + assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS)); + + startHttpClient(); + ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/jetty.icon"); + assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); + assertThat("Ensure that gzip exclusion worked", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); + assertThat("Correct Content-Type", response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/vnd.microsoft.icon")); + } + } + } + private static class ResponseDetails implements Supplier { private final ContentResponse response; From 386836055562cdde7dfb8a7af4fdc33eeb5dc46c Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 30 Jul 2021 07:29:59 -0500 Subject: [PATCH 3/5] Issue #6544 - More updates based on review and merge Signed-off-by: Joakim Erdfelt --- .../tests/distribution/GzipModuleTests.java | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java index af1755687e38..040e79e9d6ae 100644 --- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java @@ -16,7 +16,6 @@ import java.io.File; import java.nio.file.Path; import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.http.HttpHeader; @@ -68,8 +67,9 @@ public void testGzipDefault() throws Exception startHttpClient(); ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/index.html"); - assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); - assertThat("Ensure that gzip is working", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), containsString("gzip")); + String responseDetails = toResponseDetails(response); + assertEquals(HttpStatus.OK_200, response.getStatus(), responseDetails); + assertThat(responseDetails, response.getHeaders().get(HttpHeader.CONTENT_ENCODING), containsString("gzip")); } } } @@ -111,9 +111,10 @@ public void testGzipDefaultExcludedMimeType() throws Exception startHttpClient(); ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/jetty.webp"); - assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); - assertThat("Correct Content-Type", response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/webp")); - assertThat("Ensure that gzip exclusion worked", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); + String responseDetails = toResponseDetails(response); + assertEquals(HttpStatus.OK_200, response.getStatus(), responseDetails); + assertThat(responseDetails, response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/webp")); + assertThat(responseDetails, response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); } } } @@ -156,30 +157,20 @@ public void testGzipAddWebappSpecificExcludeMimeType() throws Exception startHttpClient(); ContentResponse response = client.GET("http://localhost:" + httpPort + "/demo/jetty.icon"); - assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response)); - assertThat("Ensure that gzip exclusion worked", response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); - assertThat("Correct Content-Type", response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/vnd.microsoft.icon")); + String responseDetails = toResponseDetails(response); + assertEquals(HttpStatus.OK_200, response.getStatus(), responseDetails); + assertThat(responseDetails, response.getHeaders().get(HttpHeader.CONTENT_ENCODING), not(containsString("gzip"))); + assertThat(responseDetails, response.getHeaders().get(HttpHeader.CONTENT_TYPE), containsString("image/vnd.microsoft.icon")); } } } - private static class ResponseDetails implements Supplier + private static String toResponseDetails(ContentResponse response) { - private final ContentResponse response; - - public ResponseDetails(ContentResponse response) - { - this.response = response; - } - - @Override - public String get() - { - StringBuilder ret = new StringBuilder(); - ret.append(response.toString()).append(System.lineSeparator()); - ret.append(response.getHeaders().toString()).append(System.lineSeparator()); - ret.append(response.getContentAsString()).append(System.lineSeparator()); - return ret.toString(); - } + StringBuilder ret = new StringBuilder(); + ret.append(response.toString()).append(System.lineSeparator()); + ret.append(response.getHeaders().toString()).append(System.lineSeparator()); + ret.append(response.getContentAsString()).append(System.lineSeparator()); + return ret.toString(); } } From d5da842ea8c914f15a5880b2c14ba28daa6755b2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 30 Jul 2021 07:32:19 -0500 Subject: [PATCH 4/5] Issue #6544 - Remove braces Signed-off-by: Joakim Erdfelt --- .../test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index e27d87ab6974..c6470583c79c 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -163,15 +163,12 @@ private String getContentTypeFromRequest(String filename, HttpServletRequest req String defaultContentType = "application/octet-stream"; if (req.getParameter("type") != null) defaultContentType = req.getParameter("type"); - ServletContextHandler servletContextHandler = ServletContextHandler.getServletContextHandler(getServletContext()); if (servletContextHandler == null) return defaultContentType; String contentType = servletContextHandler.getMimeTypes().getMimeByExtension(filename); if (contentType != null) - { return contentType; - } return defaultContentType; } } From dc48a4b4521f069d50e19426407a6769ce516d5b Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 30 Jul 2021 08:56:21 -0500 Subject: [PATCH 5/5] Issue #6544 - Adding comment about mime-type in web.xml Signed-off-by: Joakim Erdfelt --- demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml index 8ce8b679a5a0..79d16dcd8500 100644 --- a/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml +++ b/demos/demo-simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -6,6 +6,7 @@ Simple Web Application + icon image/vnd.microsoft.icon