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 b943184bda4..68bc334d47f 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 @@ -329,6 +329,11 @@ public class ServerProperties { */ private int maxHttpHeaderSize = 0; + /** + * Maximum amount of request body bytes to swallow. + */ + private int maxSwallowSize = 4096; + /** * Whether requests to the context root should be redirected by appending a / to * the path. @@ -491,6 +496,14 @@ public class ServerProperties { return this.maxHttpHeaderSize; } + public int getMaxSwallowSize() { + return this.maxSwallowSize; + } + + public void setMaxSwallowSize(int maxSwallowSize) { + this.maxSwallowSize = maxSwallowSize; + } + public void setMaxHttpHeaderSize(int maxHttpHeaderSize) { this.maxHttpHeaderSize = maxHttpHeaderSize; } 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 a39f6df1a34..b2f70db2f62 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 @@ -85,6 +86,8 @@ public class TomcatWebServerFactoryCustomizer implements propertyMapper.from(() -> determineMaxHttpHeaderSize()).when(this::isPositive) .to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize)); + propertyMapper.from(tomcatProperties::getMaxSwallowSize) + .to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize)); propertyMapper.from(tomcatProperties::getMaxHttpPostSize) .when((maxHttpPostSize) -> maxHttpPostSize != 0) .to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory, @@ -216,6 +219,17 @@ public class TomcatWebServerFactoryCustomizer implements }); } + 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); + } + }); + } + private void customizeMaxHttpPostSize(ConfigurableTomcatWebServerFactory factory, int maxHttpPostSize) { factory.addConnectorCustomizers( 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 ce43fac13dc..d5b58abaefc 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,8 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Brian Clozel * @author Phillip Webb * @author Rob Tompkins + * @author Artsiom Yudovin + * @author Stephane Nicoll */ public class TomcatWebServerFactoryCustomizerTests { @@ -67,6 +70,15 @@ public class TomcatWebServerFactoryCustomizerTests { this.serverProperties); } + @Test + public void defaultsAreConsistent() { + customizeAndRunServer((server) -> { + assertThat(((AbstractHttp11Protocol) server.getTomcat().getConnector() + .getProtocolHandler()).getMaxSwallowSize()).isEqualTo( + this.serverProperties.getTomcat().getMaxSwallowSize()); + }); + } + @Test public void customAcceptCount() { bind("server.tomcat.accept-count=10"); @@ -107,6 +119,14 @@ public class TomcatWebServerFactoryCustomizerTests { .isEqualTo(10000)); } + @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 customRemoteIpValve() { bind("server.tomcat.remote-ip-header=x-my-remote-ip-header", 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 dbc2f8d9af1..50add4549be 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 @@ -252,6 +252,7 @@ content into your application. Rather, pick only the properties that you need. server.tomcat.max-connections=0 # Maximum number of connections that the server accepts and processes at any given time. server.tomcat.max-http-header-size=0 # Maximum size, in bytes, of the HTTP message header. server.tomcat.max-http-post-size=0 # Maximum size, in bytes, of the HTTP post content. + server.tomcat.max-swallow-size=4096 # Maximum amount of request body bytes to swallow. server.tomcat.max-threads=0 # Maximum number of worker threads. server.tomcat.min-spare-threads=0 # Minimum number of worker threads. server.tomcat.port-header=X-Forwarded-Port # Name of the HTTP header used to override the original port value.