req icon indicating copy to clipboard operation
req copied to clipboard

Add support for zstd content encoding...

Open plzcloseyoureyes opened this issue 8 months ago • 2 comments

zstd seems to be not supported, if i get response encoded with zstd it simply turns gibbrish...

plzcloseyoureyes avatar Apr 03 '25 19:04 plzcloseyoureyes

func NewAndroidClient() *EnhancedClient { bm := NewBrowserManager() info := bm.GetAndroidUA()

client := req.C()

// 根据浏览器类型配置
switch info.Type {
case Chrome:
    // 使用新的 Android Chrome 方法
    if info.Version >= 130 && info.Version <= 138 {
        client.ImpersonateAndroidChromeWithVersion(info.Version)
    } else {
        client.ImpersonateAndroidChrome()
    }
    
case OkHttp:
    // 使用新的 OkHttp 方法
    client.ImpersonateOkHttp()
}

// 添加解压支持
client.OnAfterResponse(handleAllCompression)
client.SetTimeout(30 * time.Second)

return &EnhancedClient{
    Client:      client,
    BrowserInfo: info,
}

}

// handleAllCompression 处理所有类型的压缩 func handleAllCompression(c *req.Client, resp *req.Response) error { if resp.Err != nil || resp.Body == nil { return nil }

contentEncoding := resp.Header.Get("Content-Encoding")
if contentEncoding == "" {
    return nil
}

// 读取原始内容
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
    return nil
}
resp.Body.Close()

// 解压
decodedBytes, err := decompressData(bodyBytes, contentEncoding)
if err != nil {
    // 解压失败,使用原始数据
    resp.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes))
} else {
    // 解压成功
    resp.Body = ioutil.NopCloser(bytes.NewReader(decodedBytes))
}

return nil

}

// decompressData 解压数据 func decompressData(data []byte, encoding string) ([]byte, error) { switch encoding { case "br": reader := brotli.NewReader(bytes.NewReader(data)) return ioutil.ReadAll(reader)

case "gzip":
    reader, err := gzip.NewReader(bytes.NewReader(data))
    if err != nil {
        return nil, err
    }
    defer reader.Close()
    return ioutil.ReadAll(reader)
    
case "deflate":
    reader := flate.NewReader(bytes.NewReader(data))
    defer reader.Close()
    return ioutil.ReadAll(reader)
    
case "zstd":
    decoder, err := zstd.NewReader(bytes.NewReader(data))
    if err != nil {
        return nil, err
    }
    defer decoder.Close()
    return ioutil.ReadAll(decoder)
    
default:
    // 未知编码,返回原始数据
    return data, nil
}

}

// GetDecodedContent 获取解码后的内容 func (ec *EnhancedClient) GetDecodedContent(resp *req.Response) (string, error) { body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } resp.Body = ioutil.NopCloser(bytes.NewReader(body)) return string(body), nil } 顺带一提brotli 好像也不支持?

itututu avatar Jul 13 '25 14:07 itututu

zstd and brotli both are supported by default: https://github.com/imroc/req/blob/2069ef940dcb1c493d80750609b589765be3c465/internal/compress/reader.go#L17-L20

Do you use latest version? Can you provide reproducible code?

imroc avatar Jul 14 '25 01:07 imroc