Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class ServerProperties {
/**
* Maximum size, in bytes, of the HTTP message header.
*/
private int maxHttpHeaderSize = 0; // bytes
private int maxHttpHeaderSize = 8192;

/**
* Time that connectors wait for another HTTP request before closing the connection.
Expand Down Expand Up @@ -729,6 +729,11 @@ public static class Jetty {
*/
private Integer selectors;

/**
* Maximum size, in bytes, of the HTTP response header.
*/
private int maxHttpResponseHeaderSize;

public Accesslog getAccesslog() {
return this.accesslog;
}
Expand Down Expand Up @@ -757,6 +762,14 @@ public void setSelectors(Integer selectors) {
this.selectors = selectors;
}

public int getMaxHttpResponseHeaderSize() {
return this.maxHttpResponseHeaderSize;
}

public void setMaxHttpResponseHeaderSize(int maxHttpResponseHeaderSize) {
this.maxHttpResponseHeaderSize = maxHttpResponseHeaderSize;
}

/**
* Jetty access log properties.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
.to(factory::setAcceptors);
propertyMapper.from(jettyProperties::getSelectors).whenNonNull()
.to(factory::setSelectors);
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive)
.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,
maxHttpHeaderSize));
propertyMapper.from(properties::getMaxHttpHeaderSize).when(this::isPositive).to(
(maxHttpRequestHeaderSize) -> customizeMaxHttpRequestHeaderSize(factory,
maxHttpRequestHeaderSize));
propertyMapper.from(jettyProperties::getMaxHttpResponseHeaderSize)
.when(this::isPositive)
.to((maxHttpResponseHeaderSize) -> customizeMaxHttpResponseHeaderSize(
factory, maxHttpResponseHeaderSize));
propertyMapper.from(jettyProperties::getMaxHttpPostSize).when(this::isPositive)
.to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory,
maxHttpPostSize));
Expand Down Expand Up @@ -112,8 +116,8 @@ private void customizeConnectionTimeout(ConfigurableJettyWebServerFactory factor
});
}

private void customizeMaxHttpHeaderSize(ConfigurableJettyWebServerFactory factory,
int maxHttpHeaderSize) {
private void customizeMaxHttpRequestHeaderSize(
ConfigurableJettyWebServerFactory factory, int maxHttpRequestHeaderSize) {
factory.addServerCustomizers(new JettyServerCustomizer() {

@Override
Expand All @@ -132,8 +136,34 @@ public void customize(Server server) {

private void customize(HttpConfiguration.ConnectionFactory factory) {
HttpConfiguration configuration = factory.getHttpConfiguration();
configuration.setRequestHeaderSize(maxHttpHeaderSize);
configuration.setResponseHeaderSize(maxHttpHeaderSize);
configuration.setRequestHeaderSize(maxHttpRequestHeaderSize);
}

});
}

private void customizeMaxHttpResponseHeaderSize(
ConfigurableJettyWebServerFactory factory,
Integer maxHttpResponseHeaderSize) {
factory.addServerCustomizers(new JettyServerCustomizer() {

@Override
public void customize(Server server) {
for (org.eclipse.jetty.server.Connector connector : server
.getConnectors()) {
for (ConnectionFactory connectionFactory : connector
.getConnectionFactories()) {
if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) {
customize(
(HttpConfiguration.ConnectionFactory) connectionFactory);
}
}
}
}

private void customize(HttpConfiguration.ConnectionFactory factory) {
HttpConfiguration configuration = factory.getHttpConfiguration();
configuration.setResponseHeaderSize(maxHttpResponseHeaderSize);
}

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

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;
Expand Down Expand Up @@ -51,6 +53,11 @@ public int getOrder() {
public void customize(NettyReactiveWebServerFactory factory) {
factory.setUseForwardHeaders(
getOrDeduceUseForwardHeaders(this.serverProperties, this.environment));
PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(this.serverProperties::getMaxHttpHeaderSize)
.when(this::isPositive)
.to((maxHttpRequestHeaderSize) -> customizeMaxHttpHeaderSize(factory,
maxHttpRequestHeaderSize));
}

private boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties,
Expand All @@ -62,4 +69,15 @@ private boolean getOrDeduceUseForwardHeaders(ServerProperties serverProperties,
return platform != null && platform.isUsingForwardHeaders();
}

private void customizeMaxHttpHeaderSize(NettyReactiveWebServerFactory factory,
Integer maxHttpHeaderSize) {
factory.addServerCustomizers((NettyServerCustomizer) (httpServer) -> httpServer
.httpRequestDecoder((httpRequestDecoderSpec) -> httpRequestDecoderSpec
.maxHeaderSize(maxHttpHeaderSize)));
}

private boolean isPositive(Integer value) {
return value > 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ public void testCustomizeJettyAccessLog() {
assertThat(jetty.getAccesslog().isAppend()).isTrue();
}

@Test
public void customizeMaxHttpResponseHeaderSize() {
bind("server.jetty.max-http-response-header-size", "2048");
ServerProperties.Jetty jetty = this.properties.getJetty();
assertThat(jetty.getMaxHttpResponseHeaderSize()).isEqualTo(2048);
}

private void bind(String name, String value) {
bind(Collections.singletonMap(name, value));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
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;
Expand Down Expand Up @@ -140,6 +143,21 @@ public void setUseForwardHeaders() {
verify(factory).setUseForwardHeaders(true);
}

@Test
public void customizeMaxHttpResponseHeaderSize() {
bind("server.jetty.max-http-response-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.getResponseHeaderSize()).isEqualTo(2048);
});
}
}

private void bind(String... inlinedProperties) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
inlinedProperties);
Expand Down