From 93cc2635aedac1efc16dee016bfbe4a0c4c1cc31 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Tue, 19 Mar 2024 14:30:39 +0200 Subject: [PATCH] Make max parameters of multipart handling configurable Closes: #39546 --- .../ResteasyReactiveRuntimeRecorder.java | 3 ++- .../vertx/http/runtime/ServerLimitsConfig.java | 8 ++++++++ .../multipart/MultiPartParserDefinition.java | 17 ++++++++++++++--- .../server/handlers/FormBodyHandler.java | 1 + .../server/spi/DefaultRuntimeConfiguration.java | 8 +++++++- .../server/spi/RuntimeConfiguration.java | 2 ++ .../framework/ResteasyReactiveUnitTest.java | 4 +++- 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRuntimeRecorder.java b/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRuntimeRecorder.java index fc7feb6161b7e..4722dcceccaab 100644 --- a/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRuntimeRecorder.java +++ b/extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/ResteasyReactiveRuntimeRecorder.java @@ -37,7 +37,8 @@ public Supplier runtimeConfiguration(RuntimeValue + * If a client sends more than this number of parameters in a request, the connection is closed. + */ + @ConfigItem(defaultValue = "1000") + public int maxParameters; + /** * The maximum number of connections that are allowed at any one time. If this is set * it is recommended to set a short idle timeout. diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java index 1cea966a9e0b1..276b59a87c1fd 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java @@ -55,6 +55,7 @@ public class MultiPartParserDefinition implements FormParserFactory.ParserDefini private long fileSizeThreshold; private long maxAttributeSize = 2048; + private int maxParameters = 1000; private long maxEntitySize = -1; private List fileContentTypes; @@ -80,7 +81,7 @@ public FormDataParser create(final ResteasyReactiveRequestContext exchange, Set< return null; } final MultiPartUploadHandler parser = new MultiPartUploadHandler(exchange, boundary, maxIndividualFileSize, - fileSizeThreshold, defaultCharset, mimeType, maxAttributeSize, maxEntitySize, fileFormNames); + fileSizeThreshold, defaultCharset, mimeType, maxAttributeSize, maxEntitySize, maxParameters, fileFormNames); exchange.registerCompletionCallback(new CompletionCallback() { @Override public void onComplete(Throwable throwable) { @@ -156,6 +157,15 @@ public MultiPartParserDefinition setMaxEntitySize(long maxEntitySize) { return this; } + public int getMaxParameters() { + return maxParameters; + } + + public MultiPartParserDefinition setMaxParameters(int maxParameters) { + this.maxParameters = maxParameters; + return this; + } + public List getFileContentTypes() { return fileContentTypes; } @@ -174,6 +184,7 @@ private final class MultiPartUploadHandler implements FormDataParser, MultipartP private final long fileSizeThreshold; private final long maxAttributeSize; private final long maxEntitySize; + private final int maxParameters; private final Set fileFormNames; private String defaultEncoding; @@ -189,7 +200,7 @@ private final class MultiPartUploadHandler implements FormDataParser, MultipartP private MultiPartUploadHandler(final ResteasyReactiveRequestContext exchange, final String boundary, final long maxIndividualFileSize, final long fileSizeThreshold, final String defaultEncoding, - String contentType, long maxAttributeSize, long maxEntitySize, + String contentType, long maxAttributeSize, long maxEntitySize, int maxParameters, Set fileFormNames) { this.exchange = exchange; this.maxIndividualFileSize = maxIndividualFileSize; @@ -197,8 +208,8 @@ private MultiPartUploadHandler(final ResteasyReactiveRequestContext exchange, fi this.fileSizeThreshold = fileSizeThreshold; this.maxAttributeSize = maxAttributeSize; this.maxEntitySize = maxEntitySize; + this.maxParameters = maxParameters; this.fileFormNames = fileFormNames; - int maxParameters = 1000; this.data = new FormData(maxParameters); String charset = defaultEncoding; if (contentType != null) { diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java index 42c7ada9b433e..840ceaaaee51b 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java @@ -47,6 +47,7 @@ public void configure(RuntimeConfiguration configuration) { .setFileSizeThreshold(0) .setMaxAttributeSize(configuration.limits().maxFormAttributeSize()) .setMaxEntitySize(configuration.limits().maxBodySize().orElse(-1L)) + .setMaxParameters(configuration.limits().maxParameters()) .setDeleteUploadsOnEnd(configuration.body().deleteUploadedFilesOnEnd()) .setFileContentTypes(configuration.body().multiPart().fileContentTypes()) .setDefaultCharset(configuration.body().defaultCharset().name()) diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/DefaultRuntimeConfiguration.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/DefaultRuntimeConfiguration.java index 958c6e55b7f8f..8b60dfd0774dc 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/DefaultRuntimeConfiguration.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/DefaultRuntimeConfiguration.java @@ -11,7 +11,8 @@ public class DefaultRuntimeConfiguration implements RuntimeConfiguration { private final Limits limits; public DefaultRuntimeConfiguration(Duration readTimeout, boolean deleteUploadedFilesOnEnd, String uploadsDirectory, - List fileContentTypes, Charset defaultCharset, Optional maxBodySize, long maxFormAttributeSize) { + List fileContentTypes, Charset defaultCharset, Optional maxBodySize, long maxFormAttributeSize, + int maxParameters) { this.readTimeout = readTimeout; body = new Body() { Body.MultiPart multiPart = new Body.MultiPart() { @@ -51,6 +52,11 @@ public Optional maxBodySize() { public long maxFormAttributeSize() { return maxFormAttributeSize; } + + @Override + public int maxParameters() { + return maxParameters; + } }; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/RuntimeConfiguration.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/RuntimeConfiguration.java index 6ccfdcee9dd50..4674daf402237 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/RuntimeConfiguration.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/RuntimeConfiguration.java @@ -32,5 +32,7 @@ interface Limits { Optional maxBodySize(); long maxFormAttributeSize(); + + int maxParameters(); } } diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/framework/ResteasyReactiveUnitTest.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/framework/ResteasyReactiveUnitTest.java index ec50f18b9c567..ce5fa2789cc3f 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/framework/ResteasyReactiveUnitTest.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/framework/ResteasyReactiveUnitTest.java @@ -131,6 +131,8 @@ public boolean isBlockingAllowed() { private Charset defaultCharset = StandardCharsets.UTF_8;; private int maxFormAttributeSize = 2048; + private int maxParameters = 1000; + public static Vertx getVertx() { return vertx; } @@ -397,7 +399,7 @@ public Thread newThread(Runnable r) { DefaultRuntimeConfiguration runtimeConfiguration = new DefaultRuntimeConfiguration(Duration.ofMinutes(1), deleteUploadedFilesOnEnd, uploadPath != null ? uploadPath.toAbsolutePath().toString() : System.getProperty("java.io.tmpdir"), - fileContentTypes, defaultCharset, Optional.empty(), maxFormAttributeSize); + fileContentTypes, defaultCharset, Optional.empty(), maxFormAttributeSize, maxParameters); ResteasyReactiveDeploymentManager.RunnableApplication application = prepared.createApplication(runtimeConfiguration, new VertxRequestContextFactory(), executor); fieldInjectionSupport.runtimeInit(testClassLoader, application.getDeployment());