Skip to content

Commit dbbb378

Browse files
qctsnicoll
authored andcommitted
Align max HTTP header size configuration
See gh-14234
1 parent 7de9653 commit dbbb378

File tree

8 files changed

+60
-15
lines changed

8 files changed

+60
-15
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
* @author Aurélien Leboulanger
5454
* @author Brian Clozel
5555
* @author Olivier Lamy
56+
* @author Chentao Qu
5657
*/
5758
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
5859
public class ServerProperties {
@@ -81,9 +82,9 @@ public class ServerProperties {
8182
private String serverHeader;
8283

8384
/**
84-
* Maximum size, in bytes, of the HTTP message header.
85+
* Maximum size of the HTTP message header.
8586
*/
86-
private int maxHttpHeaderSize = 0; // bytes
87+
private DataSize maxHttpHeaderSize = DataSize.ofKiloBytes(8L);
8788

8889
/**
8990
* Time that connectors wait for another HTTP request before closing the connection.
@@ -141,11 +142,11 @@ public void setServerHeader(String serverHeader) {
141142
this.serverHeader = serverHeader;
142143
}
143144

144-
public int getMaxHttpHeaderSize() {
145+
public DataSize getMaxHttpHeaderSize() {
145146
return this.maxHttpHeaderSize;
146147
}
147148

148-
public void setMaxHttpHeaderSize(int maxHttpHeaderSize) {
149+
public void setMaxHttpHeaderSize(DataSize maxHttpHeaderSize) {
149150
this.maxHttpHeaderSize = maxHttpHeaderSize;
150151
}
151152

@@ -327,7 +328,9 @@ public static class Tomcat {
327328

328329
/**
329330
* Maximum size, in bytes, of the HTTP message header.
331+
* @deprecated since 2.1.0 in favor of {@link ServerProperties#maxHttpHeaderSize}
330332
*/
333+
@Deprecated
331334
private int maxHttpHeaderSize = 0;
332335

333336
/**

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
3737
import org.springframework.core.Ordered;
3838
import org.springframework.core.env.Environment;
39+
import org.springframework.util.unit.DataSize;
3940

4041
/**
4142
* Customization for Jetty-specific features common for both Servlet and Reactive servers.
@@ -73,7 +74,8 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
7374
.to(factory::setAcceptors);
7475
propertyMapper.from(jettyProperties::getSelectors).whenNonNull()
7576
.to(factory::setSelectors);
76-
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive)
77+
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull()
78+
.asInt(DataSize::toBytes)
7779
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
7880
maxHttpHeaderSize));
7981
propertyMapper.from(jettyProperties::getMaxHttpPostSize).when(this::isPositive)
@@ -133,7 +135,6 @@ public void customize(Server server) {
133135
private void customize(HttpConfiguration.ConnectionFactory factory) {
134136
HttpConfiguration configuration = factory.getHttpConfiguration();
135137
configuration.setRequestHeaderSize(maxHttpHeaderSize);
136-
configuration.setResponseHeaderSize(maxHttpHeaderSize);
137138
}
138139

139140
});

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,19 @@
1818

1919
import org.springframework.boot.autoconfigure.web.ServerProperties;
2020
import org.springframework.boot.cloud.CloudPlatform;
21+
import org.springframework.boot.context.properties.PropertyMapper;
2122
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
23+
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
2224
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
2325
import org.springframework.core.Ordered;
2426
import org.springframework.core.env.Environment;
27+
import org.springframework.util.unit.DataSize;
2528

2629
/**
2730
* Customization for Netty-specific features.
2831
*
2932
* @author Brian Clozel
33+
* @author Chentao Qu
3034
* @since 2.1.0
3135
*/
3236
public class NettyWebServerFactoryCustomizer
@@ -51,6 +55,11 @@ public int getOrder() {
5155
public void customize(NettyReactiveWebServerFactory factory) {
5256
factory.setUseForwardHeaders(
5357
getOrDeduceUseForwardHeaders(this.serverProperties, this.environment));
58+
PropertyMapper propertyMapper = PropertyMapper.get();
59+
propertyMapper.from(this.serverProperties::getMaxHttpHeaderSize).whenNonNull()
60+
.asInt(DataSize::toBytes)
61+
.to((maxHttpRequestHeaderSize) -> customizeMaxHttpHeaderSize(factory,
62+
maxHttpRequestHeaderSize));
5463
}
5564

5665
private boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties,
@@ -62,4 +71,11 @@ private boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties,
6271
return platform != null && platform.isUsingForwardHeaders();
6372
}
6473

74+
private void customizeMaxHttpHeaderSize(NettyReactiveWebServerFactory factory,
75+
Integer maxHttpHeaderSize) {
76+
factory.addServerCustomizers((NettyServerCustomizer) (httpServer) -> httpServer
77+
.httpRequestDecoder((httpRequestDecoderSpec) -> httpRequestDecoderSpec
78+
.maxHeaderSize(maxHttpHeaderSize)));
79+
}
80+
6581
}

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
* @author Stephane Nicoll
4949
* @author Phillip Webb
5050
* @author Artsiom Yudovin
51+
* @author Chentao Qu
5152
* @since 2.0.0
5253
*/
5354
public class TomcatWebServerFactoryCustomizer implements
@@ -84,7 +85,8 @@ public void customize(ConfigurableTomcatWebServerFactory factory) {
8485
tomcatProperties.getMaxThreads()));
8586
propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive)
8687
.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
87-
propertyMapper.from(this::determineMaxHttpHeaderSize).when(this::isPositive)
88+
propertyMapper.from(this::determineMaxHttpHeaderSize).whenNonNull()
89+
.asInt(DataSize::toBytes)
8890
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
8991
maxHttpHeaderSize));
9092
propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull()
@@ -114,10 +116,11 @@ private boolean isPositive(int value) {
114116
return value > 0;
115117
}
116118

117-
private int determineMaxHttpHeaderSize() {
118-
return (this.serverProperties.getMaxHttpHeaderSize() > 0)
119-
? this.serverProperties.getMaxHttpHeaderSize()
120-
: this.serverProperties.getTomcat().getMaxHttpHeaderSize();
119+
private DataSize determineMaxHttpHeaderSize() {
120+
return isPositive(this.serverProperties.getTomcat().getMaxHttpHeaderSize())
121+
? DataSize
122+
.ofBytes(this.serverProperties.getTomcat().getMaxHttpHeaderSize())
123+
: this.serverProperties.getMaxHttpHeaderSize();
121124
}
122125

123126
private void customizeAcceptCount(ConfigurableTomcatWebServerFactory factory,

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
2828
import org.springframework.core.Ordered;
2929
import org.springframework.core.env.Environment;
30+
import org.springframework.util.unit.DataSize;
3031

3132
/**
3233
* Customization for Undertow-specific features common for both Servlet and Reactive
@@ -83,7 +84,8 @@ public void customize(ConfigurableUndertowWebServerFactory factory) {
8384
.to(factory::setAccessLogRotate);
8485
propertyMapper.from(this::getOrDeduceUseForwardHeaders)
8586
.to(factory::setUseForwardHeaders);
86-
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive)
87+
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull()
88+
.asInt(DataSize::toBytes)
8789
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
8890
maxHttpHeaderSize));
8991
propertyMapper.from(undertowProperties::getMaxHttpPostSize).when(this::isPositive)

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.boot.context.properties.bind.Binder;
3030
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
3131
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
32+
import org.springframework.util.unit.DataSize;
3233

3334
import static org.assertj.core.api.Assertions.assertThat;
3435

@@ -136,7 +137,8 @@ public void testCustomizeUriEncoding() {
136137
@Test
137138
public void testCustomizeHeaderSize() {
138139
bind("server.max-http-header-size", "9999");
139-
assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(9999);
140+
assertThat(this.properties.getMaxHttpHeaderSize())
141+
.isEqualTo(DataSize.ofBytes(9999));
140142
}
141143

142144
@Test

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import java.util.Locale;
2222
import java.util.TimeZone;
2323

24+
import org.eclipse.jetty.server.Connector;
25+
import org.eclipse.jetty.server.HttpConfiguration;
26+
import org.eclipse.jetty.server.HttpConfiguration.ConnectionFactory;
2427
import org.eclipse.jetty.server.NCSARequestLog;
2528
import org.eclipse.jetty.server.RequestLog;
2629
import org.junit.Before;
@@ -140,6 +143,21 @@ public void setUseForwardHeaders() {
140143
verify(factory).setUseForwardHeaders(true);
141144
}
142145

146+
@Test
147+
public void customizeMaxHttpHeaderSize() {
148+
bind("server.max-http-header-size=2048");
149+
JettyWebServer server = customizeAndGetServer();
150+
for (Connector connector : server.getServer().getConnectors()) {
151+
connector.getConnectionFactories().stream()
152+
.filter((factory) -> factory instanceof ConnectionFactory)
153+
.forEach((cf) -> {
154+
ConnectionFactory factory = (ConnectionFactory) cf;
155+
HttpConfiguration configuration = factory.getHttpConfiguration();
156+
assertThat(configuration.getRequestHeaderSize()).isEqualTo(2048);
157+
});
158+
}
159+
}
160+
143161
private void bind(String... inlinedProperties) {
144162
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
145163
inlinedProperties);

spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ content into your application. Rather, pick only the properties that you need.
207207
server.jetty.accesslog.time-zone=GMT # Timezone of the request log.
208208
server.jetty.max-http-post-size=0 # Maximum size, in bytes, of the HTTP post or put content.
209209
server.jetty.selectors= # Number of selector threads to use.
210-
server.max-http-header-size=0 # Maximum size, in bytes, of the HTTP message header.
210+
server.max-http-header-size=8KB # Maximum size of the HTTP message header.
211211
server.port=8080 # Server HTTP port.
212212
server.server-header= # Value to use for the Server response header (if empty, no header is sent).
213213
server.use-forward-headers= # Whether X-Forwarded-* headers should be applied to the HttpRequest.
@@ -265,7 +265,7 @@ content into your application. Rather, pick only the properties that you need.
265265
172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|\\
266266
172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3} # Regular expression matching trusted IP addresses.
267267
server.tomcat.max-connections=0 # Maximum number of connections that the server accepts and processes at any given time.
268-
server.tomcat.max-http-header-size=0 # Maximum size, in bytes, of the HTTP message header.
268+
server.tomcat.max-http-header-size=0 # Maximum size, in bytes, of the HTTP message header. Deprecated, use server.max-http-header-size instead.
269269
server.tomcat.max-http-post-size=0 # Maximum size, in bytes, of the HTTP post content.
270270
server.tomcat.max-swallow-size=2MB # Maximum amount of request body to swallow.
271271
server.tomcat.max-threads=0 # Maximum number of worker threads.

0 commit comments

Comments
 (0)