Skip to content

Commit

Permalink
Configure Jetty to compress responses to requests other than GET
Browse files Browse the repository at this point in the history
Closes gh-8184
  • Loading branch information
wilkinsona committed Jul 22, 2017
1 parent 6df1be3 commit bc46039
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.AbstractConnector;
Expand Down Expand Up @@ -229,6 +230,9 @@ private HandlerWrapper createGzipHandler() {
Compression compression = getCompression();
handler.setMinGzipSize(compression.getMinResponseSize());
handler.setIncludedMimeTypes(compression.getMimeTypes());
for (HttpMethod httpMethod : HttpMethod.values()) {
handler.addIncludedMethods(httpMethod.name());
}
if (compression.getExcludedUserAgents() != null) {
handler.setExcludedAgentPatterns(compression.getExcludedUserAgents());
}
Expand Down Expand Up @@ -581,8 +585,8 @@ public void setServerCustomizers(
}

/**
* Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be applied
* to the {@link Server} before the it is created.
* Returns a mutable collection of Jetty {@link JettyServerCustomizer}s that will be
* applied to the {@link Server} before the it is created.
* @return the {@link JettyServerCustomizer}s
*/
public Collection<JettyServerCustomizer> getServerCustomizers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,12 @@

package org.springframework.boot.web.embedded.jetty;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
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.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
Expand All @@ -43,13 +37,10 @@
import org.junit.Test;
import org.mockito.InOrder;

import org.springframework.boot.web.server.Compression;
import org.springframework.boot.web.server.PortInUseException;
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.AbstractServletWebServerFactoryTests;
import org.springframework.http.HttpHeaders;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.isA;
Expand Down Expand Up @@ -296,38 +287,6 @@ public void customize(Server server) {
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
protected JspServlet getJspServlet() throws Exception {
WebAppContext context = (WebAppContext) ((JettyWebServer) this.webServer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.http.client.HttpClient;
Expand Down Expand Up @@ -775,10 +777,15 @@ public void getValidSessionStoreWhenSessionStoreReferencesFile() throws Exceptio
}

@Test
public void compression() throws Exception {
public void compressionOfResposeToGetRequest() throws Exception {
assertThat(doTestCompression(10000, null, null)).isTrue();
}

@Test
public void compressionOfResposeToPostRequest() throws Exception {
assertThat(doTestCompression(10000, null, null, HttpMethod.POST)).isTrue();
}

@Test
public void noCompressionForSmallResponse() throws Exception {
assertThat(doTestCompression(100, null, null)).isFalse();
Expand Down Expand Up @@ -991,28 +998,31 @@ protected abstract void handleExceptionCausedByBlockedPort(RuntimeException ex,

private boolean doTestCompression(int contentSize, String[] mimeTypes,
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,
excludedUserAgents);
TestGzipInputStreamFactory inputStreamFactory = new TestGzipInputStreamFactory();
Map<String, InputStreamFactory> contentDecoderMap = Collections
.singletonMap("gzip", (InputStreamFactory) inputStreamFactory);
String response = getResponse(getLocalUrl("/test.txt"),
String response = getResponse(getLocalUrl("/test.txt"), method,
new HttpComponentsClientHttpRequestFactory(
HttpClientBuilder.create().setUserAgent("testUserAgent")
.setContentDecoderRegistry(contentDecoderMap).build()));
assertThat(response).isEqualTo(testContent);
return inputStreamFactory.wasCompressionUsed();
}

protected String setUpFactoryForCompression(int contentSize, String[] mimeTypes,
private String setUpFactoryForCompression(int contentSize, String[] mimeTypes,
String[] excludedUserAgents) throws Exception {
char[] chars = new char[contentSize];
Arrays.fill(chars, 'F');
String testContent = new String(chars);
AbstractServletWebServerFactory factory = getFactory();
FileCopyUtils.copy(testContent,
new FileWriter(this.temporaryFolder.newFile("test.txt")));
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Compression compression = new Compression();
compression.setEnabled(true);
if (mimeTypes != null) {
Expand All @@ -1022,6 +1032,20 @@ protected String setUpFactoryForCompression(int contentSize, String[] mimeTypes,
compression.setExcludedUserAgents(excludedUserAgents);
}
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.start();
return testContent;
Expand Down

0 comments on commit bc46039

Please sign in to comment.