From 8e51112d533bb0eae8629d8f45ddd764c51c8877 Mon Sep 17 00:00:00 2001 From: markslater Date: Thu, 14 Apr 2022 21:58:45 +0100 Subject: [PATCH 1/3] #7880 PrecompressedFormats set on ResourceService are used in DefaultServlet unless overridden by an InitParameter. --- .../eclipse/jetty/servlet/DefaultServlet.java | 17 ++++-- .../jetty/servlet/DefaultServletTest.java | 52 ++++++++++++++++--- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index bb573ee04a90..1ec0f87e094f 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.StringTokenizer; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -170,7 +171,7 @@ public void init() _resourceService.setAcceptRanges(getInitBoolean("acceptRanges", _resourceService.isAcceptRanges())); _resourceService.setDirAllowed(getInitBoolean("dirAllowed", _resourceService.isDirAllowed())); _resourceService.setRedirectWelcome(getInitBoolean("redirectWelcome", _resourceService.isRedirectWelcome())); - _resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip", false))); + _resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip"), _resourceService.getPrecompressedFormats())); _resourceService.setPathInfoOnly(getInitBoolean("pathInfoOnly", _resourceService.isPathInfoOnly())); _resourceService.setEtags(getInitBoolean("etags", _resourceService.isEtags())); @@ -303,8 +304,11 @@ public void init() LOG.debug("resource base = {}", _resourceBase); } - private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, boolean gzip) + private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, Boolean gzip, CompressedContentFormat[] dft) { + if (precompressed == null && gzip == null) { + return dft; + } List ret = new ArrayList<>(); if (precompressed != null && precompressed.indexOf('=') > 0) { @@ -367,11 +371,11 @@ public String getInitParameter(String name) return value; } - private boolean getInitBoolean(String name, boolean dft) + private Boolean getInitBoolean(String name) { String value = getInitParameter(name); if (value == null || value.length() == 0) - return dft; + return null; return (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || @@ -379,6 +383,11 @@ private boolean getInitBoolean(String name, boolean dft) value.startsWith("1")); } + private boolean getInitBoolean(String name, boolean dft) + { + return Optional.ofNullable(getInitBoolean(name)).orElse(dft); + } + private int getInitInt(String name, int dft) { String value = getInitParameter(name); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index 1acd1f5a5248..a75da87940ea 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -40,12 +40,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.DateGenerator; -import org.eclipse.jetty.http.HttpContent; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.HttpTester; +import org.eclipse.jetty.http.*; import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.AllowedResourceAliasChecker; import org.eclipse.jetty.server.HttpConfiguration; @@ -1968,6 +1963,51 @@ public void testCustomCompressionFormats() throws Exception assertThat(body, containsString("fake gzip")); } + @Test + public void testProgrammaticCustomCompressionFormats() throws Exception + { + createFile(docRoot.resolve("data0.txt"), "Hello Text 0"); + createFile(docRoot.resolve("data0.txt.br"), "fake brotli"); + createFile(docRoot.resolve("data0.txt.gz"), "fake gzip"); + createFile(docRoot.resolve("data0.txt.bz2"), "fake bzip2"); + + ResourceService resourceService = new ResourceService(); + resourceService.setPrecompressedFormats(new CompressedContentFormat[]{ + new CompressedContentFormat("bzip2", ".bz2"), + new CompressedContentFormat("gzip", ".gz"), + new CompressedContentFormat("br", ".br") + }); + ServletHolder defholder = new ServletHolder(new DefaultServlet(resourceService)); + context.addServlet(defholder, "/"); + defholder.setInitParameter("resourceBase", docRoot.toString()); + + String rawResponse; + HttpTester.Response response; + String body; + + rawResponse = connector.getResponse("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:bzip2, br, gzip\r\n\r\n"); + response = HttpTester.parseResponse(rawResponse); + assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_LENGTH, "10")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_TYPE, "text/plain")); + assertThat(response, containsHeaderValue(HttpHeader.VARY, "Accept-Encoding")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_ENCODING, "bzip2")); + body = response.getContent(); + assertThat(body, containsString("fake bzip2")); + + // TODO: show accept-encoding search order issue (shouldn't this request return data0.txt.br?) + + rawResponse = connector.getResponse("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:br, gzip\r\n\r\n"); + response = HttpTester.parseResponse(rawResponse); + assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_LENGTH, "9")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_TYPE, "text/plain")); + assertThat(response, containsHeaderValue(HttpHeader.VARY, "Accept-Encoding")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_ENCODING, "gzip")); + body = response.getContent(); + assertThat(body, containsString("fake gzip")); + } + @Test public void testControlCharacter() throws Exception { From 708553d611e6485ca7eab1da07202378d304c6f9 Mon Sep 17 00:00:00 2001 From: markslater Date: Thu, 14 Apr 2022 22:56:09 +0100 Subject: [PATCH 2/3] #7880 Fix checkstyle violations. --- .../java/org/eclipse/jetty/servlet/DefaultServlet.java | 3 ++- .../org/eclipse/jetty/servlet/DefaultServletTest.java | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index 1ec0f87e094f..0c317345639e 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -306,7 +306,8 @@ public void init() private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, Boolean gzip, CompressedContentFormat[] dft) { - if (precompressed == null && gzip == null) { + if (precompressed == null && gzip == null) + { return dft; } List ret = new ArrayList<>(); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index a75da87940ea..1ec1f9d2c526 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -40,7 +40,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.*; +import org.eclipse.jetty.http.CompressedContentFormat; +import org.eclipse.jetty.http.DateGenerator; +import org.eclipse.jetty.http.HttpContent; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.AllowedResourceAliasChecker; import org.eclipse.jetty.server.HttpConfiguration; From 9ffd2bf11392bac94093a89ea43b479b613c1dc4 Mon Sep 17 00:00:00 2001 From: markslater Date: Fri, 15 Apr 2022 07:57:20 +0100 Subject: [PATCH 3/3] #7880 Fix NPEs. --- .../main/java/org/eclipse/jetty/servlet/DefaultServlet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index 0c317345639e..b580148be212 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -319,7 +319,7 @@ private CompressedContentFormat[] parsePrecompressedFormats(String precompressed String encoding = setting[0].trim(); String extension = setting[1].trim(); ret.add(new CompressedContentFormat(encoding, extension)); - if (gzip && !ret.contains(CompressedContentFormat.GZIP)) + if (gzip == Boolean.TRUE && !ret.contains(CompressedContentFormat.GZIP)) ret.add(CompressedContentFormat.GZIP); } } @@ -331,7 +331,7 @@ else if (precompressed != null) ret.add(CompressedContentFormat.GZIP); } } - else if (gzip) + else if (gzip == Boolean.TRUE) { // gzip handling is for backwards compatibility with older Jetty ret.add(CompressedContentFormat.GZIP);