diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index fc6dae6e13..3551095503 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -163,7 +163,7 @@ content into your application. Rather, pick only the properties that you need. server.compression.enabled=false # Whether response compression is enabled. server.compression.excluded-user-agents= # List of user-agents to exclude from compression. server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript # Comma-separated list of MIME types that should be compressed. - server.compression.min-response-size=2048 # Minimum response size that is required for compression to be performed. + server.compression.min-response-size=2048 # Minimum "Content-Length" value that is required for compression to be performed. server.connection-timeout= # Time that connectors wait for another HTTP request before closing the connection. When not set, the connector's container-specific default is used. Use a value of -1 to indicate no (that is, an infinite) timeout. server.error.include-exception=false # Include the "exception" attribute. server.error.include-stacktrace=never # When to include a "stacktrace" attribute. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java index 4f1f64b013..7130e8b3dc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/CompressionCustomizer.java @@ -42,27 +42,22 @@ final class CompressionCustomizer implements NettyServerCustomizer { @Override public void customize(HttpServerOptions.Builder builder) { - if (compression.getMinResponseSize() >= 0) { - builder.compression(compression.getMinResponseSize()); + if (this.compression.getMinResponseSize() >= 0) { + builder.compression(this.compression.getMinResponseSize()); } - BiPredicate compressPredicate = null; - - if (compression.getMimeTypes() != null && - compression.getMimeTypes().length > 0) { - compressPredicate = new CompressibleMimeTypePredicate(compression.getMimeTypes()); + if (this.compression.getMimeTypes() != null && + this.compression.getMimeTypes().length > 0) { + compressPredicate = new CompressibleMimeTypePredicate(this.compression.getMimeTypes()); } - - if (compression.getExcludedUserAgents() != null && - compression.getExcludedUserAgents().length > 0 ) { + if (this.compression.getExcludedUserAgents() != null && + this.compression.getExcludedUserAgents().length > 0) { BiPredicate agentCompressPredicate = - new CompressibleAgentPredicate(compression.getExcludedUserAgents()); - + new CompressibleAgentPredicate(this.compression.getExcludedUserAgents()); compressPredicate = compressPredicate == null ? agentCompressPredicate : compressPredicate.and(agentCompressPredicate); } - if (compressPredicate != null) { builder.compression(compressPredicate); } @@ -80,9 +75,9 @@ final class CompressionCustomizer implements NettyServerCustomizer { @Override public boolean test(HttpServerRequest request, HttpServerResponse response) { - for(String excludedAgent : excludedAgents) { + for (String excludedAgent : this.excludedAgents) { if (request.requestHeaders() - .contains(HttpHeaderNames.USER_AGENT, excludedAgent, true)) { + .contains(HttpHeaderNames.USER_AGENT, excludedAgent, true)) { return false; } } @@ -105,7 +100,7 @@ final class CompressionCustomizer implements NettyServerCustomizer { @Override public boolean test(HttpServerRequest request, HttpServerResponse response) { String contentType = response.responseHeaders() - .get(HttpHeaderNames.CONTENT_TYPE); + .get(HttpHeaderNames.CONTENT_TYPE); if (contentType != null) { for (MimeType mimeType : this.mimeTypes) { if (mimeType.isCompatibleWith(MimeTypeUtils.parseMimeType(contentType))) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java index fe4991781b..36d48d1f75 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/Compression.java @@ -43,7 +43,7 @@ public class Compression { private String[] excludedUserAgents = null; /** - * Minimum response size that is required for compression to be performed. + * Minimum "Content-Length" value that is required for compression to be performed. */ private int minResponseSize = 2048; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java index 24fb278197..385fd05582 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/server/AbstractReactiveWebServerFactoryTests.java @@ -46,7 +46,6 @@ import reactor.ipc.netty.http.client.HttpClientOptions; import reactor.test.StepVerifier; import org.springframework.boot.testsupport.rule.OutputCapture; -import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory; import org.springframework.boot.web.server.Compression; import org.springframework.boot.web.server.Ssl; @@ -258,7 +257,7 @@ public abstract class AbstractReactiveWebServerFactoryTests { } @Test - public void compressionOfResponseToGetRequest() throws Exception { + public void compressionOfResponseToGetRequest() { WebClient client = prepareCompressionTest(); ResponseEntity response = client.get().exchange() .flatMap((res) -> res.toEntity(Void.class)).block(); @@ -266,7 +265,7 @@ public abstract class AbstractReactiveWebServerFactoryTests { } @Test - public void compressionOfResponseToPostRequest() throws Exception { + public void compressionOfResponseToPostRequest() { WebClient client = prepareCompressionTest(); ResponseEntity response = client.post().exchange() .flatMap((res) -> res.toEntity(Void.class)).block(); @@ -274,9 +273,10 @@ public abstract class AbstractReactiveWebServerFactoryTests { } @Test - public void noCompressionForMimeType() throws Exception { + public void noCompressionForSmallResponse() { Compression compression = new Compression(); - compression.setMimeTypes(new String[] { "application/json" }); + compression.setEnabled(true); + compression.setMinResponseSize(3001); WebClient client = prepareCompressionTest(compression); ResponseEntity response = client.get().exchange() .flatMap((res) -> res.toEntity(Void.class)).block(); @@ -284,10 +284,20 @@ public abstract class AbstractReactiveWebServerFactoryTests { } @Test - public void noCompressionForUserAgent() throws Exception { + public void noCompressionForMimeType() { + Compression compression = new Compression(); + compression.setMimeTypes(new String[] {"application/json"}); + WebClient client = prepareCompressionTest(compression); + ResponseEntity response = client.get().exchange() + .flatMap((res) -> res.toEntity(Void.class)).block(); + assertResponseIsNotCompressed(response); + } + + @Test + public void noCompressionForUserAgent() { Compression compression = new Compression(); compression.setEnabled(true); - compression.setExcludedUserAgents(new String[] { "testUserAgent" }); + compression.setExcludedUserAgents(new String[] {"testUserAgent"}); WebClient client = prepareCompressionTest(compression); ResponseEntity response = client.get().header("User-Agent", "testUserAgent") .exchange().flatMap((res) -> res.toEntity(Void.class)).block(); @@ -338,7 +348,7 @@ public abstract class AbstractReactiveWebServerFactoryTests { extends ChannelInboundHandlerAdapter { @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpResponse) { HttpResponse response = (HttpResponse) msg; boolean compressed = response.headers() @@ -371,6 +381,7 @@ public abstract class AbstractReactiveWebServerFactoryTests { public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { response.setStatusCode(HttpStatus.OK); response.getHeaders().setContentType(this.mediaType); + response.getHeaders().setContentLength(this.bytes.readableByteCount()); return response.writeWith(Mono.just(this.bytes)); }