Make max header size config consistent across web servers

Closes gh-29382
pull/32585/head
Andy Wilkinson 2 years ago
parent 4f86f685c5
commit e6568596b9

@ -98,9 +98,9 @@ public class ServerProperties {
private String serverHeader; private String serverHeader;
/** /**
* Maximum size of the HTTP message header. * Maximum size of the HTTP request header.
*/ */
private DataSize maxHttpHeaderSize = DataSize.ofKilobytes(8); private DataSize maxHttpRequestHeaderSize = DataSize.ofKilobytes(8);
/** /**
* Type of shutdown that the server will support. * Type of shutdown that the server will support.
@ -152,12 +152,23 @@ public class ServerProperties {
this.serverHeader = serverHeader; this.serverHeader = serverHeader;
} }
@Deprecated(since = "3.0.0", forRemoval = true)
@DeprecatedConfigurationProperty
public DataSize getMaxHttpHeaderSize() { public DataSize getMaxHttpHeaderSize() {
return this.maxHttpHeaderSize; return getMaxHttpRequestHeaderSize();
} }
@Deprecated(since = "3.0.0", forRemoval = true)
public void setMaxHttpHeaderSize(DataSize maxHttpHeaderSize) { public void setMaxHttpHeaderSize(DataSize maxHttpHeaderSize) {
this.maxHttpHeaderSize = maxHttpHeaderSize; setMaxHttpRequestHeaderSize(maxHttpHeaderSize);
}
public DataSize getMaxHttpRequestHeaderSize() {
return this.maxHttpRequestHeaderSize;
}
public void setMaxHttpRequestHeaderSize(DataSize maxHttpRequestHeaderSize) {
this.maxHttpRequestHeaderSize = maxHttpRequestHeaderSize;
} }
public Shutdown getShutdown() { public Shutdown getShutdown() {

@ -82,9 +82,9 @@ public class JettyWebServerFactoryCustomizer
PropertyMapper propertyMapper = PropertyMapper.get(); PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(threadProperties::getAcceptors).whenNonNull().to(factory::setAcceptors); propertyMapper.from(threadProperties::getAcceptors).whenNonNull().to(factory::setAcceptors);
propertyMapper.from(threadProperties::getSelectors).whenNonNull().to(factory::setSelectors); propertyMapper.from(threadProperties::getSelectors).whenNonNull().to(factory::setSelectors);
propertyMapper.from(properties::getMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes) propertyMapper.from(properties::getMaxHttpRequestHeaderSize).whenNonNull().asInt(DataSize::toBytes)
.when(this::isPositive).to((maxHttpHeaderSize) -> factory .when(this::isPositive).to((maxHttpRequestHeaderSize) -> factory
.addServerCustomizers(new MaxHttpHeaderSizeCustomizer(maxHttpHeaderSize))); .addServerCustomizers(new MaxHttpRequestHeaderSizeCustomizer(maxHttpRequestHeaderSize)));
propertyMapper.from(jettyProperties::getMaxHttpFormPostSize).asInt(DataSize::toBytes).when(this::isPositive) propertyMapper.from(jettyProperties::getMaxHttpFormPostSize).asInt(DataSize::toBytes).when(this::isPositive)
.to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize)); .to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize));
propertyMapper.from(jettyProperties::getConnectionIdleTimeout).whenNonNull() propertyMapper.from(jettyProperties::getConnectionIdleTimeout).whenNonNull()
@ -192,12 +192,12 @@ public class JettyWebServerFactoryCustomizer
return CustomRequestLog.NCSA_FORMAT; return CustomRequestLog.NCSA_FORMAT;
} }
private static class MaxHttpHeaderSizeCustomizer implements JettyServerCustomizer { private static class MaxHttpRequestHeaderSizeCustomizer implements JettyServerCustomizer {
private final int maxHttpHeaderSize; private final int maxRequestHeaderSize;
MaxHttpHeaderSizeCustomizer(int maxHttpHeaderSize) { MaxHttpRequestHeaderSizeCustomizer(int maxRequestHeaderSize) {
this.maxHttpHeaderSize = maxHttpHeaderSize; this.maxRequestHeaderSize = maxRequestHeaderSize;
} }
@Override @Override
@ -212,7 +212,7 @@ public class JettyWebServerFactoryCustomizer
private void customize(ConnectionFactory factory) { private void customize(ConnectionFactory factory) {
if (factory instanceof HttpConfiguration.ConnectionFactory) { if (factory instanceof HttpConfiguration.ConnectionFactory) {
((HttpConfiguration.ConnectionFactory) factory).getHttpConfiguration() ((HttpConfiguration.ConnectionFactory) factory).getHttpConfiguration()
.setRequestHeaderSize(this.maxHttpHeaderSize); .setRequestHeaderSize(this.maxRequestHeaderSize);
} }
} }

@ -83,7 +83,7 @@ public class NettyWebServerFactoryCustomizer
private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) { private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) {
factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> { factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> {
propertyMapper.from(this.serverProperties.getMaxHttpHeaderSize()).whenNonNull() propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()).whenNonNull()
.to((maxHttpRequestHeader) -> httpRequestDecoderSpec .to((maxHttpRequestHeader) -> httpRequestDecoderSpec
.maxHeaderSize((int) maxHttpRequestHeader.toBytes())); .maxHeaderSize((int) maxHttpRequestHeader.toBytes()));
ServerProperties.Netty nettyProperties = this.serverProperties.getNetty(); ServerProperties.Netty nettyProperties = this.serverProperties.getNetty();

@ -92,9 +92,9 @@ public class TomcatWebServerFactoryCustomizer
.to((maxThreads) -> customizeMaxThreads(factory, threadProperties.getMax())); .to((maxThreads) -> customizeMaxThreads(factory, threadProperties.getMax()));
propertyMapper.from(threadProperties::getMinSpare).when(this::isPositive) propertyMapper.from(threadProperties::getMinSpare).when(this::isPositive)
.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads)); .to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
propertyMapper.from(this.serverProperties.getMaxHttpHeaderSize()).whenNonNull().asInt(DataSize::toBytes) propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()).whenNonNull().asInt(DataSize::toBytes)
.when(this::isPositive) .when(this::isPositive)
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize)); .to((maxHttpRequestHeaderSize) -> customizeMaxHttpRequestHeaderSize(factory, maxHttpRequestHeaderSize));
propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull().asInt(DataSize::toBytes) propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull().asInt(DataSize::toBytes)
.to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize)); .to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize));
propertyMapper.from(tomcatProperties::getMaxHttpFormPostSize).asInt(DataSize::toBytes) propertyMapper.from(tomcatProperties::getMaxHttpFormPostSize).asInt(DataSize::toBytes)
@ -275,12 +275,13 @@ public class TomcatWebServerFactoryCustomizer
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private void customizeMaxHttpHeaderSize(ConfigurableTomcatWebServerFactory factory, int maxHttpHeaderSize) { private void customizeMaxHttpRequestHeaderSize(ConfigurableTomcatWebServerFactory factory,
int maxHttpRequestHeaderSize) {
factory.addConnectorCustomizers((connector) -> { factory.addConnectorCustomizers((connector) -> {
ProtocolHandler handler = connector.getProtocolHandler(); ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) { if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler; AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler;
protocol.setMaxHttpHeaderSize(maxHttpHeaderSize); protocol.setMaxHttpRequestHeaderSize(maxHttpRequestHeaderSize);
} }
}); });
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2020 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -78,7 +78,7 @@ public class UndertowWebServerFactoryCustomizer
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
ServerOptions options = new ServerOptions(factory); ServerOptions options = new ServerOptions(factory);
ServerProperties properties = this.serverProperties; ServerProperties properties = this.serverProperties;
map.from(properties::getMaxHttpHeaderSize).asInt(DataSize::toBytes).when(this::isPositive) map.from(properties::getMaxHttpRequestHeaderSize).asInt(DataSize::toBytes).when(this::isPositive)
.to(options.option(UndertowOptions.MAX_HEADER_SIZE)); .to(options.option(UndertowOptions.MAX_HEADER_SIZE));
mapUndertowProperties(factory, options); mapUndertowProperties(factory, options);
mapAccessLogProperties(factory); mapAccessLogProperties(factory);

@ -204,15 +204,33 @@ class ServerPropertiesTests {
} }
@Test @Test
@SuppressWarnings("removal")
@Deprecated(since = "3.0.0", forRemoval = true)
void testCustomizeHeaderSize() { void testCustomizeHeaderSize() {
bind("server.max-http-header-size", "1MB"); bind("server.max-http-header-size", "1MB");
assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofMegabytes(1)); assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofMegabytes(1));
assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofMegabytes(1));
} }
@Test @Test
@SuppressWarnings("removal")
@Deprecated(since = "3.0.0", forRemoval = true)
void testCustomizeHeaderSizeUseBytesByDefault() { void testCustomizeHeaderSizeUseBytesByDefault() {
bind("server.max-http-header-size", "1024"); bind("server.max-http-header-size", "1024");
assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(1)); assertThat(this.properties.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(1));
assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(1));
}
@Test
void testCustomizeMaxHttpRequestHeaderSize() {
bind("server.max-http-request-header-size", "1MB");
assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofMegabytes(1));
}
@Test
void testCustomizeMaxHttpRequestHeaderSizeUseBytesByDefault() {
bind("server.max-http-request-header-size", "1024");
assertThat(this.properties.getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(1));
} }
@Test @Test

@ -179,7 +179,7 @@ class TomcatWebServerFactoryCustomizerTests {
bind("server.max-http-header-size=1KB"); bind("server.max-http-header-size=1KB");
customizeAndRunServer((server) -> assertThat( customizeAndRunServer((server) -> assertThat(
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler()) ((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(1).toBytes())); .getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(1).toBytes()));
} }
@Test @Test
@ -189,7 +189,7 @@ class TomcatWebServerFactoryCustomizerTests {
AbstractHttp11Protocol<?> protocolHandler = (AbstractHttp11Protocol<?>) server.getTomcat().getConnector() AbstractHttp11Protocol<?> protocolHandler = (AbstractHttp11Protocol<?>) server.getTomcat().getConnector()
.getProtocolHandler(); .getProtocolHandler();
long expectedSize = DataSize.ofKilobytes(1).toBytes(); long expectedSize = DataSize.ofKilobytes(1).toBytes();
assertThat(protocolHandler.getMaxHttpHeaderSize()).isEqualTo(expectedSize); assertThat(protocolHandler.getMaxHttpRequestHeaderSize()).isEqualTo(expectedSize);
assertThat(((Http2Protocol) protocolHandler.getUpgradeProtocol("h2c")).getMaxHeaderSize()) assertThat(((Http2Protocol) protocolHandler.getUpgradeProtocol("h2c")).getMaxHeaderSize())
.isEqualTo(expectedSize); .isEqualTo(expectedSize);
}); });
@ -200,7 +200,7 @@ class TomcatWebServerFactoryCustomizerTests {
bind("server.max-http-header-size=-1"); bind("server.max-http-header-size=-1");
customizeAndRunServer((server) -> assertThat( customizeAndRunServer((server) -> assertThat(
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler()) ((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(8).toBytes())); .getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(8).toBytes()));
} }
@Test @Test
@ -208,7 +208,7 @@ class TomcatWebServerFactoryCustomizerTests {
bind("server.max-http-header-size=0"); bind("server.max-http-header-size=0");
customizeAndRunServer((server) -> assertThat( customizeAndRunServer((server) -> assertThat(
((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler()) ((AbstractHttp11Protocol<?>) server.getTomcat().getConnector().getProtocolHandler())
.getMaxHttpHeaderSize()).isEqualTo(DataSize.ofKilobytes(8).toBytes())); .getMaxHttpRequestHeaderSize()).isEqualTo(DataSize.ofKilobytes(8).toBytes()));
} }
@Test @Test

Loading…
Cancel
Save