From 0d40c5aeccacb3123d3d5b4eb4391031cddb4adf Mon Sep 17 00:00:00 2001 From: artsiom Date: Tue, 31 Jul 2018 23:53:30 +0300 Subject: [PATCH] Make "MaxSwallowSize" more easily configurable See gh-13966 --- .../boot/autoconfigure/web/ServerProperties.java | 14 ++++++++++++++ .../TomcatWebServerFactoryCustomizer.java | 16 ++++++++++++++++ .../autoconfigure/web/ServerPropertiesTests.java | 3 +++ .../TomcatWebServerFactoryCustomizerTests.java | 10 ++++++++++ .../appendix-application-properties.adoc | 1 + 5 files changed, 44 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index b943184bda..d793754dfc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -52,6 +52,7 @@ import org.springframework.util.StringUtils; * @author Aurélien Leboulanger * @author Brian Clozel * @author Olivier Lamy + * @author Artsiom Yudovin */ @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true) public class ServerProperties { @@ -359,6 +360,11 @@ public class ServerProperties { */ private int acceptCount = 0; + /** + * Maximum amount of request body to swallow. + */ + private int maxSwallowSize = 0; + /** * Comma-separated list of additional patterns that match jars to ignore for TLD * scanning. The special '?' and '*' characters can be used in the pattern to @@ -503,6 +509,14 @@ public class ServerProperties { this.acceptCount = acceptCount; } + public int getMaxSwallowSize() { + return this.maxSwallowSize; + } + + public void setMaxSwallowSize(int maxSwallowSize) { + this.maxSwallowSize = maxSwallowSize; + } + public List getAdditionalTldSkipPatterns() { return this.additionalTldSkipPatterns; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index a39f6df1a3..be0bcc0d86 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -46,6 +46,7 @@ import org.springframework.util.StringUtils; * @author Yulin Qin * @author Stephane Nicoll * @author Phillip Webb + * @author Artsiom Yudovin * @since 2.0.0 */ public class TomcatWebServerFactoryCustomizer implements @@ -101,6 +102,9 @@ public class TomcatWebServerFactoryCustomizer implements .to((maxConnections) -> customizeMaxConnections(factory, maxConnections)); propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive) .to((acceptCount) -> customizeAcceptCount(factory, acceptCount)); + propertyMapper.from(tomcatProperties::getMaxSwallowSize) + .when((maxSwallowSize) -> maxSwallowSize != 0) + .to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize)); customizeStaticResources(factory); customizeErrorReportValve(properties.getError(), factory); } @@ -266,4 +270,16 @@ public class TomcatWebServerFactoryCustomizer implements } } + @SuppressWarnings("rawtypes") + private void customizeMaxSwallowSize(ConfigurableTomcatWebServerFactory factory, + int maxSwallowSize) { + factory.addConnectorCustomizers((connector) -> { + ProtocolHandler handler = connector.getProtocolHandler(); + if (handler instanceof AbstractHttp11Protocol) { + AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler; + protocol.setMaxSwallowSize(maxSwallowSize); + } + }); + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java index 771c3b646c..c7763e61bb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java @@ -42,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Eddú Meléndez * @author Quinten De Swaef * @author Venil Noronha + * @author Artsiom Yudovin */ public class ServerPropertiesTests { @@ -91,6 +92,7 @@ public class ServerPropertiesTests { map.put("server.tomcat.remote-ip-header", "Remote-Ip"); map.put("server.tomcat.internal-proxies", "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); map.put("server.tomcat.background-processor-delay", "10"); + map.put("server.tomcat.max-swallow-size", "2"); bind(map); ServerProperties.Tomcat tomcat = this.properties.getTomcat(); assertThat(tomcat.getAccesslog().getPattern()).isEqualTo("%h %t '%r' %s %b"); @@ -105,6 +107,7 @@ public class ServerPropertiesTests { .isEqualTo("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); assertThat(tomcat.getBackgroundProcessorDelay()) .isEqualTo(Duration.ofSeconds(10)); + assertThat(tomcat.getMaxSwallowSize()).isEqualTo(2); } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index ce43fac13d..ad02f42963 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -28,6 +28,7 @@ import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.RemoteIpValve; import org.apache.catalina.webresources.StandardRoot; import org.apache.coyote.AbstractProtocol; +import org.apache.coyote.http11.AbstractHttp11Protocol; import org.junit.Before; import org.junit.Test; @@ -49,6 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Brian Clozel * @author Phillip Webb * @author Rob Tompkins + * @author Artsiom Yudovin */ public class TomcatWebServerFactoryCustomizerTests { @@ -67,6 +69,14 @@ public class TomcatWebServerFactoryCustomizerTests { this.serverProperties); } + @Test + public void customMaxSwallowSize() { + bind("server.tomcat.max-swallow-size=10"); + customizeAndRunServer((server) -> assertThat(((AbstractHttp11Protocol) server + .getTomcat().getConnector().getProtocolHandler()).getMaxSwallowSize()) + .isEqualTo(10)); + } + @Test public void customAcceptCount() { bind("server.tomcat.accept-count=10"); 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 dbc2f8d9af..bd12b0a38d 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 @@ -263,6 +263,7 @@ content into your application. Rather, pick only the properties that you need. server.tomcat.resource.cache-ttl= # Time-to-live of the static resource cache. server.tomcat.uri-encoding=UTF-8 # Character encoding to use to decode the URI. server.tomcat.use-relative-redirects= # Whether HTTP 1.1 and later location headers generated by a call to sendRedirect will use relative or absolute redirects. + server.tomcat.max-swallow-size= # Maximum amount of request body to swallow. server.undertow.accesslog.dir= # Undertow access log directory. server.undertow.accesslog.enabled=false # Whether to enable the access log. server.undertow.accesslog.pattern=common # Format pattern for access logs.