Skip to content

Enabled server.maxHttpHeaderSize and server.maxHttpPostSize configuration #5641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
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 @@ -30,13 +30,23 @@
import javax.servlet.SessionTrackingMode;
import javax.validation.constraints.NotNull;

import io.undertow.Undertow.Builder;
import io.undertow.UndertowOptions;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.valves.RemoteIpValve;
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;

import org.springframework.boot.autoconfigure.web.ServerProperties.Session.Cookie;
import org.springframework.boot.cloud.CloudPlatform;
Expand All @@ -50,11 +60,14 @@
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
Expand All @@ -73,6 +86,7 @@
* @author Marcos Barbero
* @author Eddú Meléndez
* @author Quinten De Swaef
* @author Venil Noronha
*/
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties
Expand Down Expand Up @@ -122,6 +136,16 @@ public class ServerProperties
*/
private String serverHeader;

/**
* Maximum size in bytes of the HTTP message header.
*/
private int maxHttpHeaderSize = 0; // bytes

/**
* Maximum size in bytes of the HTTP post content.
*/
private int maxHttpPostSize = 0; // bytes

private Session session = new Session();

@NestedConfigurationProperty
Expand Down Expand Up @@ -319,6 +343,22 @@ public void setServerHeader(String serverHeader) {
this.serverHeader = serverHeader;
}

public int getMaxHttpHeaderSize() {
return this.maxHttpHeaderSize;
}

public void setMaxHttpHeaderSize(int maxHttpHeaderSize) {
this.maxHttpHeaderSize = maxHttpHeaderSize;
}

public int getMaxHttpPostSize() {
return this.maxHttpPostSize;
}

public void setMaxHttpPostSize(int maxHttpPostSize) {
this.maxHttpPostSize = maxHttpPostSize;
}

protected final boolean getOrDeduceUseForwardHeaders() {
if (this.useForwardHeaders != null) {
return this.useForwardHeaders;
Expand Down Expand Up @@ -612,10 +652,23 @@ public void setMinSpareThreads(int minSpareThreads) {
this.minSpareThreads = minSpareThreads;
}

/**
* Get the max http header size.
* @return the max http header size.
* @deprecated in favor of {@code server.maxHttpHeaderSize}
*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "server.maxHttpHeaderSize")
public int getMaxHttpHeaderSize() {
return this.maxHttpHeaderSize;
}

/**
* Set the max http header size.
* @param maxHttpHeaderSize the max http header size.
* @deprecated in favor of {@code server.maxHttpHeaderSize}
*/
@Deprecated
public void setMaxHttpHeaderSize(int maxHttpHeaderSize) {
this.maxHttpHeaderSize = maxHttpHeaderSize;
}
Expand Down Expand Up @@ -701,8 +754,14 @@ void customizeTomcat(ServerProperties serverProperties,
if (this.minSpareThreads > 0) {
customizeMinThreads(factory);
}
if (this.maxHttpHeaderSize > 0) {
customizeMaxHttpHeaderSize(factory);
if (serverProperties.getMaxHttpHeaderSize() > 0) {
customizeMaxHttpHeaderSize(factory, serverProperties.getMaxHttpHeaderSize());
}
else if (this.maxHttpHeaderSize > 0) {
customizeMaxHttpHeaderSize(factory, this.maxHttpHeaderSize);
}
if (serverProperties.getMaxHttpPostSize() > 0) {
customizeMaxHttpPostSize(factory, serverProperties.getMaxHttpPostSize());
}
if (this.accesslog.enabled) {
customizeAccessLog(factory);
Expand Down Expand Up @@ -782,21 +841,31 @@ public void customize(Connector connector) {

@SuppressWarnings("rawtypes")
private void customizeMaxHttpHeaderSize(
TomcatEmbeddedServletContainerFactory factory) {
TomcatEmbeddedServletContainerFactory factory, final int maxHttpHeaderSize) {
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

@Override
public void customize(Connector connector) {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler;
protocol.setMaxHttpHeaderSize(Tomcat.this.maxHttpHeaderSize);
protocol.setMaxHttpHeaderSize(maxHttpHeaderSize);
}
}

});
}

private void customizeMaxHttpPostSize(
TomcatEmbeddedServletContainerFactory factory, final int maxHttpPostSize) {
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
connector.setMaxPostSize(maxHttpPostSize);
}
});
}

private void customizeAccessLog(TomcatEmbeddedServletContainerFactory factory) {
AccessLogValve valve = new AccessLogValve();
valve.setPattern(this.accesslog.getPattern());
Expand Down Expand Up @@ -882,6 +951,62 @@ private static class Jetty {
void customizeJetty(ServerProperties serverProperties,
JettyEmbeddedServletContainerFactory factory) {
factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
if (serverProperties.getMaxHttpHeaderSize() > 0) {
customizeMaxHttpHeaderSize(factory, serverProperties.getMaxHttpHeaderSize());
}
if (serverProperties.getMaxHttpPostSize() > 0) {
customizeMaxHttpPostSize(factory, serverProperties.getMaxHttpPostSize());
}
}

private void customizeMaxHttpHeaderSize(
JettyEmbeddedServletContainerFactory factory, final int maxHttpHeaderSize) {
factory.addServerCustomizers(new JettyServerCustomizer() {
@Override
public void customize(Server server) {
org.eclipse.jetty.server.Connector[] connectors = server.getConnectors();
for (org.eclipse.jetty.server.Connector connector : connectors) {
for (ConnectionFactory connectionFactory : connector.getConnectionFactories()) {
if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) {
HttpConfiguration httpConfig =
((HttpConfiguration.ConnectionFactory) connectionFactory)
.getHttpConfiguration();
httpConfig.setRequestHeaderSize(maxHttpHeaderSize);
httpConfig.setResponseHeaderSize(maxHttpHeaderSize);
}
}
}
}
});
}

private void customizeMaxHttpPostSize(
JettyEmbeddedServletContainerFactory factory, final int maxHttpPostSize) {
factory.addServerCustomizers(new JettyServerCustomizer() {

@Override
public void customize(Server server) {
setHandlerMaxHttpPostSize(maxHttpPostSize, server.getHandlers());
}

private void setHandlerMaxHttpPostSize(int maxHttpPostSize,
Handler... handlers) {
for (Handler handler : handlers) {
if (handler instanceof ContextHandler) {
((ContextHandler) handler).setMaxFormContentSize(maxHttpPostSize);
}
else if (handler instanceof HandlerWrapper) {
setHandlerMaxHttpPostSize(maxHttpPostSize,
((HandlerWrapper) handler).getHandler());
}
else if (handler instanceof HandlerCollection) {
setHandlerMaxHttpPostSize(maxHttpPostSize,
((HandlerCollection) handler).getHandlers());
}
}
}

});
}

}
Expand Down Expand Up @@ -970,6 +1095,32 @@ void customizeUndertow(ServerProperties serverProperties,
factory.setAccessLogPattern(this.accesslog.pattern);
factory.setAccessLogEnabled(this.accesslog.enabled);
factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
if (serverProperties.getMaxHttpHeaderSize() > 0) {
customizeMaxHttpHeaderSize(factory, serverProperties.getMaxHttpHeaderSize());
}
if (serverProperties.getMaxHttpPostSize() > 0) {
customizeMaxHttpPostSize(factory, serverProperties.getMaxHttpPostSize());
}
}

private void customizeMaxHttpHeaderSize(
UndertowEmbeddedServletContainerFactory factory, final int maxHttpHeaderSize) {
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
@Override
public void customize(Builder builder) {
builder.setServerOption(UndertowOptions.MAX_HEADER_SIZE, maxHttpHeaderSize);
}
});
}

private void customizeMaxHttpPostSize(
UndertowEmbeddedServletContainerFactory factory, final int maxHttpPostSize) {
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
@Override
public void customize(Builder builder) {
builder.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, (long) maxHttpPostSize);
}
});
}

public static class Accesslog {
Expand Down