1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http;
17
18 import static io.netty.handler.codec.http.HttpHeaderValues.BR;
19 import static io.netty.handler.codec.http.HttpHeaderValues.DEFLATE;
20 import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
21 import static io.netty.handler.codec.http.HttpHeaderValues.X_DEFLATE;
22 import static io.netty.handler.codec.http.HttpHeaderValues.X_GZIP;
23 import static io.netty.handler.codec.http.HttpHeaderValues.SNAPPY;
24 import static io.netty.handler.codec.http.HttpHeaderValues.ZSTD;
25
26 import io.netty.channel.embedded.EmbeddedChannel;
27 import io.netty.handler.codec.compression.Brotli;
28 import io.netty.handler.codec.compression.BrotliDecoder;
29 import io.netty.handler.codec.compression.SnappyFrameDecoder;
30 import io.netty.handler.codec.compression.ZlibCodecFactory;
31 import io.netty.handler.codec.compression.ZlibWrapper;
32 import io.netty.handler.codec.compression.Zstd;
33 import io.netty.handler.codec.compression.ZstdDecoder;
34
35
36
37
38
39
40 public class HttpContentDecompressor extends HttpContentDecoder {
41
42 private final boolean strict;
43
44
45
46
47 public HttpContentDecompressor() {
48 this(false);
49 }
50
51
52
53
54
55
56
57 public HttpContentDecompressor(boolean strict) {
58 this.strict = strict;
59 }
60
61 @Override
62 protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Exception {
63 if (GZIP.contentEqualsIgnoreCase(contentEncoding) ||
64 X_GZIP.contentEqualsIgnoreCase(contentEncoding)) {
65 return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
66 ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
67 }
68 if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) ||
69 X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) {
70 final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE;
71
72 return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
73 ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper));
74 }
75 if (Brotli.isAvailable() && BR.contentEqualsIgnoreCase(contentEncoding)) {
76 return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
77 ctx.channel().config(), new BrotliDecoder());
78 }
79
80 if (SNAPPY.contentEqualsIgnoreCase(contentEncoding)) {
81 return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
82 ctx.channel().config(), new SnappyFrameDecoder());
83 }
84
85 if (Zstd.isAvailable() && ZSTD.contentEqualsIgnoreCase(contentEncoding)) {
86 return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(),
87 ctx.channel().config(), new ZstdDecoder());
88 }
89
90
91 return null;
92 }
93 }