diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/DefaultHttpCompressionStrategy.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/DefaultHttpCompressionStrategy.java index a06975d5829..20ecbbecac0 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/DefaultHttpCompressionStrategy.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/DefaultHttpCompressionStrategy.java @@ -36,6 +36,7 @@ final class DefaultHttpCompressionStrategy implements HttpCompressionStrategy { private final int compressionThreshold; private final int compressionLevel; + private final int maxZstdEncodeSize; /** * @param serverConfiguration The netty server configuration @@ -44,15 +45,17 @@ final class DefaultHttpCompressionStrategy implements HttpCompressionStrategy { DefaultHttpCompressionStrategy(NettyHttpServerConfiguration serverConfiguration) { this.compressionThreshold = serverConfiguration.getCompressionThreshold(); this.compressionLevel = serverConfiguration.getCompressionLevel(); + this.maxZstdEncodeSize = serverConfiguration.getMaxZstdEncodeSize(); } /** * @param compressionThreshold The compression threshold * @param compressionLevel The compression level (0-9) */ - DefaultHttpCompressionStrategy(int compressionThreshold, int compressionLevel) { + DefaultHttpCompressionStrategy(int compressionThreshold, int compressionLevel, int maxZstdEncodeSize) { this.compressionThreshold = compressionThreshold; this.compressionLevel = compressionLevel; + this.maxZstdEncodeSize = maxZstdEncodeSize; } @Override @@ -79,4 +82,9 @@ public boolean shouldCompress(HttpResponse response) { public int getCompressionLevel() { return compressionLevel; } + + @Override + public int getMaxZstdEncodeSize() { + return maxZstdEncodeSize; + } } diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpCompressionStrategy.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpCompressionStrategy.java index 29edddefd98..2746fc5b674 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpCompressionStrategy.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpCompressionStrategy.java @@ -39,4 +39,9 @@ public interface HttpCompressionStrategy extends Toggleable { default int getCompressionLevel() { return StandardCompressionOptions.gzip().compressionLevel(); } + + /** + * @return The maximum size of data that can be encoded using the zstd algorithm. + */ + int getMaxZstdEncodeSize(); } diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/configuration/NettyHttpServerConfiguration.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/configuration/NettyHttpServerConfiguration.java index d26b2ff1f63..0d5c9b7f60e 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/configuration/NettyHttpServerConfiguration.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/configuration/NettyHttpServerConfiguration.java @@ -109,6 +109,12 @@ public class NettyHttpServerConfiguration extends HttpServerConfiguration { @SuppressWarnings("WeakerAccess") public static final int DEFAULT_COMPRESSIONLEVEL = 6; + /** + * The default size of the largest data that can be encoded using the zstd algorithm. + */ + @SuppressWarnings("WeakerAccess") + public static final int DEFAULT_MAX_ZSTD_ENCODE_SIZE = 1024 * 1024 * 32; + /** * The default configuration for boolean flag indicating whether to add connection header `keep-alive` to responses with HttpStatus > 499. */ @@ -200,6 +206,7 @@ public class NettyHttpServerConfiguration extends HttpServerConfiguration { private LogLevel logLevel; private int compressionThreshold = DEFAULT_COMPRESSIONTHRESHOLD; private int compressionLevel = DEFAULT_COMPRESSIONLEVEL; + private int maxZstdEncodeSize = DEFAULT_MAX_ZSTD_ENCODE_SIZE; private boolean useNativeTransport = DEFAULT_USE_NATIVE_TRANSPORT; private String fallbackProtocol = ApplicationProtocolNames.HTTP_1_1; private AccessLogger accessLogger; @@ -472,6 +479,16 @@ public int getCompressionLevel() { return compressionLevel; } + /** + * The default maximum size of data that can be encoded using the zstd algorithm. + * Default value ({@value #DEFAULT_MAX_ZSTD_ENCODE_SIZE}). + * + * @return The maximum size of data that can be encoded using the zstd algorithm. + */ + public int getMaxZstdEncodeSize() { + return maxZstdEncodeSize; + } + /** * @return The Netty child channel options. * @see io.netty.bootstrap.ServerBootstrap#childOption(io.netty.channel.ChannelOption, Object) @@ -657,6 +674,15 @@ public void setCompressionLevel(@ReadableBytes int compressionLevel) { this.compressionLevel = compressionLevel; } + /** + * Sets the maximum size of data that can be encoded using the zstd algorithm. Default value ({@value #DEFAULT_MAX_ZSTD_ENCODE_SIZE}). + * + * @param maxZstdEncodeSize The maximum size of block. + */ + public void setMaxZstdEncodeSize(int maxZstdEncodeSize) { + this.maxZstdEncodeSize = maxZstdEncodeSize; + } + /** * Whether to send connection keep alive on internal server errors. Default value ({@value DEFAULT_KEEP_ALIVE_ON_SERVER_ERROR}). * @param keepAliveOnServerError The keep alive on server error flag diff --git a/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/Compressor.java b/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/Compressor.java index dd5a88ca2a3..9c28d2294eb 100644 --- a/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/Compressor.java +++ b/http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/Compressor.java @@ -65,7 +65,11 @@ final class Compressor { this.gzipOptions = StandardCompressionOptions.gzip(strategy.getCompressionLevel(), stdGzip.windowBits(), stdGzip.memLevel()); DeflateOptions stdDeflate = StandardCompressionOptions.deflate(); this.deflateOptions = StandardCompressionOptions.deflate(strategy.getCompressionLevel(), stdDeflate.windowBits(), stdDeflate.memLevel()); - this.zstdOptions = Zstd.isAvailable() ? StandardCompressionOptions.zstd() : null; + this.zstdOptions = Zstd.isAvailable() + ? StandardCompressionOptions.zstd(strategy.getCompressionLevel(), + StandardCompressionOptions.zstd().blockSize(), + strategy.getMaxZstdEncodeSize()) + : null; this.snappyOptions = StandardCompressionOptions.snappy(); } @@ -96,7 +100,7 @@ Session prepare(ChannelHandlerContext ctx, HttpRequest request, HttpResponse res response.headers().add(HttpHeaderNames.CONTENT_ENCODING, encoding.contentEncoding); ChannelHandler handler = switch (encoding) { case BR -> makeBrotliEncoder(); - case ZSTD -> new ZstdEncoder(zstdOptions.compressionLevel(), zstdOptions.blockSize(), zstdOptions.maxEncodeSize()); + case ZSTD -> new ZstdEncoder(zstdOptions.compressionLevel(), zstdOptions.blockSize(), strategy.getMaxZstdEncodeSize()); case SNAPPY -> new SnappyFrameEncoder(); case GZIP -> ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP, gzipOptions.compressionLevel(), gzipOptions.windowBits(), gzipOptions.memLevel()); case DEFLATE -> ZlibCodecFactory.newZlibEncoder(ZlibWrapper.ZLIB, deflateOptions.compressionLevel(), deflateOptions.windowBits(), deflateOptions.memLevel());