You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何判断gzip压缩byte[]是否被多次压缩?Netty解压问题

解决Netty HttpContentDecompressor处理多次压缩请求的问题

方案1:检查数据是否为gzip格式

gzip压缩的数据开头有固定的魔数(0x1F 0x8B),可以通过判断字节数组的前两个字节识别是否仍处于压缩状态。实现一个简单的工具方法即可:

public static boolean isGzipped(byte[] data) {
    if (data == null || data.length < 2) {
        return false;
    }
    return (data[0] == (byte) 0x1F) && (data[1] == (byte) 0x8B);
}

在HttpContentDecompressor解压完成后调用这个方法,若返回true则再次执行解压逻辑,直到数据不再是gzip格式。注意设置最大解压次数(比如3次),防止恶意嵌套压缩导致死循环。

方案2:自定义递归解压的Handler

继承HttpContentDecompressor,重写解压逻辑实现自动多次处理:

public class RecursiveHttpContentDecompressor extends HttpContentDecompressor {
    private static final int MAX_DECOMPRESS_TIMES = 3;
    private int decompressCount = 0;

    @Override
    protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
        super.decode(ctx, msg, out);
        // 处理完整请求对象
        if (msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;
            ByteBuf content = request.content();
            byte[] data = new byte[content.readableBytes()];
            content.readBytes(data);
            content.resetReaderIndex();
            
            if (isGzipped(data) && decompressCount < MAX_DECOMPRESS_TIMES) {
                decompressCount++;
                FullHttpRequest newRequest = request.retain();
                decode(ctx, newRequest, out);
            }
        }
        // 流式请求需先拼接完整内容再检查压缩状态,这里省略具体实现
    }
    
    private boolean isGzipped(byte[] data) {
        if (data == null || data.length < 2) {
            return false;
        }
        return (data[0] == (byte) 0x1F) && (data[1] == (byte) 0x8B);
    }
}

用这个自定义Handler替换原有的HttpContentDecompressor,即可自动处理多次压缩的请求,同时通过MAX_DECOMPRESS_TIMES限制解压次数避免资源耗尽。

注意事项

  • 流式请求(分段的HttpContent)需要先拼接完整请求体,再检查压缩状态,不能单独处理每个片段。
  • 必须设置最大解压次数,防范恶意构造的无限嵌套压缩数据攻击。

内容的提问来源于stack exchange,提问作者V John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:17:15