Add support for configuring Tomcat’s gzip support using the environment

Tomcat provide built-it support for gzip compression of HTTP responses.
This commit adds support for enabling and configuring this compression
via the environment using server.tomcat.compression and
server.tomcat.compressableMimeTypes.

See gh-2031
This commit is contained in:
Andy Wilkinson 2015-01-15 14:18:18 +00:00
parent 704054a861
commit ec17c00126
2 changed files with 92 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -307,6 +307,19 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
*/
private String uriEncoding;
/**
* Controls response compression. Acceptable values are "off" to disable
* compression, "on" to enable compression of responses over 2048 bytes, "force"
* to force response compression, or an integer value to enable compression of
* responses with content length that is at least that value.
*/
private String compression = "off";
/**
* A comma-separated list of MIME types for which compression is used.
*/
private String compressableMimeTypes = "text/html,text/xml,text/plain";
public int getMaxThreads() {
return this.maxThreads;
}
@ -355,6 +368,22 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
this.accessLogPattern = accessLogPattern;
}
public String getCompressableMimeTypes() {
return this.compressableMimeTypes;
}
public void setCompressableMimeTypes(String compressableMimeTypes) {
this.compressableMimeTypes = compressableMimeTypes;
}
public String getCompression() {
return this.compression;
}
public void setCompression(String compression) {
this.compression = compression;
}
public String getInternalProxies() {
return this.internalProxies;
}
@ -447,6 +476,19 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
});
}
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
@SuppressWarnings("rawtypes")
AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler;
protocol.setCompression(Tomcat.this.compression);
protocol.setCompressableMimeTypes(Tomcat.this.compressableMimeTypes);
}
}
});
if (this.accessLogEnabled) {
AccessLogValve valve = new AccessLogValve();
String accessLogPattern = getAccessLogPattern();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,10 +23,12 @@ import java.util.Map;
import org.apache.catalina.Valve;
import org.apache.catalina.valves.RemoteIpValve;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
@ -193,6 +195,52 @@ public class ServerPropertiesTests {
assertEquals("192.168.0.1", remoteIpValve.getInternalProxies());
}
@Test
public void customTomcatCompression() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("server.port", "0");
map.put("server.tomcat.compression", "on");
bindProperties(map);
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
this.properties.customize(factory);
TomcatEmbeddedServletContainer container = (TomcatEmbeddedServletContainer) factory
.getEmbeddedServletContainer();
try {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) container
.getTomcat().getConnector().getProtocolHandler();
assertEquals("on", protocol.getCompression());
}
finally {
container.stop();
}
}
@Test
public void customTomcatCompressableMimeTypes() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("server.port", "0");
map.put("server.tomcat.compressableMimeTypes", "application/foo");
bindProperties(map);
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
this.properties.customize(factory);
TomcatEmbeddedServletContainer container = (TomcatEmbeddedServletContainer) factory
.getEmbeddedServletContainer();
try {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) container
.getTomcat().getConnector().getProtocolHandler();
assertEquals("application/foo", protocol.getCompressableMimeTypes());
}
finally {
container.stop();
}
}
private void bindProperties(Map<String, String> map) {
new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues(
map));