diff --git a/src/main/java/io/vertx/core/http/HttpServerOptions.java b/src/main/java/io/vertx/core/http/HttpServerOptions.java index 447767ca7a0..c202fe30325 100755 --- a/src/main/java/io/vertx/core/http/HttpServerOptions.java +++ b/src/main/java/io/vertx/core/http/HttpServerOptions.java @@ -201,6 +201,11 @@ public class HttpServerOptions extends NetServerOptions { */ public static final TimeUnit DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION_TIME_UNIT = TimeUnit.SECONDS; + /** + * HTTP/2 maximum allowed number of small continuation frames. + */ + public static final int DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES = 16; + private boolean compressionSupported; private int compressionLevel; private List compressors; @@ -231,6 +236,7 @@ public class HttpServerOptions extends NetServerOptions { private boolean registerWebSocketWriteHandlers; private int http2RstFloodMaxRstFramePerWindow; private int http2RstFloodWindowDuration; + private int http2MaxSmallContinuationFrames; private TimeUnit http2RstFloodWindowDurationTimeUnit; /** @@ -280,6 +286,7 @@ public HttpServerOptions(HttpServerOptions other) { this.http2RstFloodMaxRstFramePerWindow = other.http2RstFloodMaxRstFramePerWindow; this.http2RstFloodWindowDuration = other.http2RstFloodWindowDuration; this.http2RstFloodWindowDurationTimeUnit = other.http2RstFloodWindowDurationTimeUnit; + this.http2MaxSmallContinuationFrames = other.http2MaxSmallContinuationFrames; } /** @@ -335,6 +342,7 @@ private void init() { http2RstFloodMaxRstFramePerWindow = DEFAULT_HTTP2_RST_FLOOD_MAX_RST_FRAME_PER_WINDOW; http2RstFloodWindowDuration = DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION; http2RstFloodWindowDurationTimeUnit = DEFAULT_HTTP2_RST_FLOOD_WINDOW_DURATION_TIME_UNIT; + http2MaxSmallContinuationFrames = DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES; } @Override @@ -1274,4 +1282,27 @@ public HttpServerOptions setHttp2RstFloodWindowDurationTimeUnit(TimeUnit http2Rs this.http2RstFloodWindowDurationTimeUnit = http2RstFloodWindowDurationTimeUnit; return this; } + + /** + * @return the max number of small continuation frame allowed + */ + public int getHttp2MaxSmallContinuationFrames() { + return http2MaxSmallContinuationFrames; + } + + /** + * Set the maximum number of small continuation frames allowed, this is used to prevent flood DoS attack + * via zero-byte continuation frames. The default value + * is {@link #DEFAULT_HTTP2_MAX_SMALL_CONTINUATION_FRAMES}. + * + * @param http2MaxSmallContinuationFrames the max number of small continuation frame allowed + * @return a reference to this, so the API can be used fluently + */ + public HttpServerOptions setHttp2MaxSmallContinuationFrames(int http2MaxSmallContinuationFrames) { + if (http2MaxSmallContinuationFrames < 1) { + throw new IllegalArgumentException(); + } + this.http2MaxSmallContinuationFrames = http2MaxSmallContinuationFrames; + return this; + } } diff --git a/src/main/java/io/vertx/core/http/impl/HttpServerWorker.java b/src/main/java/io/vertx/core/http/impl/HttpServerWorker.java index f783d9a333e..8098f28cb39 100644 --- a/src/main/java/io/vertx/core/http/impl/HttpServerWorker.java +++ b/src/main/java/io/vertx/core/http/impl/HttpServerWorker.java @@ -253,9 +253,11 @@ VertxHttp2ConnectionHandler buildHttp2ConnectionHandler(C HttpServerMetrics metrics = (HttpServerMetrics) server.getMetrics(); int maxRstFramesPerWindow = options.getHttp2RstFloodMaxRstFramePerWindow(); int secondsPerWindow = (int)options.getHttp2RstFloodWindowDurationTimeUnit().toSeconds(options.getHttp2RstFloodWindowDuration()); + int maxSmallContinuationFrames = options.getHttp2MaxSmallContinuationFrames(); VertxHttp2ConnectionHandler handler = new VertxHttp2ConnectionHandlerBuilder() .server(true) .useCompression(compressionOptions) + .decoderEnforceMaxSmallContinuationFrames(maxSmallContinuationFrames) .decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow) .encoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow) .useDecompression(options.isDecompressionSupported()) diff --git a/src/main/java/io/vertx/core/http/impl/VertxHttp2ConnectionHandlerBuilder.java b/src/main/java/io/vertx/core/http/impl/VertxHttp2ConnectionHandlerBuilder.java index 9f273a9fda1..7c2813b0c39 100644 --- a/src/main/java/io/vertx/core/http/impl/VertxHttp2ConnectionHandlerBuilder.java +++ b/src/main/java/io/vertx/core/http/impl/VertxHttp2ConnectionHandlerBuilder.java @@ -58,6 +58,11 @@ VertxHttp2ConnectionHandlerBuilder useUniformStreamByteDistributor(boolean us return this; } + @Override + protected VertxHttp2ConnectionHandlerBuilder decoderEnforceMaxSmallContinuationFrames(int maxSmallContinuationFrames) { + return super.decoderEnforceMaxSmallContinuationFrames(maxSmallContinuationFrames); + } + @Override protected VertxHttp2ConnectionHandlerBuilder decoderEnforceMaxRstFramesPerWindow(int maxRstFramesPerWindow, int secondsPerWindow) { return super.decoderEnforceMaxRstFramesPerWindow(maxRstFramesPerWindow, secondsPerWindow);