Skip to content

Commit

Permalink
Make max parameters of multipart handling configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand authored and ketola committed Mar 23, 2024
1 parent 9e95889 commit 6d97685
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public Supplier<RuntimeConfiguration> runtimeConfiguration(RuntimeValue<Deployme
httpConf.body.deleteUploadedFilesOnEnd, httpConf.body.uploadsDirectory,
httpConf.body.multipart.fileContentTypes.orElse(null),
runtimeConf.multipart().inputPart().defaultCharset(), maxBodySize,
httpConf.limits.maxFormAttributeSize.asLongValue());
httpConf.limits.maxFormAttributeSize.asLongValue(),
httpConf.limits.maxParameters);

deployment.getValue().setRuntimeConfiguration(runtimeConfiguration);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ public class ServerLimitsConfig {
@ConfigItem(defaultValue = "2048")
public MemorySize maxFormAttributeSize;

/**
* The maximum number of HTTP request parameters permitted for incoming requests.
* <p>
* 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> fileContentTypes;

Expand All @@ -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) {
Expand Down Expand Up @@ -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<String> getFileContentTypes() {
return fileContentTypes;
}
Expand All @@ -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<String> fileFormNames;
private String defaultEncoding;

Expand All @@ -189,16 +200,16 @@ 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<String> fileFormNames) {
this.exchange = exchange;
this.maxIndividualFileSize = maxIndividualFileSize;
this.defaultEncoding = defaultEncoding;
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public class DefaultRuntimeConfiguration implements RuntimeConfiguration {
private final Limits limits;

public DefaultRuntimeConfiguration(Duration readTimeout, boolean deleteUploadedFilesOnEnd, String uploadsDirectory,
List<String> fileContentTypes, Charset defaultCharset, Optional<Long> maxBodySize, long maxFormAttributeSize) {
List<String> fileContentTypes, Charset defaultCharset, Optional<Long> maxBodySize, long maxFormAttributeSize,
int maxParameters) {
this.readTimeout = readTimeout;
body = new Body() {
Body.MultiPart multiPart = new Body.MultiPart() {
Expand Down Expand Up @@ -51,6 +52,11 @@ public Optional<Long> maxBodySize() {
public long maxFormAttributeSize() {
return maxFormAttributeSize;
}

@Override
public int maxParameters() {
return maxParameters;
}
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ interface Limits {
Optional<Long> maxBodySize();

long maxFormAttributeSize();

int maxParameters();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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());
Expand Down

0 comments on commit 6d97685

Please sign in to comment.