diff --git a/docs/src/main/asciidoc/http-reference.adoc b/docs/src/main/asciidoc/http-reference.adoc index c60c868cc9a30..6c376daaf2ddd 100644 --- a/docs/src/main/asciidoc/http-reference.adoc +++ b/docs/src/main/asciidoc/http-reference.adoc @@ -292,6 +292,10 @@ If you want to disable HTTP/2 you can set: quarkus.http.http2=false ---- +Note that some configuration attributes are specific to HTTP/2. +For example, to configure the max header list size (~ header), you need to configure the `quarkus.http.limits.max-header-list-size` attribute. +You can also enable or disable HTTP/2 push using `quarkus.http.http2-push-enabled`. + == Listening on a Random Port If you don't want to specify a port you can set `quarkus.http.port=0` or `quarkus.http.test-port=0`. A random open port diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java index e62490a3dddbe..9558a2d64b845 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java @@ -81,6 +81,14 @@ public class HttpConfiguration { @ConfigItem(defaultValue = "true") public boolean http2; + /** + * Enables or Disable the HTTP/2 Push feature. + * This setting can be used to disable server push. The server will not send a {@code PUSH_PROMISE} frame if it + * receives this parameter set to @{code false}. + */ + @ConfigItem(defaultValue = "true") + public boolean http2PushEnabled; + /** * The CORS config */ @@ -179,6 +187,14 @@ public class HttpConfiguration { @ConfigItem(defaultValue = "-1") public int acceptBacklog; + /** + * Set the SETTINGS_INITIAL_WINDOW_SIZE HTTP/2 setting. + * Indicates the sender's initial window size (in octets) for stream-level flow control. + * The initial value is {@code 2^16-1} (65,535) octets. + */ + @ConfigItem + public OptionalInt initialWindowSize; + /** * Path to a unix domain socket */ diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ServerLimitsConfig.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ServerLimitsConfig.java index 6b5bdd93e5d11..1d8e91e323eed 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ServerLimitsConfig.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ServerLimitsConfig.java @@ -2,6 +2,7 @@ import java.util.Optional; import java.util.OptionalInt; +import java.util.OptionalLong; import io.quarkus.runtime.annotations.ConfigGroup; import io.quarkus.runtime.annotations.ConfigItem; @@ -46,4 +47,43 @@ public class ServerLimitsConfig { @ConfigItem public OptionalInt maxConnections; + /** + * Set the SETTINGS_HEADER_TABLE_SIZE HTTP/2 setting. + *

+ * Allows the sender to inform the remote endpoint of the maximum size of the header compression table used to decode + * header blocks, in octets. The encoder can select any size equal to or less than this value by using signaling + * specific to the header compression format inside a header block. + * The initial value is {@code 4,096} octets. + */ + @ConfigItem + public OptionalLong headerTableSize; + + /** + * Set SETTINGS_MAX_CONCURRENT_STREAMS HTTP/2 setting. + *

+ * Indicates the maximum number of concurrent streams that the sender will allow. This limit is directional: it + * applies to the number of streams that the sender permits the receiver to create. Initially, there is no limit to + * this value. It is recommended that this value be no smaller than 100, to not unnecessarily limit parallelism. + */ + @ConfigItem + public OptionalLong maxConcurrentStreams; + + /** + * Set the SETTINGS_MAX_FRAME_SIZE HTTP/2 setting. + * Indicates the size of the largest frame payload that the sender is willing to receive, in octets. + * The initial value is {@code 2^14} (16,384) octets. + */ + @ConfigItem + public OptionalInt maxFrameSize; + + /** + * Set the SETTINGS_MAX_HEADER_LIST_SIZE HTTP/2 setting. + * This advisory setting informs a peer of the maximum size of header list that the sender is prepared to accept, + * in octets. The value is based on the uncompressed size of header fields, including the length of the name and + * value in octets plus an overhead of 32 octets for each header field. + * The default value is {@code 8192} + */ + @ConfigItem + public OptionalLong maxHeaderListSize; + } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/options/HttpServerOptionsUtils.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/options/HttpServerOptionsUtils.java index b9c522270fb30..1b0870c71234c 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/options/HttpServerOptionsUtils.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/options/HttpServerOptionsUtils.java @@ -23,6 +23,7 @@ import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig; import io.quarkus.vertx.http.runtime.management.ManagementInterfaceConfiguration; import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.Http2Settings; import io.vertx.core.http.HttpServerOptions; import io.vertx.core.http.HttpVersion; import io.vertx.core.net.JdkSSLEngineOptions; @@ -275,6 +276,27 @@ public static void applyCommonOptions(HttpServerOptions httpServerOptions, httpServerOptions.setDecompressionSupported(buildTimeConfig.enableDecompression); httpServerOptions.setMaxInitialLineLength(httpConfiguration.limits.maxInitialLineLength); httpServerOptions.setHandle100ContinueAutomatically(httpConfiguration.handle100ContinueAutomatically); + + if (httpConfiguration.http2) { + var settings = new Http2Settings(); + if (httpConfiguration.limits.headerTableSize.isPresent()) { + settings.setHeaderTableSize(httpConfiguration.limits.headerTableSize.getAsLong()); + } + settings.setPushEnabled(httpConfiguration.http2PushEnabled); + if (httpConfiguration.limits.maxConcurrentStreams.isPresent()) { + settings.setMaxConcurrentStreams(httpConfiguration.limits.maxConcurrentStreams.getAsLong()); + } + if (httpConfiguration.initialWindowSize.isPresent()) { + settings.setInitialWindowSize(httpConfiguration.initialWindowSize.getAsInt()); + } + if (httpConfiguration.limits.maxFrameSize.isPresent()) { + settings.setMaxFrameSize(httpConfiguration.limits.maxFrameSize.getAsInt()); + } + if (httpConfiguration.limits.maxHeaderListSize.isPresent()) { + settings.setMaxHeaderListSize(httpConfiguration.limits.maxHeaderListSize.getAsLong()); + } + httpServerOptions.setInitialSettings(settings); + } } public static void applyCommonOptionsForManagementInterface(HttpServerOptions options,