61
61
62
62
import java .net .InetSocketAddress ;
63
63
import java .net .SocketOption ;
64
+ import java .util .ArrayList ;
65
+ import java .util .List ;
64
66
import java .util .concurrent .TimeUnit ;
65
67
66
68
import io .netty .bootstrap .ServerBootstrap ;
77
79
import io .netty .channel .SimpleChannelInboundHandler ;
78
80
import io .netty .channel .socket .nio .NioChannelOption ;
79
81
import io .netty .handler .codec .ByteToMessageDecoder ;
82
+ import io .netty .handler .codec .compression .Brotli ;
83
+ import io .netty .handler .codec .compression .CompressionOptions ;
84
+ import io .netty .handler .codec .compression .DeflateOptions ;
85
+ import io .netty .handler .codec .compression .GzipOptions ;
86
+ import io .netty .handler .codec .compression .StandardCompressionOptions ;
87
+ import io .netty .handler .codec .compression .ZstdEncoder ;
80
88
import io .netty .handler .codec .http .HttpContentCompressor ;
81
89
import io .netty .handler .codec .http .HttpContentDecompressor ;
82
90
import io .netty .handler .codec .http .HttpMessage ;
@@ -440,7 +448,7 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws E
440
448
pipeline .addAfter (
441
449
"aggregator" ,
442
450
"encoder_compress" ,
443
- new HttpContentCompressor (handlingSettings .getCompressionLevel ())
451
+ new HttpContentCompressor (defaultCompressionOptions ( handlingSettings .getCompressionLevel () ))
444
452
);
445
453
}
446
454
pipeline .addBefore ("handler" , "request_creator" , requestCreator );
@@ -467,7 +475,10 @@ protected void configureDefaultHttpPipeline(ChannelPipeline pipeline) {
467
475
aggregator .setMaxCumulationBufferComponents (transport .maxCompositeBufferComponents );
468
476
pipeline .addLast ("aggregator" , aggregator );
469
477
if (handlingSettings .isCompression ()) {
470
- pipeline .addLast ("encoder_compress" , new HttpContentCompressor (handlingSettings .getCompressionLevel ()));
478
+ pipeline .addLast (
479
+ "encoder_compress" ,
480
+ new HttpContentCompressor (defaultCompressionOptions (handlingSettings .getCompressionLevel ()))
481
+ );
471
482
}
472
483
pipeline .addLast ("request_creator" , requestCreator );
473
484
pipeline .addLast ("response_creator" , responseCreator );
@@ -512,7 +523,10 @@ protected void initChannel(Channel childChannel) throws Exception {
512
523
513
524
if (handlingSettings .isCompression ()) {
514
525
childChannel .pipeline ()
515
- .addLast ("encoder_compress" , new HttpContentCompressor (handlingSettings .getCompressionLevel ()));
526
+ .addLast (
527
+ "encoder_compress" ,
528
+ new HttpContentCompressor (defaultCompressionOptions (handlingSettings .getCompressionLevel ()))
529
+ );
516
530
}
517
531
518
532
childChannel .pipeline ()
@@ -563,4 +577,59 @@ protected ChannelInboundHandlerAdapter createHeaderVerifier() {
563
577
protected ChannelInboundHandlerAdapter createDecompressor () {
564
578
return new HttpContentDecompressor ();
565
579
}
580
+
581
+ /**
582
+ * Copy of {@link HttpContentCompressor} default compression options with ZSTD excluded:
583
+ * although zstd-jni is on the classpath, {@link ZstdEncoder} requires direct buffers support
584
+ * which by default {@link NettyAllocator} does not provide.
585
+ *
586
+ * @param compressionLevel
587
+ * {@code 1} yields the fastest compression and {@code 9} yields the
588
+ * best compression. {@code 0} means no compression. The default
589
+ * compression level is {@code 6}.
590
+ *
591
+ * @return default compression options
592
+ */
593
+ private static CompressionOptions [] defaultCompressionOptions (int compressionLevel ) {
594
+ return defaultCompressionOptions (compressionLevel , 15 , 8 );
595
+ }
596
+
597
+ /**
598
+ * Copy of {@link HttpContentCompressor} default compression options with ZSTD excluded:
599
+ * although zstd-jni is on the classpath, {@link ZstdEncoder} requires direct buffers support
600
+ * which by default {@link NettyAllocator} does not provide.
601
+ *
602
+ * @param compressionLevel
603
+ * {@code 1} yields the fastest compression and {@code 9} yields the
604
+ * best compression. {@code 0} means no compression. The default
605
+ * compression level is {@code 6}.
606
+ * @param windowBits
607
+ * The base two logarithm of the size of the history buffer. The
608
+ * value should be in the range {@code 9} to {@code 15} inclusive.
609
+ * Larger values result in better compression at the expense of
610
+ * memory usage. The default value is {@code 15}.
611
+ * @param memLevel
612
+ * How much memory should be allocated for the internal compression
613
+ * state. {@code 1} uses minimum memory and {@code 9} uses maximum
614
+ * memory. Larger values result in better and faster compression
615
+ * at the expense of memory usage. The default value is {@code 8}
616
+ *
617
+ * @return default compression options
618
+ */
619
+ private static CompressionOptions [] defaultCompressionOptions (int compressionLevel , int windowBits , int memLevel ) {
620
+ final List <CompressionOptions > options = new ArrayList <CompressionOptions >(4 );
621
+ final GzipOptions gzipOptions = StandardCompressionOptions .gzip (compressionLevel , windowBits , memLevel );
622
+ final DeflateOptions deflateOptions = StandardCompressionOptions .deflate (compressionLevel , windowBits , memLevel );
623
+
624
+ options .add (gzipOptions );
625
+ options .add (deflateOptions );
626
+ options .add (StandardCompressionOptions .snappy ());
627
+
628
+ if (Brotli .isAvailable ()) {
629
+ options .add (StandardCompressionOptions .brotli ());
630
+ }
631
+
632
+ return options .toArray (new CompressionOptions [0 ]);
633
+ }
634
+
566
635
}
0 commit comments