Skip to content
Open
Show file tree
Hide file tree
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 @@ -87,6 +87,11 @@ static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, HttpSer
obj.setMaxFormBufferedBytes(((Number)member.getValue()).intValue());
}
break;
case "maxQueryParams":
if (member.getValue() instanceof Number) {
obj.setMaxQueryParams(((Number)member.getValue()).intValue());
}
break;
case "initialSettings":
if (member.getValue() instanceof JsonObject) {
obj.setInitialSettings(new io.vertx.core.http.Http2Settings((io.vertx.core.json.JsonObject)member.getValue()));
Expand Down Expand Up @@ -214,6 +219,7 @@ static void toJson(HttpServerOptions obj, java.util.Map<String, Object> json) {
json.put("maxFormAttributeSize", obj.getMaxFormAttributeSize());
json.put("maxFormFields", obj.getMaxFormFields());
json.put("maxFormBufferedBytes", obj.getMaxFormBufferedBytes());
json.put("maxQueryParams", obj.getMaxQueryParams());
if (obj.getInitialSettings() != null) {
json.put("initialSettings", obj.getInitialSettings().toJson());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ private static TcpServerConfig defaultTcpServerConfig() {
private int maxFormAttributeSize;
private int maxFormFields;
private int maxFormBufferedBytes;
private int maxQueryParams;
private boolean handle100ContinueAutomatically;
private ServerSSLOptions sslOptions;
private boolean strictThreadMode;
Expand Down Expand Up @@ -91,6 +92,7 @@ public HttpServerConfig(HttpServerOptions options) {
this.maxFormAttributeSize = options.getMaxFormAttributeSize();
this.maxFormFields = options.getMaxFormFields();
this.maxFormBufferedBytes = options.getMaxFormBufferedBytes();
this.maxQueryParams = options.getMaxQueryParams();
this.handle100ContinueAutomatically = options.isHandle100ContinueAutomatically();
this.sslOptions = options.getSslOptions() != null ? new ServerSSLOptions(options.getSslOptions()) : null;
this.strictThreadMode = options.getStrictThreadMode();
Expand Down Expand Up @@ -369,6 +371,13 @@ public int getMaxFormFields() {
return maxFormFields;
}

/**
* @return Returns the maximum number of query params
*/
public int getMaxQueryParams() {
return maxQueryParams;
}

/**
* Set the maximum number of fields of a form. Set to {@code -1} to allow unlimited number of attributes
*
Expand Down
26 changes: 26 additions & 0 deletions vertx-core/src/main/java/io/vertx/core/http/HttpServerOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public class HttpServerOptions extends NetServerOptions {
*/
public static final int DEFAULT_MAX_FORM_BUFFERED_SIZE = 1024;

/**
* Default max number of query params = 1024
*/
public static final int DEFAULT_MAX_QUERY_PARAMS = 1024;

/**
* Default value of whether 100-Continue should be handled automatically = {@code false}
*/
Expand Down Expand Up @@ -209,6 +214,7 @@ public class HttpServerOptions extends NetServerOptions {
private int maxFormAttributeSize;
private int maxFormFields;
private int maxFormBufferedBytes;
private int maxQueryParams;
private Http1ServerConfig http1Config;
private Http2ServerConfig http2Config;
private WebSocketServerConfig webSocketConfig;
Expand Down Expand Up @@ -239,6 +245,7 @@ public HttpServerOptions(HttpServerOptions other) {
this.maxFormAttributeSize = other.getMaxFormAttributeSize();
this.maxFormFields = other.getMaxFormFields();
this.maxFormBufferedBytes = other.getMaxFormBufferedBytes();
this.maxQueryParams = other.getMaxQueryParams();
this.compressionLevel = other.getCompressionLevel();
this.compression = other.compression != null ? new HttpCompressionConfig(other.compression) : new HttpCompressionConfig();
this.handle100ContinueAutomatically = other.handle100ContinueAutomatically;
Expand Down Expand Up @@ -278,6 +285,7 @@ private void init() {
maxFormAttributeSize = DEFAULT_MAX_FORM_ATTRIBUTE_SIZE;
maxFormFields = DEFAULT_MAX_FORM_FIELDS;
maxFormBufferedBytes = DEFAULT_MAX_FORM_BUFFERED_SIZE;
maxQueryParams = DEFAULT_MAX_QUERY_PARAMS;
strictThreadMode = DEFAULT_STRICT_THREAD_MODE_STRICT;
compression = new HttpCompressionConfig();
handle100ContinueAutomatically = DEFAULT_HANDLE_100_CONTINE_AUTOMATICALLY;
Expand Down Expand Up @@ -845,6 +853,24 @@ public HttpServerOptions setMaxFormBufferedBytes(int maxFormBufferedBytes) {
return this;
}

/**
* @return Returns the maximum number of query params
*/
public int getMaxQueryParams() {
return maxQueryParams;
}

/**
* Set the maximum number of query params
*
* @param maxQueryParams the new maximum
* @return a reference to this, so the API can be used fluently
*/
public HttpServerOptions setMaxQueryParams(int maxQueryParams) {
this.maxQueryParams = maxQueryParams;
return this;
}

/**
* @return the initial HTTP/2 connection settings
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class HttpServerRequestImpl extends HttpServerRequestInternal {
private final int maxFormAttributeSize;
private final int maxFormFields;
private final int maxFormBufferedBytes;
private final int maxQueryParams;
private final Handler<HttpServerRequest> handler;

// Accessed on context thread
Expand Down Expand Up @@ -79,6 +80,7 @@ public HttpServerRequestImpl(Handler<HttpServerRequest> handler,
int maxFormAttributeSize,
int maxFormFields,
int maxFormBufferedBytes,
int maxQueryParams,
String serverOrigin) {
this.handler = handler;
this.context = context;
Expand All @@ -89,6 +91,7 @@ public HttpServerRequestImpl(Handler<HttpServerRequest> handler,
this.handle100ContinueAutomatically = handle100ContinueAutomatically;
this.maxFormAttributeSize = maxFormAttributeSize;
this.maxFormFields = maxFormFields;
this.maxQueryParams = maxQueryParams;
this.maxFormBufferedBytes = maxFormBufferedBytes;
}

Expand Down Expand Up @@ -397,7 +400,7 @@ public String getParamsCharset() {
public MultiMap params(boolean semicolonIsNormalChar) {
synchronized (connection) {
if (params == null || semicolonIsNormalChar != semicolonIsNormalCharInParams) {
params = HttpUtils.params(uri(), paramsCharset, semicolonIsNormalChar);
params = HttpUtils.params(uri(), paramsCharset, maxQueryParams, semicolonIsNormalChar);
semicolonIsNormalCharInParams = semicolonIsNormalChar;
}
return params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,11 @@ public static String absoluteURI(String serverOrigin, HttpServerRequest req) {
}

public static MultiMap params(String uri, Charset charset, boolean semicolonIsNormalChar) {
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri, charset, true, 1024, semicolonIsNormalChar);
return params(uri, charset, 1024, semicolonIsNormalChar);
}

public static MultiMap params(String uri, Charset charset, int maxParams, boolean semicolonIsNormalChar) {
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri, charset, true, maxParams, semicolonIsNormalChar);
Map<String, List<String>> prms = queryStringDecoder.parameters();
MultiMap params = MultiMap.caseInsensitiveMultiMap();
if (!prms.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class Http1ServerConnection extends Http1Connection implements HttpServer
private final boolean eagerCreateRequestQueue;
private final int maxFormAttributeSize;
private final int maxFormFields;
private final int maxQueryParams;
private final int maxFormBufferedBytes;
private final Http1ServerConfig serverConfig;
private final boolean registerWebSocketWriteHandlers;
Expand All @@ -104,6 +105,7 @@ public Http1ServerConnection(ThreadingModel threadingModel,
SslContextManager sslContextManager,
int maxFormAttributeSize,
int maxFormFields,
int maxQueryParams,
int maxFormBufferedBytes,
Http1ServerConfig serverConfig,
boolean registerWebSocketWriteHandlers,
Expand All @@ -119,6 +121,7 @@ public Http1ServerConnection(ThreadingModel threadingModel,
this.streamContextSupplier = streamContextSupplier;
this.maxFormAttributeSize = maxFormAttributeSize;
this.maxFormFields = maxFormFields;
this.maxQueryParams = maxQueryParams;
this.maxFormBufferedBytes = maxFormBufferedBytes;
this.serverConfig = serverConfig;
this.registerWebSocketWriteHandlers = registerWebSocketWriteHandlers;
Expand All @@ -142,6 +145,10 @@ int maxFormFields() {
return maxFormFields;
}

int maxQueryParams() {
return maxQueryParams;
}

int maxFormBufferedBytes() {
return maxFormBufferedBytes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ public String getParamsCharset() {
@Override
public MultiMap params(boolean semicolonIsNormalChar) {
if (params == null || semicolonIsNormalChar != semicolonIsNormalCharInParams) {
params = HttpUtils.params(uri(), paramsCharset, semicolonIsNormalChar);
params = HttpUtils.params(uri(), paramsCharset, this.conn.maxQueryParams(), semicolonIsNormalChar);
semicolonIsNormalCharInParams = semicolonIsNormalChar;
}
return params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ private static class ConnectionHandler implements Handler<QuicConnection> {
private final boolean handle100ContinueAutomatically;
private final int maxFormAttributeSize;
private final int maxFormFields;
private final int maxQueryParams;
private final int maxFormBufferedSize;
private final Http3Settings localSettings;

Expand All @@ -142,6 +143,7 @@ public ConnectionHandler(QuicServer transport,
boolean handle100ContinueAutomatically,
int maxFormAttributeSize,
int maxFormFields,
int maxQueryParams,
int maxFormBufferedSize,
Http3Settings localSettings) {
this.transport = transport;
Expand All @@ -151,6 +153,7 @@ public ConnectionHandler(QuicServer transport,
this.handle100ContinueAutomatically = handle100ContinueAutomatically;
this.maxFormAttributeSize = maxFormAttributeSize;
this.maxFormFields = maxFormFields;
this.maxQueryParams = maxQueryParams;
this.maxFormBufferedSize = maxFormBufferedSize;
this.localSettings = localSettings;
}
Expand All @@ -170,7 +173,7 @@ public void handle(QuicConnection connection) {
http3Connection.streamHandler(stream -> {
HttpServerRequestImpl request = new HttpServerRequestImpl(requestHandler, stream, stream.context(),
handle100ContinueAutomatically, maxFormAttributeSize,
maxFormFields, maxFormBufferedSize, serverOrigin);
maxFormFields, maxFormBufferedSize, maxQueryParams, serverOrigin);
request.init();
});

Expand Down Expand Up @@ -221,7 +224,8 @@ public Future<HttpServer> listen(ContextInternal current, SocketAddress address)
}

quicServer.handler(new ConnectionHandler(quicServer, httpMetrics, requestHandler, connectionHandler,
config.isHandle100ContinueAutomatically(), config.getMaxFormAttributeSize(), config.getMaxFormFields(),
config.isHandle100ContinueAutomatically(), config.getMaxFormAttributeSize(),
config.getMaxFormFields(), config.getMaxQueryParams(),
config.getMaxFormBufferedBytes(), http3Config.getInitialSettings() != null ? http3Config.getInitialSettings().copy() : new Http3Settings()));
return quicServer
.bind(current, address)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void handle(HttpServerConnection conn) {
HttpServerConfig config = server.config;
HttpServerRequestImpl request = new HttpServerRequestImpl(requestHandler, stream, stream.context(),
config.isHandle100ContinueAutomatically(), config.getMaxFormAttributeSize(), config.getMaxFormFields(),
config.getMaxFormBufferedBytes(), serverOrigin);
config.getMaxFormBufferedBytes(), config.getMaxQueryParams(), serverOrigin);
request.init();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class HttpServerConnectionInitializer {
private final boolean handle100ContinueAutomatically;
private final int maxFormAttributeSize;
private final int maxFormFields;
private final int maxQueryParams;
private final int maxFormBufferedBytes;
private final Http1ServerConfig http1Config;
private final Http2ServerConfig http2Config;
Expand All @@ -92,6 +93,7 @@ public HttpServerConnectionInitializer(ContextInternal context,
boolean handle100ContinueAutomatically,
int maxFormAttributeSize,
int maxFormFields,
int maxQueryParams,
int maxFormBufferedBytes,
Http1ServerConfig http1Config,
Http2ServerConfig http2Config,
Expand Down Expand Up @@ -154,6 +156,7 @@ public HttpServerConnectionInitializer(ContextInternal context,
this.handle100ContinueAutomatically = handle100ContinueAutomatically;
this.maxFormAttributeSize = maxFormAttributeSize;
this.maxFormFields = maxFormFields;
this.maxQueryParams = maxQueryParams;
this.maxFormBufferedBytes = maxFormBufferedBytes;
this.http1Config = http1Config;
this.http2Config = http2Config;
Expand Down Expand Up @@ -297,6 +300,7 @@ public void configureHttp1Handler(ChannelPipeline pipeline, SslContextManager ss
sslContextManager,
maxFormAttributeSize,
maxFormFields,
maxQueryParams,
maxFormBufferedBytes,
http1Config,
registerWebSocketWriteHandlers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ public synchronized Future<HttpServer> listen(ContextInternal context, SocketAdd
config.isHandle100ContinueAutomatically(),
config.getMaxFormAttributeSize(),
config.getMaxFormFields(),
config.getMaxQueryParams(),
config.getMaxFormBufferedBytes(),
config.getHttp1Config(),
config.getHttp2Config(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ public void setup() {
null,
HttpServerOptions.DEFAULT_MAX_FORM_ATTRIBUTE_SIZE,
HttpServerOptions.DEFAULT_MAX_FORM_FIELDS,
HttpServerOptions.DEFAULT_MAX_QUERY_PARAMS,
HttpServerOptions.DEFAULT_MAX_FORM_BUFFERED_SIZE,
new Http1ServerConfig(),
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public void testSimple() {
null,
HttpServerOptions.DEFAULT_MAX_FORM_ATTRIBUTE_SIZE,
HttpServerOptions.DEFAULT_MAX_FORM_FIELDS,
HttpServerOptions.DEFAULT_MAX_QUERY_PARAMS,
HttpServerOptions.DEFAULT_MAX_FORM_BUFFERED_SIZE,
new Http1ServerConfig(),
false,
Expand Down
10 changes: 9 additions & 1 deletion vertx-core/src/test/java/io/vertx/tests/http/Http1xTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ public void testServerOptions() {
assertEquals(256, options.getDecoderInitialBufferSize());
assertIllegalArgumentException(() -> options.setDecoderInitialBufferSize(-1));

assertEquals(HttpServerOptions.DEFAULT_MAX_QUERY_PARAMS, options.getMaxQueryParams());
assertEquals(options, options.setMaxQueryParams(1025));
assertEquals(1025, options.getMaxQueryParams());
}

@Test
Expand Down Expand Up @@ -772,6 +775,7 @@ public void testCopyServerOptions() {
boolean decompressionSupported = rand.nextBoolean();
boolean acceptUnmaskedFrames = rand.nextBoolean();
int decoderInitialBufferSize = TestUtils.randomPositiveInt();
int maxQueryParams = TestUtils.randomPositiveInt();

options.setSendBufferSize(sendBufferSize);
options.setReceiveBufferSize(receiverBufferSize);
Expand Down Expand Up @@ -803,6 +807,7 @@ public void testCopyServerOptions() {
options.setDecompressionSupported(decompressionSupported);
options.setAcceptUnmaskedFrames(acceptUnmaskedFrames);
options.setDecoderInitialBufferSize(decoderInitialBufferSize);
options.setMaxQueryParams(maxQueryParams);

HttpServerOptions copy = new HttpServerOptions(options);
checkCopyHttpServerOptions(options, copy);
Expand Down Expand Up @@ -906,6 +911,7 @@ public void testServerOptionsJson() {
boolean decompressionSupported = TestUtils.randomBoolean();
boolean acceptUnmaskedFrames = TestUtils.randomBoolean();
int decoderInitialBufferSize = TestUtils.randomPositiveInt();
int maxQueryParams = TestUtils.randomPositiveInt();

JsonObject json = new JsonObject();
json.put("sendBufferSize", sendBufferSize)
Expand Down Expand Up @@ -946,7 +952,8 @@ public void testServerOptionsJson() {
.put("openSslSessionCacheEnabled", openSslSessionCacheEnabled)
.put("decompressionSupported", decompressionSupported)
.put("acceptUnmaskedFrames", acceptUnmaskedFrames)
.put("decoderInitialBufferSize", decoderInitialBufferSize);
.put("decoderInitialBufferSize", decoderInitialBufferSize)
.put("maxQueryParams", maxQueryParams);

HttpServerOptions options = new HttpServerOptions(json);
assertEquals(sendBufferSize, options.getSendBufferSize());
Expand Down Expand Up @@ -996,6 +1003,7 @@ public void testServerOptionsJson() {
assertEquals(decompressionSupported, options.isDecompressionSupported());
assertEquals(acceptUnmaskedFrames, options.isAcceptUnmaskedFrames());
assertEquals(decoderInitialBufferSize, options.getDecoderInitialBufferSize());
assertEquals(maxQueryParams, options.getMaxQueryParams());

// Test other keystore/truststore types
json.remove("keyStoreOptions");
Expand Down
Loading
Loading