io.netty.handler.codec.compression.DecompressionException: Unsupported compression method 0 in the GZIP header
See original GitHub issueExpected behavior
I’m expecting HttpDecompressor
to decompress the payload correctly when the request payload is compresssed with gzip.
Actual behavior
I’m getting the below exception -
io.netty.handler.codec.compression.DecompressionException: Unsupported compression method 0 in the GZIP header at io.netty.handler.codec.compression.JdkZlibDecoder.readGZIPHeader(JdkZlibDecoder.java:321) at io.netty.handler.codec.compression.JdkZlibDecoder.decode(JdkZlibDecoder.java:212) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:498) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:437) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:343) at io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:254) at io.netty.handler.codec.http.HttpContentDecoder.decodeContent(HttpContentDecoder.java:161) at io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:150) at io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:47) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295) at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)
Steps to reproduce
curl --location --request POST 'http://localhost:5880/' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Accept-Encoding: gzip' \
--header 'Accept-Language: en-US,en;q=0.9' \
--header 'Connection: Keep-Alive' \
--header 'Content-Encoding: gzip' \
--header 'Content-Type: text/plain' \
--data-raw '�VP*I-.QR�R0T���-!'
The request payload ‘�VP*I-.QR�R0T���-!’ is Gzip compression of string "{ \"test\" : 1 }"
using below logic -
public static byte[] compress(String str) throws Exception {
if (str == null || str.length() == 0) {
return null;
}
System.out.println("String length : " + str.length());
ByteArrayOutputStream obj=new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj, 2);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return obj.toByteArray();
}
Minimal yet complete reproducer code (or URL to code)
public void start() {
System.out.println("In Start method");
try {
ServerBootstrap b = new ServerBootstrap();
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new HttpServerPipelineFactory())
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT)
.childOption(ChannelOption.AUTO_READ, false)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(listenerPort).sync();
System.out.println("server started listening on port " + listenerPort);
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}
}
HTTP pipeline factory class is -
public class HttpServerPipelineFactory extends ChannelInitializer<Channel> {
@Override
protected void initChannel(Channel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec", new HttpServerCodec());
pipeline.addLast("compress", new HttpContentCompressor());
pipeline.addLast("decompress", new HttpContentDecompressor());
pipeline.addLast("aggregator", new HttpObjectAggregator( 512 * 1024));
pipeline.addLast("chunked", new ChunkedWriteHandler());
pipeline.addLast("flow", new FlowControlHandler());
pipeline.addLast("keep-alive", new HttpServerKeepAliveHandler());
pipeline.addLast("request", new HTTPRequestHandler());
}
}
HTTPRequestHandler is -
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static io.netty.util.CharsetUtil.UTF_8;
public class HTTPRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private static Logger logger = LoggerFactory.getLogger(HTTPRequestHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
System.out.println("uri is " + request.uri());
String responseStr = request.method() +"/ Got request at " + request.uri();
System.out.println("body is \n" + request.content().toString(UTF_8));
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.copiedBuffer(responseStr.getBytes()), false);
response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
ctx.channel().writeAndFlush(response);
ctx.read();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.read();
}
}
Netty version
4.1.14.Final
JVM version (e.g. java -version
)
openjdk version "1.8.0_232"
OS version (e.g. uname -a
)
Darwin BOSM0001-RANATA.local 16.7.0 Darwin Kernel Version 16.7.0: Sun Jun 2 20:26:31 PDT 2019; root:xnu-3789.73.50~1/RELEASE_X86_64 x86_64
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (5 by maintainers)
Top Results From Across the Web
io.netty.handler.codec.compression.DecompressionException
The way I'm testing the http compression is wrong. Below code works fine - try(CloseableHttpClient httpclient = HttpClients.
Read more >com.couchbase.client.deps.io.netty.handler.codec ... - Tabnine
Validates that the offset extracted from a compressed reference is within * the permissible bounds of an offset (4 <= offset <= 32768), ......
Read more >io.netty.handler.codec.compression.JdkZlibDecoder - Netty 4.0.56 ...
以上源码来自: 即时通讯网 - 即时通讯开发者社区!
Read more >JdkZlibDecoder xref - Netty
15 */ 16 package io.netty.handler.codec.compression; 17 18 import io.netty.buffer. ... 43 44 private enum GzipState { 45 HEADER_START, 46 HEADER_END, ...
Read more >io.netty.handler.codec.compression.JdkZlibDecoder.java ...
Here is the source code for io.netty.handler.codec.compression.JdkZlibDecoder.java ... "Unsupported compression method " + method + " in the GZIP header"); ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Replace
compressedData
byte array with your compressed data byte array.This won’t work, see #2132.
HttpContentDecompressor
extendsHttpContentDecoder
that currently only decodesHttpRequest
s andHttpContentCompressor
extendsHttpContentEncoder
that currently only encodesHttpResponse
s.In short: Netty only supports compressing server side and decompressing client side, not the other way around like you’re trying to do.