Align max HTTP header size configuration
See gh-14234
This commit is contained in:
@@ -53,6 +53,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Brian Clozel
|
||||
* @author Olivier Lamy
|
||||
* @author Chentao Qu
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
|
||||
public class ServerProperties {
|
||||
@@ -81,9 +82,9 @@ public class ServerProperties {
|
||||
private String serverHeader;
|
||||
|
||||
/**
|
||||
* Maximum size, in bytes, of the HTTP message header.
|
||||
* Maximum size of the HTTP message header.
|
||||
*/
|
||||
private int maxHttpHeaderSize = 0; // bytes
|
||||
private DataSize maxHttpHeaderSize = DataSize.ofKiloBytes(8L);
|
||||
|
||||
/**
|
||||
* Time that connectors wait for another HTTP request before closing the connection.
|
||||
@@ -141,11 +142,11 @@ public class ServerProperties {
|
||||
this.serverHeader = serverHeader;
|
||||
}
|
||||
|
||||
public int getMaxHttpHeaderSize() {
|
||||
public DataSize getMaxHttpHeaderSize() {
|
||||
return this.maxHttpHeaderSize;
|
||||
}
|
||||
|
||||
public void setMaxHttpHeaderSize(int maxHttpHeaderSize) {
|
||||
public void setMaxHttpHeaderSize(DataSize maxHttpHeaderSize) {
|
||||
this.maxHttpHeaderSize = maxHttpHeaderSize;
|
||||
}
|
||||
|
||||
@@ -327,7 +328,9 @@ public class ServerProperties {
|
||||
|
||||
/**
|
||||
* Maximum size, in bytes, of the HTTP message header.
|
||||
* @deprecated since 2.1.0 in favor of {@link ServerProperties#maxHttpHeaderSize}
|
||||
*/
|
||||
@Deprecated
|
||||
private int maxHttpHeaderSize = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Customization for Jetty-specific features common for both Servlet and Reactive servers.
|
||||
@@ -73,7 +74,8 @@ public class JettyWebServerFactoryCustomizer implements
|
||||
.to(factory::setAcceptors);
|
||||
propertyMapper.from(jettyProperties::getSelectors).whenNonNull()
|
||||
.to(factory::setSelectors);
|
||||
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive)
|
||||
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull()
|
||||
.asInt(DataSize::toBytes)
|
||||
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
|
||||
maxHttpHeaderSize));
|
||||
propertyMapper.from(jettyProperties::getMaxHttpPostSize).when(this::isPositive)
|
||||
@@ -133,7 +135,6 @@ public class JettyWebServerFactoryCustomizer implements
|
||||
private void customize(HttpConfiguration.ConnectionFactory factory) {
|
||||
HttpConfiguration configuration = factory.getHttpConfiguration();
|
||||
configuration.setRequestHeaderSize(maxHttpHeaderSize);
|
||||
configuration.setResponseHeaderSize(maxHttpHeaderSize);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -18,15 +18,19 @@ package org.springframework.boot.autoconfigure.web.embedded;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Customization for Netty-specific features.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Chentao Qu
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class NettyWebServerFactoryCustomizer
|
||||
@@ -51,6 +55,11 @@ public class NettyWebServerFactoryCustomizer
|
||||
public void customize(NettyReactiveWebServerFactory factory) {
|
||||
factory.setUseForwardHeaders(
|
||||
getOrDeduceUseForwardHeaders(this.serverProperties, this.environment));
|
||||
PropertyMapper propertyMapper = PropertyMapper.get();
|
||||
propertyMapper.from(this.serverProperties::getMaxHttpHeaderSize).whenNonNull()
|
||||
.asInt(DataSize::toBytes)
|
||||
.to((maxHttpRequestHeaderSize) -> customizeMaxHttpHeaderSize(factory,
|
||||
maxHttpRequestHeaderSize));
|
||||
}
|
||||
|
||||
private boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties,
|
||||
@@ -62,4 +71,11 @@ public class NettyWebServerFactoryCustomizer
|
||||
return platform != null && platform.isUsingForwardHeaders();
|
||||
}
|
||||
|
||||
private void customizeMaxHttpHeaderSize(NettyReactiveWebServerFactory factory,
|
||||
Integer maxHttpHeaderSize) {
|
||||
factory.addServerCustomizers((NettyServerCustomizer) (httpServer) -> httpServer
|
||||
.httpRequestDecoder((httpRequestDecoderSpec) -> httpRequestDecoderSpec
|
||||
.maxHeaderSize(maxHttpHeaderSize)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Artsiom Yudovin
|
||||
* @author Chentao Qu
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatWebServerFactoryCustomizer implements
|
||||
@@ -84,7 +85,8 @@ public class TomcatWebServerFactoryCustomizer implements
|
||||
tomcatProperties.getMaxThreads()));
|
||||
propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive)
|
||||
.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
|
||||
propertyMapper.from(this::determineMaxHttpHeaderSize).when(this::isPositive)
|
||||
propertyMapper.from(this::determineMaxHttpHeaderSize).whenNonNull()
|
||||
.asInt(DataSize::toBytes)
|
||||
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
|
||||
maxHttpHeaderSize));
|
||||
propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull()
|
||||
@@ -114,10 +116,11 @@ public class TomcatWebServerFactoryCustomizer implements
|
||||
return value > 0;
|
||||
}
|
||||
|
||||
private int determineMaxHttpHeaderSize() {
|
||||
return (this.serverProperties.getMaxHttpHeaderSize() > 0)
|
||||
? this.serverProperties.getMaxHttpHeaderSize()
|
||||
: this.serverProperties.getTomcat().getMaxHttpHeaderSize();
|
||||
private DataSize determineMaxHttpHeaderSize() {
|
||||
return isPositive(this.serverProperties.getTomcat().getMaxHttpHeaderSize())
|
||||
? DataSize
|
||||
.ofBytes(this.serverProperties.getTomcat().getMaxHttpHeaderSize())
|
||||
: this.serverProperties.getMaxHttpHeaderSize();
|
||||
}
|
||||
|
||||
private void customizeAcceptCount(ConfigurableTomcatWebServerFactory factory,
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebSer
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Customization for Undertow-specific features common for both Servlet and Reactive
|
||||
@@ -83,7 +84,8 @@ public class UndertowWebServerFactoryCustomizer implements
|
||||
.to(factory::setAccessLogRotate);
|
||||
propertyMapper.from(this::getOrDeduceUseForwardHeaders)
|
||||
.to(factory::setUseForwardHeaders);
|
||||
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive)
|
||||
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull()
|
||||
.asInt(DataSize::toBytes)
|
||||
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
|
||||
maxHttpHeaderSize));
|
||||
propertyMapper.from(undertowProperties::getMaxHttpPostSize).when(this::isPositive)
|
||||
|
||||
@@ -29,6 +29,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.util.unit.DataSize;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -136,7 +137,8 @@ public class ServerPropertiesTests {
|
||||
@Test
|
||||
public void testCustomizeHeaderSize() {
|
||||
bind("server.max-http-header-size", "9999");
|
||||
assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(9999);
|
||||
assertThat(this.properties.getMaxHttpHeaderSize())
|
||||
.isEqualTo(DataSize.ofBytes(9999));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -21,6 +21,9 @@ import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConfiguration.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.NCSARequestLog;
|
||||
import org.eclipse.jetty.server.RequestLog;
|
||||
import org.junit.Before;
|
||||
@@ -140,6 +143,21 @@ public class JettyWebServerFactoryCustomizerTests {
|
||||
verify(factory).setUseForwardHeaders(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customizeMaxHttpHeaderSize() {
|
||||
bind("server.max-http-header-size=2048");
|
||||
JettyWebServer server = customizeAndGetServer();
|
||||
for (Connector connector : server.getServer().getConnectors()) {
|
||||
connector.getConnectionFactories().stream()
|
||||
.filter((factory) -> factory instanceof ConnectionFactory)
|
||||
.forEach((cf) -> {
|
||||
ConnectionFactory factory = (ConnectionFactory) cf;
|
||||
HttpConfiguration configuration = factory.getHttpConfiguration();
|
||||
assertThat(configuration.getRequestHeaderSize()).isEqualTo(2048);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void bind(String... inlinedProperties) {
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
|
||||
inlinedProperties);
|
||||
|
||||
Reference in New Issue
Block a user