Add support for 'server.jetty.max-form-key' property

Add a new 'server.jetty.max-form-key' property that can be used to
configure Jetty's Handler.setMaxFormKeys(...).

See gh-42448
This commit is contained in:
qingbozhang
2024-09-25 23:04:55 +08:00
committed by Phillip Webb
parent 90f375ea3e
commit 6e885c423f
4 changed files with 54 additions and 9 deletions

View File

@@ -1148,6 +1148,11 @@ public class ServerProperties {
*/
private DataSize maxHttpFormPostSize = DataSize.ofBytes(200000);
/**
* Maximum number of form keys.
*/
private int maxFormKeys = 1000;
/**
* Time that the connection can be idle before it is closed.
*/
@@ -1180,6 +1185,14 @@ public class ServerProperties {
this.maxHttpFormPostSize = maxHttpFormPostSize;
}
public int getMaxFormKeys() {
return this.maxFormKeys;
}
public void setMaxFormKeys(int maxFormKeys) {
this.maxFormKeys = maxFormKeys;
}
public Duration getConnectionIdleTimeout() {
return this.connectionIdleTimeout;
}

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.web.embedded;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.server.AbstractConnector;
@@ -93,7 +94,11 @@ public class JettyWebServerFactoryCustomizer
map.from(properties::getMaxHttpFormPostSize)
.asInt(DataSize::toBytes)
.when(this::isPositive)
.to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize));
.to((maxHttpFormPostSize) -> customizeServletContextHandler(factory, contextHandler -> contextHandler.setMaxFormContentSize(maxHttpFormPostSize)));
map.from(properties::getMaxFormKeys)
.when(this::isPositive)
.to((maxFormKeys) -> customizeServletContextHandler(factory, contextHandler -> contextHandler.setMaxFormKeys(maxFormKeys)));
map.from(properties::getConnectionIdleTimeout).to((idleTimeout) -> customizeIdleTimeout(factory, idleTimeout));
map.from(properties::getAccesslog)
.when(ServerProperties.Jetty.Accesslog::isEnabled)
@@ -122,29 +127,29 @@ public class JettyWebServerFactoryCustomizer
});
}
private void customizeMaxHttpFormPostSize(ConfigurableJettyWebServerFactory factory, int maxHttpFormPostSize) {
private void customizeServletContextHandler(ConfigurableJettyWebServerFactory factory, Consumer<ServletContextHandler> customFunc) {
factory.addServerCustomizers(new JettyServerCustomizer() {
@Override
public void customize(Server server) {
setHandlerMaxHttpFormPostSize(server.getHandlers());
acceptCustomizeServletContextHandler(server.getHandlers());
}
private void setHandlerMaxHttpFormPostSize(List<Handler> handlers) {
private void acceptCustomizeServletContextHandler(List<Handler> handlers) {
for (Handler handler : handlers) {
setHandlerMaxHttpFormPostSize(handler);
acceptCustomizeServletContextHandler(handler);
}
}
private void setHandlerMaxHttpFormPostSize(Handler handler) {
private void acceptCustomizeServletContextHandler(Handler handler) {
if (handler instanceof ServletContextHandler contextHandler) {
contextHandler.setMaxFormContentSize(maxHttpFormPostSize);
customFunc.accept(contextHandler);
}
else if (handler instanceof Handler.Wrapper wrapper) {
setHandlerMaxHttpFormPostSize(wrapper.getHandler());
acceptCustomizeServletContextHandler(wrapper.getHandler());
}
else if (handler instanceof Handler.Collection collection) {
setHandlerMaxHttpFormPostSize(collection.getHandlers());
acceptCustomizeServletContextHandler(collection.getHandlers());
}
}

View File

@@ -465,6 +465,15 @@ class ServerPropertiesTests {
.isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormContentSize());
}
@Test
void jettyMaxFormKeysMatchesDefault() {
JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0);
JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer();
Server server = jetty.getServer();
assertThat(this.properties.getJetty().getMaxFormKeys())
.isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormKeys());
}
@Test
void undertowMaxHttpPostSizeMatchesDefault() {
assertThat(this.properties.getUndertow().getMaxHttpPostSize().toBytes())

View File

@@ -26,6 +26,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.function.Function;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.CustomRequestLog;
@@ -324,6 +325,23 @@ class JettyWebServerFactoryCustomizerTests {
assertThat(timeouts).containsOnly(60000L);
}
@Test
void customMaxFormKeys() {
bind("server.jetty.max-form-keys=2048");
JettyWebServer server = customizeAndGetServer();
List<Integer> maxFormKeys = getMaxFormKeys(server);
assertThat(maxFormKeys).containsOnly(2048);
}
private List<Integer> getMaxFormKeys(JettyWebServer server) {
server.start();
server.stop();
return server.getServer().getHandlers().stream()
.filter(handler -> handler instanceof ServletContextHandler)
.map(handler -> ((ServletContextHandler) handler).getMaxFormKeys())
.toList();
}
private List<Long> connectorsIdleTimeouts(JettyWebServer server) {
// Start (and directly stop) server to have connectors available
server.start();