Skip to content

Commit

Permalink
Makes Brotli more native compilation friendly (#12409)
Browse files Browse the repository at this point in the history
Motivation:
CompressorHttp2ConnectionEncoder shouldn't load anything specific to Brotli if it isn't available

Modification:
Allows a null Brotli option to be passed to CompressorHttp2ConnectionEncoder

Result:
GraalVM Native compilation without Brotli doesn't requires Brotli classes
  • Loading branch information
franz1981 committed Jun 1, 2022
1 parent 27e0f52 commit 8098219
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
Expand Up @@ -178,8 +178,13 @@ public HttpContentCompressor(int contentSizeThreshold, CompressionOptions... com
} else {
ObjectUtil.deepCheckNotNull("compressionOptions", compressionOptions);
for (CompressionOptions compressionOption : compressionOptions) {
if (compressionOption instanceof BrotliOptions) {
// if we have BrotliOptions, it means Brotli is available
// BrotliOptions' class initialization depends on Brotli classes being on the classpath.
// The Brotli.isAvailable check ensures that BrotliOptions will only get instantiated if Brotli is
// on the classpath.
// This results in the static analysis of native-image identifying the instanceof BrotliOptions check
// and thus BrotliOptions itself as unreachable, enabling native-image to link all classes
// at build time and not complain about the missing Brotli classes.
if (Brotli.isAvailable() && compressionOption instanceof BrotliOptions) {
brotliOptions = (BrotliOptions) compressionOption;
} else if (compressionOption instanceof GzipOptions) {
gzipOptions = (GzipOptions) compressionOption;
Expand Down Expand Up @@ -207,7 +212,7 @@ public HttpContentCompressor(int contentSizeThreshold, CompressionOptions... com
if (this.deflateOptions != null) {
this.factories.put("deflate", new DeflateEncoderFactory());
}
if (this.brotliOptions != null) {
if (Brotli.isAvailable() && this.brotliOptions != null) {
this.factories.put("br", new BrEncoderFactory());
}
if (this.zstdOptions != null) {
Expand Down
Expand Up @@ -24,6 +24,7 @@
import io.netty.handler.codec.compression.BrotliEncoder;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.codec.compression.Brotli;
import io.netty.handler.codec.compression.BrotliOptions;
import io.netty.handler.codec.compression.CompressionOptions;
import io.netty.handler.codec.compression.DeflateOptions;
Expand Down Expand Up @@ -73,8 +74,17 @@ public class CompressorHttp2ConnectionEncoder extends DecoratingHttp2ConnectionE
* with default implementation of {@link StandardCompressionOptions}
*/
public CompressorHttp2ConnectionEncoder(Http2ConnectionEncoder delegate) {
this(delegate, StandardCompressionOptions.brotli(), StandardCompressionOptions.gzip(),
StandardCompressionOptions.deflate());
this(delegate, defaultCompressionOptions());
}

private static CompressionOptions[] defaultCompressionOptions() {
if (Brotli.isAvailable()) {
return new CompressionOptions[] {
StandardCompressionOptions.brotli(),
StandardCompressionOptions.gzip(),
StandardCompressionOptions.deflate() };
}
return new CompressionOptions[] { StandardCompressionOptions.gzip(), StandardCompressionOptions.deflate() };
}

/**
Expand Down Expand Up @@ -113,7 +123,13 @@ public CompressorHttp2ConnectionEncoder(Http2ConnectionEncoder delegate,
ObjectUtil.deepCheckNotNull("CompressionOptions", compressionOptionsArgs);

for (CompressionOptions compressionOptions : compressionOptionsArgs) {
if (compressionOptions instanceof BrotliOptions) {
// BrotliOptions' class initialization depends on Brotli classes being on the classpath.
// The Brotli.isAvailable check ensures that BrotliOptions will only get instantiated if Brotli is on
// the classpath.
// This results in the static analysis of native-image identifying the instanceof BrotliOptions check
// and thus BrotliOptions itself as unreachable, enabling native-image to link all classes at build time
// and not complain about the missing Brotli classes.
if (Brotli.isAvailable() && compressionOptions instanceof BrotliOptions) {
brotliOptions = (BrotliOptions) compressionOptions;
} else if (compressionOptions instanceof GzipOptions) {
gzipCompressionOptions = (GzipOptions) compressionOptions;
Expand Down Expand Up @@ -258,7 +274,7 @@ protected EmbeddedChannel newContentCompressor(ChannelHandlerContext ctx, CharSe
if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) || X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) {
return newCompressionChannel(ctx, ZlibWrapper.ZLIB);
}
if (brotliOptions != null && BR.contentEqualsIgnoreCase(contentEncoding)) {
if (Brotli.isAvailable() && brotliOptions != null && BR.contentEqualsIgnoreCase(contentEncoding)) {
return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
ctx.channel().config(), new BrotliEncoder(brotliOptions.parameters()));
}
Expand Down

0 comments on commit 8098219

Please sign in to comment.