Skip to content

Commit a188fff

Browse files
committed
Add support for configuring Tomcat connector's max part count, max part header size
See gh-45881 Signed-off-by: Daeho Kwon <[email protected]>
1 parent 0daf3f5 commit a188fff

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
* @author Florian Storz
7474
* @author Michael Weidmann
7575
* @author Lasse Wulff
76+
* @author Daeho Kwon
7677
* @since 1.0.0
7778
*/
7879
@ConfigurationProperties("server")
@@ -519,6 +520,21 @@ public static class Tomcat {
519520
*/
520521
private int maxParameterCount = 10000;
521522

523+
/**
524+
* The maximum total number of parts permitted in a request where the content type
525+
* is multipart/form-data. This limit is in addition to maxParameterCount.
526+
* Requests that exceed this limit will be rejected. A value of less than 0 means
527+
* no limit.
528+
*/
529+
private int maxPartCount = 10;
530+
531+
/**
532+
* The maximum number of header bytes permitted per part in a request where the
533+
* content type is multipart/form-data. Requests that exceed this limit will be
534+
* rejected. A value of less than 0 means no limit.
535+
*/
536+
private DataSize maxPartHeaderSize = DataSize.ofBytes(512);
537+
522538
/**
523539
* Whether to use APR.
524540
*/
@@ -688,6 +704,22 @@ public void setMaxParameterCount(int maxParameterCount) {
688704
this.maxParameterCount = maxParameterCount;
689705
}
690706

707+
public int getMaxPartCount() {
708+
return this.maxPartCount;
709+
}
710+
711+
public void setMaxPartCount(int maxPartCount) {
712+
this.maxPartCount = maxPartCount;
713+
}
714+
715+
public DataSize getMaxPartHeaderSize() {
716+
return this.maxPartHeaderSize;
717+
}
718+
719+
public void setMaxPartHeaderSize(DataSize maxPartHeaderSize) {
720+
this.maxPartHeaderSize = maxPartHeaderSize;
721+
}
722+
691723
public UseApr getUseApr() {
692724
return this.useApr;
693725
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
* @author Parviz Rozikov
6363
* @author Florian Storz
6464
* @author Michael Weidmann
65+
* @author Daeho Kwon
6566
* @since 2.0.0
6667
*/
6768
public class TomcatWebServerFactoryCustomizer
@@ -121,6 +122,10 @@ public void customize(ConfigurableTomcatWebServerFactory factory) {
121122
.to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize));
122123
map.from(properties::getMaxParameterCount)
123124
.to((maxParameterCount) -> customizeMaxParameterCount(factory, maxParameterCount));
125+
map.from(properties::getMaxPartCount).to((maxPartCount) -> customizeMaxPartCount(factory, maxPartCount));
126+
map.from(properties::getMaxPartHeaderSize)
127+
.asInt(DataSize::toBytes)
128+
.to((maxPartHeaderSize) -> customizeMaxPartHeaderSize(factory, maxPartHeaderSize));
124129
map.from(properties::getAccesslog)
125130
.when(ServerProperties.Tomcat.Accesslog::isEnabled)
126131
.to((enabled) -> customizeAccessLog(factory));
@@ -298,6 +303,14 @@ private void customizeMaxParameterCount(ConfigurableTomcatWebServerFactory facto
298303
factory.addConnectorCustomizers((connector) -> connector.setMaxParameterCount(maxParameterCount));
299304
}
300305

306+
private void customizeMaxPartCount(ConfigurableTomcatWebServerFactory factory, int maxPartCount) {
307+
factory.addConnectorCustomizers((connector) -> connector.setMaxPartCount(maxPartCount));
308+
}
309+
310+
private void customizeMaxPartHeaderSize(ConfigurableTomcatWebServerFactory factory, int maxPartHeaderSize) {
311+
factory.addConnectorCustomizers((connector) -> connector.setMaxPartHeaderSize(maxPartHeaderSize));
312+
}
313+
301314
private void customizeAccessLog(ConfigurableTomcatWebServerFactory factory) {
302315
ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat();
303316
AccessLogValve valve = new AccessLogValve();

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
* @author Parviz Rozikov
7272
* @author Lasse Wulff
7373
* @author Moritz Halbritter
74+
* @author Daeho Kwon
7475
*/
7576
@DirtiesUrlFactories
7677
class ServerPropertiesTests {
@@ -254,6 +255,18 @@ void testCustomizeTomcatMaxParameterCount() {
254255
assertThat(this.properties.getTomcat().getMaxParameterCount()).isEqualTo(100);
255256
}
256257

258+
@Test
259+
void testCustomizeTomcatMaxPartCount() {
260+
bind("server.tomcat.max-part-count", "20");
261+
assertThat(this.properties.getTomcat().getMaxPartCount()).isEqualTo(20);
262+
}
263+
264+
@Test
265+
void testCustomizeTomcatMaxPartHeaderSize() {
266+
bind("server.tomcat.max-part-header-size", "1024");
267+
assertThat(this.properties.getTomcat().getMaxPartHeaderSize()).isEqualTo(DataSize.ofKilobytes(1));
268+
}
269+
257270
@Test
258271
void testCustomizeTomcatMinSpareThreads() {
259272
bind("server.tomcat.threads.min-spare", "10");
@@ -393,6 +406,17 @@ void tomcatMaxParameterCountMatchesConnectorDefault() {
393406
.isEqualTo(getDefaultConnector().getMaxParameterCount());
394407
}
395408

409+
@Test
410+
void tomcatMaxPartCountMatchesConnectorDefault() {
411+
assertThat(this.properties.getTomcat().getMaxPartCount()).isEqualTo(getDefaultConnector().getMaxPartCount());
412+
}
413+
414+
@Test
415+
void tomcatMaxPartHeaderSizeMatchesConnectorDefault() {
416+
assertThat(this.properties.getTomcat().getMaxPartHeaderSize().toBytes())
417+
.isEqualTo(getDefaultConnector().getMaxPartHeaderSize());
418+
}
419+
396420
@Test
397421
void tomcatBackgroundProcessorDelayMatchesEngineDefault() {
398422
assertThat(this.properties.getTomcat().getBackgroundProcessorDelay())

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
* @author Victor Mandujano
6060
* @author Parviz Rozikov
6161
* @author Moritz Halbritter
62+
* @author Daeho Kwon
6263
*/
6364
class TomcatWebServerFactoryCustomizerTests {
6465

@@ -201,6 +202,20 @@ void customMaxParameterCount() {
201202
(server) -> assertThat(server.getTomcat().getConnector().getMaxParameterCount()).isEqualTo(100));
202203
}
203204

205+
@Test
206+
void customMaxPartCount() {
207+
bind("server.tomcat.max-part-count=20");
208+
customizeAndRunServer(
209+
(server) -> assertThat(server.getTomcat().getConnector().getMaxPartCount()).isEqualTo(20));
210+
}
211+
212+
@Test
213+
void customMaxPartHeaderSize() {
214+
bind("server.tomcat.max-part-header-size=1024");
215+
customizeAndRunServer(
216+
(server) -> assertThat(server.getTomcat().getConnector().getMaxPartHeaderSize()).isEqualTo(1024));
217+
}
218+
204219
@Test
205220
void customMaxRequestHttpHeaderSizeIgnoredIfNegative() {
206221
bind("server.max-http-request-header-size=-1");

0 commit comments

Comments
 (0)