Configure Jetty to compress responses to requests other than GET
Closes gh-8184
This commit is contained in:
parent
6df1be3f1a
commit
bc4603925e
|
|
@ -32,6 +32,7 @@ import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.server.AbstractConnector;
|
import org.eclipse.jetty.server.AbstractConnector;
|
||||||
|
|
@ -229,6 +230,9 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
||||||
Compression compression = getCompression();
|
Compression compression = getCompression();
|
||||||
handler.setMinGzipSize(compression.getMinResponseSize());
|
handler.setMinGzipSize(compression.getMinResponseSize());
|
||||||
handler.setIncludedMimeTypes(compression.getMimeTypes());
|
handler.setIncludedMimeTypes(compression.getMimeTypes());
|
||||||
|
for (HttpMethod httpMethod : HttpMethod.values()) {
|
||||||
|
handler.addIncludedMethods(httpMethod.name());
|
||||||
|
}
|
||||||
if (compression.getExcludedUserAgents() != null) {
|
if (compression.getExcludedUserAgents() != null) {
|
||||||
handler.setExcludedAgentPatterns(compression.getExcludedUserAgents());
|
handler.setExcludedAgentPatterns(compression.getExcludedUserAgents());
|
||||||
}
|
}
|
||||||
|
|
@ -581,8 +585,8 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be applied
|
* Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be
|
||||||
* to the {@link Server} before the it is created.
|
* applied to the {@link Server} before the it is created.
|
||||||
* @return the {@link JettyServerCustomizer}s
|
* @return the {@link JettyServerCustomizer}s
|
||||||
*/
|
*/
|
||||||
public Collection<JettyServerCustomizer> getServerCustomizers() {
|
public Collection<JettyServerCustomizer> getServerCustomizers() {
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.boot.web.embedded.jetty;
|
package org.springframework.boot.web.embedded.jetty;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.jasper.servlet.JspServlet;
|
import org.apache.jasper.servlet.JspServlet;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
@ -43,13 +37,10 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
|
|
||||||
import org.springframework.boot.web.server.Compression;
|
|
||||||
import org.springframework.boot.web.server.PortInUseException;
|
import org.springframework.boot.web.server.PortInUseException;
|
||||||
import org.springframework.boot.web.server.Ssl;
|
import org.springframework.boot.web.server.Ssl;
|
||||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
|
||||||
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
|
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
|
||||||
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
|
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.CoreMatchers.isA;
|
import static org.hamcrest.CoreMatchers.isA;
|
||||||
|
|
@ -296,38 +287,6 @@ public class JettyServletWebServerFactoryTests
|
||||||
factory.getWebServer().start();
|
factory.getWebServer().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
// Workaround for Jetty issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=470646
|
|
||||||
protected String setUpFactoryForCompression(final int contentSize, String[] mimeTypes,
|
|
||||||
String[] excludedUserAgents) throws Exception {
|
|
||||||
char[] chars = new char[contentSize];
|
|
||||||
Arrays.fill(chars, 'F');
|
|
||||||
final String testContent = new String(chars);
|
|
||||||
AbstractServletWebServerFactory factory = getFactory();
|
|
||||||
Compression compression = new Compression();
|
|
||||||
compression.setEnabled(true);
|
|
||||||
if (mimeTypes != null) {
|
|
||||||
compression.setMimeTypes(mimeTypes);
|
|
||||||
}
|
|
||||||
if (excludedUserAgents != null) {
|
|
||||||
compression.setExcludedUserAgents(excludedUserAgents);
|
|
||||||
}
|
|
||||||
factory.setCompression(compression);
|
|
||||||
this.webServer = factory
|
|
||||||
.getWebServer(new ServletRegistrationBean<HttpServlet>(new HttpServlet() {
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
resp.setContentLength(contentSize);
|
|
||||||
resp.setHeader(HttpHeaders.CONTENT_TYPE, "text/plain");
|
|
||||||
resp.getWriter().print(testContent);
|
|
||||||
}
|
|
||||||
}, "/test.txt"));
|
|
||||||
this.webServer.start();
|
|
||||||
return testContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JspServlet getJspServlet() throws Exception {
|
protected JspServlet getJspServlet() throws Exception {
|
||||||
WebAppContext context = (WebAppContext) ((JettyWebServer) this.webServer)
|
WebAppContext context = (WebAppContext) ((JettyWebServer) this.webServer)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,9 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
|
@ -775,10 +777,15 @@ public abstract class AbstractServletWebServerFactoryTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compression() throws Exception {
|
public void compressionOfResposeToGetRequest() throws Exception {
|
||||||
assertThat(doTestCompression(10000, null, null)).isTrue();
|
assertThat(doTestCompression(10000, null, null)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compressionOfResposeToPostRequest() throws Exception {
|
||||||
|
assertThat(doTestCompression(10000, null, null, HttpMethod.POST)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noCompressionForSmallResponse() throws Exception {
|
public void noCompressionForSmallResponse() throws Exception {
|
||||||
assertThat(doTestCompression(100, null, null)).isFalse();
|
assertThat(doTestCompression(100, null, null)).isFalse();
|
||||||
|
|
@ -991,12 +998,18 @@ public abstract class AbstractServletWebServerFactoryTests {
|
||||||
|
|
||||||
private boolean doTestCompression(int contentSize, String[] mimeTypes,
|
private boolean doTestCompression(int contentSize, String[] mimeTypes,
|
||||||
String[] excludedUserAgents) throws Exception {
|
String[] excludedUserAgents) throws Exception {
|
||||||
|
return doTestCompression(contentSize, mimeTypes, excludedUserAgents,
|
||||||
|
HttpMethod.GET);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doTestCompression(int contentSize, String[] mimeTypes,
|
||||||
|
String[] excludedUserAgents, HttpMethod method) throws Exception {
|
||||||
String testContent = setUpFactoryForCompression(contentSize, mimeTypes,
|
String testContent = setUpFactoryForCompression(contentSize, mimeTypes,
|
||||||
excludedUserAgents);
|
excludedUserAgents);
|
||||||
TestGzipInputStreamFactory inputStreamFactory = new TestGzipInputStreamFactory();
|
TestGzipInputStreamFactory inputStreamFactory = new TestGzipInputStreamFactory();
|
||||||
Map<String, InputStreamFactory> contentDecoderMap = Collections
|
Map<String, InputStreamFactory> contentDecoderMap = Collections
|
||||||
.singletonMap("gzip", (InputStreamFactory) inputStreamFactory);
|
.singletonMap("gzip", (InputStreamFactory) inputStreamFactory);
|
||||||
String response = getResponse(getLocalUrl("/test.txt"),
|
String response = getResponse(getLocalUrl("/test.txt"), method,
|
||||||
new HttpComponentsClientHttpRequestFactory(
|
new HttpComponentsClientHttpRequestFactory(
|
||||||
HttpClientBuilder.create().setUserAgent("testUserAgent")
|
HttpClientBuilder.create().setUserAgent("testUserAgent")
|
||||||
.setContentDecoderRegistry(contentDecoderMap).build()));
|
.setContentDecoderRegistry(contentDecoderMap).build()));
|
||||||
|
|
@ -1004,15 +1017,12 @@ public abstract class AbstractServletWebServerFactoryTests {
|
||||||
return inputStreamFactory.wasCompressionUsed();
|
return inputStreamFactory.wasCompressionUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String setUpFactoryForCompression(int contentSize, String[] mimeTypes,
|
private String setUpFactoryForCompression(int contentSize, String[] mimeTypes,
|
||||||
String[] excludedUserAgents) throws Exception {
|
String[] excludedUserAgents) throws Exception {
|
||||||
char[] chars = new char[contentSize];
|
char[] chars = new char[contentSize];
|
||||||
Arrays.fill(chars, 'F');
|
Arrays.fill(chars, 'F');
|
||||||
String testContent = new String(chars);
|
String testContent = new String(chars);
|
||||||
AbstractServletWebServerFactory factory = getFactory();
|
AbstractServletWebServerFactory factory = getFactory();
|
||||||
FileCopyUtils.copy(testContent,
|
|
||||||
new FileWriter(this.temporaryFolder.newFile("test.txt")));
|
|
||||||
factory.setDocumentRoot(this.temporaryFolder.getRoot());
|
|
||||||
Compression compression = new Compression();
|
Compression compression = new Compression();
|
||||||
compression.setEnabled(true);
|
compression.setEnabled(true);
|
||||||
if (mimeTypes != null) {
|
if (mimeTypes != null) {
|
||||||
|
|
@ -1022,6 +1032,20 @@ public abstract class AbstractServletWebServerFactoryTests {
|
||||||
compression.setExcludedUserAgents(excludedUserAgents);
|
compression.setExcludedUserAgents(excludedUserAgents);
|
||||||
}
|
}
|
||||||
factory.setCompression(compression);
|
factory.setCompression(compression);
|
||||||
|
factory.addInitializers(
|
||||||
|
new ServletRegistrationBean<HttpServlet>(new HttpServlet() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void service(HttpServletRequest req,
|
||||||
|
HttpServletResponse resp)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
resp.setContentType("text/plain");
|
||||||
|
resp.setContentLength(testContent.length());
|
||||||
|
resp.getWriter().write(testContent);
|
||||||
|
resp.getWriter().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
}, "/test.txt"));
|
||||||
this.webServer = factory.getWebServer();
|
this.webServer = factory.getWebServer();
|
||||||
this.webServer.start();
|
this.webServer.start();
|
||||||
return testContent;
|
return testContent;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue