From b1e9fdc3ecf49be576a2727eb2147677ee194902 Mon Sep 17 00:00:00 2001 From: jdsalasca Date: Wed, 21 Jan 2026 16:31:01 -0500 Subject: [PATCH] Provide support for adding to the mime types that are compressed Signed-off-by: jdsalasca See gh-48930 --- .../boot/jetty/JettyHandlerWrappers.java | 2 +- .../reactor/netty/CompressionCustomizer.java | 2 +- .../CompressionConnectorCustomizer.java | 2 +- .../boot/web/server/Compression.java | 23 +++++++++++++++++++ .../autoconfigure/ServerPropertiesTests.java | 8 +++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java index 70cbb19a349..4b86404cd9b 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/JettyHandlerWrappers.java @@ -46,7 +46,7 @@ final class JettyHandlerWrappers { gzip.setMinCompressSize((int) compression.getMinResponseSize().toBytes()); compressionHandler.putCompression(gzip); Builder configBuilder = CompressionConfig.builder(); - for (String mimeType : compression.getMimeTypes()) { + for (String mimeType : compression.getAllMimeTypes()) { configBuilder.compressIncludeMimeType(mimeType); } for (HttpMethod httpMethod : HttpMethod.values()) { diff --git a/module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java b/module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java index 61c340482e9..b7136524ac9 100644 --- a/module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java +++ b/module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/CompressionCustomizer.java @@ -56,7 +56,7 @@ final class CompressionCustomizer implements NettyServerCustomizer { if (!this.compression.getMinResponseSize().isNegative()) { server = server.compress((int) this.compression.getMinResponseSize().toBytes()); } - CompressionPredicate mimeTypes = getMimeTypesPredicate(this.compression.getMimeTypes()); + CompressionPredicate mimeTypes = getMimeTypesPredicate(this.compression.getAllMimeTypes()); CompressionPredicate excludedUserAgents = getExcludedUserAgentsPredicate( this.compression.getExcludedUserAgents()); server = server.compress(mimeTypes.and(excludedUserAgents)); diff --git a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java index 2f85cf9ceb2..31eaa4b8d6e 100644 --- a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java +++ b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/CompressionConnectorCustomizer.java @@ -63,7 +63,7 @@ public class CompressionConnectorCustomizer implements TomcatConnectorCustomizer } private String getMimeTypes(Compression compression) { - return StringUtils.arrayToCommaDelimitedString(compression.getMimeTypes()); + return StringUtils.arrayToCommaDelimitedString(compression.getAllMimeTypes()); } private String getExcludedUserAgents(Compression compression) { diff --git a/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java b/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java index 76a530ce6d1..cc43ff3b6db 100644 --- a/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java +++ b/module/spring-boot-web-server/src/main/java/org/springframework/boot/web/server/Compression.java @@ -19,6 +19,7 @@ package org.springframework.boot.web.server; import org.jspecify.annotations.Nullable; import org.springframework.boot.context.properties.ConfigurationPropertiesSource; +import org.springframework.util.StringUtils; import org.springframework.util.unit.DataSize; /** @@ -43,6 +44,11 @@ public class Compression { private String[] mimeTypes = new String[] { "text/html", "text/xml", "text/plain", "text/css", "text/javascript", "application/javascript", "application/json", "application/xml" }; + /** + * Comma-separated list of additional MIME types that should be compressed. + */ + private String[] additionalMimeTypes = new String[0]; + /** * Comma-separated list of user agents for which responses should not be compressed. */ @@ -77,6 +83,23 @@ public class Compression { this.mimeTypes = mimeTypes; } + /** + * Return the MIME types that should be compressed, including any additional types. + * @return the MIME types that should be compressed + */ + public String[] getAllMimeTypes() { + String[] combined = StringUtils.concatenateStringArrays(this.mimeTypes, this.additionalMimeTypes); + return (combined != null) ? combined : this.mimeTypes; + } + + public String[] getAdditionalMimeTypes() { + return this.additionalMimeTypes; + } + + public void setAdditionalMimeTypes(String[] additionalMimeTypes) { + this.additionalMimeTypes = additionalMimeTypes; + } + public String @Nullable [] getExcludedUserAgents() { return this.excludedUserAgents; } diff --git a/module/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/ServerPropertiesTests.java b/module/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/ServerPropertiesTests.java index 2e4f4eae506..97aa2b566f1 100644 --- a/module/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/ServerPropertiesTests.java +++ b/module/spring-boot-web-server/src/test/java/org/springframework/boot/web/server/autoconfigure/ServerPropertiesTests.java @@ -27,6 +27,7 @@ import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; +import org.springframework.boot.web.server.Compression; import org.springframework.boot.web.server.MimeMappings; import org.springframework.boot.web.server.MimeMappings.Mapping; import org.springframework.util.unit.DataSize; @@ -148,6 +149,13 @@ class ServerPropertiesTests { .isEqualTo(new Http11Nio2Protocol().getMaxHttpRequestHeaderSize()); } + @Test + void additionalCompressionMimeTypesAreAddedToDefaults() { + bind("server.compression.additional-mime-types", "application/zip"); + assertThat(this.properties.getCompression().getAllMimeTypes()).contains(new Compression().getMimeTypes()); + assertThat(this.properties.getCompression().getAllMimeTypes()).contains("application/zip"); + } + private void bind(String name, String value) { bind(Collections.singletonMap(name, value)); }