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 <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
330fc0ba0b
commit
1bdb69dc07
|
@ -6,4 +6,9 @@
|
|||
|
||||
<display-name>Simple Web Application</display-name>
|
||||
|
||||
<mime-mapping>
|
||||
<extension>webp</extension>
|
||||
<mime-type>image/webp</mime-type>
|
||||
</mime-mapping>
|
||||
|
||||
</web-app>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -18,8 +18,8 @@
|
|||
<Set name="dispatcherTypes" property="jetty.gzip.dispatcherTypes"/>
|
||||
<Set name="includedMethodList" property="jetty.gzip.includedMethodList"/>
|
||||
<Set name="excludedMethodList" property="jetty.gzip.excludedMethodList"/>
|
||||
<Set name="includedMimeTypes" property="jetty.gzip.includedMimeTypeList"/>
|
||||
<Set name="excludedMimeTypes" property="jetty.gzip.excludedMimeTypeList"/>
|
||||
<Set name="includedMimeTypesList" property="jetty.gzip.includedMimeTypeList"/>
|
||||
<Set name="excludedMimeTypesList" property="jetty.gzip.excludedMimeTypeList"/>
|
||||
<Set name="includedPaths" property="jetty.gzip.includedPathList"/>
|
||||
<Set name="excludedPaths" property="jetty.gzip.excludedPathList"/>
|
||||
<Set name="inflaterPool">
|
||||
|
|
|
@ -768,6 +768,17 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
|||
_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 class GzipHandler extends HandlerWrapper implements GzipFactory
|
|||
_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)
|
||||
*
|
||||
|
|
|
@ -61,7 +61,6 @@ import static org.hamcrest.Matchers.not;
|
|||
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 class GzipHandlerTest
|
|||
_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 @@ public class GzipHandlerTest
|
|||
}
|
||||
}
|
||||
|
||||
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 class GzipHandlerTest
|
|||
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
|
||||
|
|
|
@ -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<String>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue