io.netty.handler.codec.compression.DecompressionException:GZIP标头中不支持的压缩方法0

问题描述 投票:0回答:1

我已实现Netty 4 HTTP服务器。

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管道工厂类是-

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是-

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();
    }
}

当我发送正常请求时,它工作正常。当我发送gzip压缩请求时,出现错误-

io.netty.handler.codec.compression.DecompressionException:GZIP标头中不支持的压缩方法0在io.netty.handler.codec.compression.JdkZlibDecoder.readGZIPHeader(JdkZlibDecoder.java:321)在io.netty.handler.codec.compression.JdkZlibDecoder.decode(JdkZlibDecoder.java:212)在io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:498)在io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:437)在io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)在io.netty.channel.DefaultChannelPipeline $ HeadContext.channelRead(DefaultChannelPipeline.java:1410)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)在io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:343)在io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:254)在io.netty.handler.codec.http.HttpContentDecoder.decodeContent(HttpContentDecoder.java:161)在io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:150)在io.netty.handler.codec.http.HttpContentDecoder.decode(HttpContentDecoder.java:47)在io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)在io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)在io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)在io.netty.channel.CombinedChannelDuplexHandler $ DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)在io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321)在io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295)在io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)在io.netty.channel.DefaultChannelPipeline $ HeadContext.channelRead(DefaultChannelPipeline.java:1410)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)在io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)在io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)在io.netty.channel.nio.AbstractNioByteChannel $ NioByteUnsafe.read(AbstractNioByteChannel.java:163)在io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)在io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)在io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)在io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)在io.netty.util.concurrent.SingleThreadEventExecutor $ 4.run(SingleThreadEventExecutor.java:989)在io.netty.util.internal.ThreadExecutorMap $ 2.run(ThreadExecutorMap.java:74)在io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)在java.lang.Thread.run(Thread.java:748)

样品申请为-

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���-!'

请求有效载荷'VP *I-.QR�R0T���-!'是使用以下逻辑的字符串"{ \"test\" : 1 }"的Gzip压缩-

 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();
}

如何使Netty Server中的Http解压缩正常工作?

netty
1个回答
0
投票

我测试http压缩的方式是错误的。下面的代码工作正常-

    try(CloseableHttpClient httpclient = HttpClients.createDefault()) {
        HttpPost httppost = new HttpPost("http://localhost:5880/test");
        String payload = "{ \"test\" : 1 }";
        EntityBuilder builder = EntityBuilder.create().gzipCompress().setContentEncoding("gzip").chunked().setText(payload);
        HttpEntity entity = builder.build();
        httppost.setEntity(entity);
        System.out.println();
        httppost.setHeader("Accept-Encoding", "gzip,deflate");
        httppost.setHeader("Content-Encoding", "gzip");
        System.out.println("Executing request: " + httppost.getRequestLine());
        CloseableHttpResponse response = httpclient.execute(httppost);
        try {
            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            System.out.println(EntityUtils.toString(response.getEntity()));
        } finally {
            response.close();
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.