gpt4 book ai didi

戈兰 : "compress/flate" module can't decompress valid deflate compressed HTTP body

转载 作者:行者123 更新时间:2023-12-02 14:50:42 31 4
gpt4 key购买 nike

这个问题继续讨论开始 here 。我发现 HTTP 响应正文无法被解码为 JSON 对象,因为后者的 deflate 压缩。现在我想知道如何用Golang进行解压。我将不胜感激任何能够显示我的代码中的错误的人。

输入数据

我已将 HTTP 响应正文转储到“test”中' 文件。这是它:

$ cat test
x��PAN�0�
;��NtJ�FӮdU�|"oVR�C%�f�����Z.�^Hs�dW뮑�'��DH�S�SFVC����r)G,�����<���z}�x_g�+�2��sl�r/�Oy>��J3\�G�9���N���#[5M�^v/�2Ҕ��|�h��[�~7�_崛<D*���/��i

让我们确保该文件可以解压,甚至包含有效的 JSON:

$ zlib-flate -uncompress < test
{"timestamp":{"tv_sec":1428488670,"tv_usec":197041},"string_timestamp":"2015-04-08 10:24:30.197041","monitor_status":"enabled","commands":{"REVERSE_LOOKUP":{"cache":{"outside":{"successes":0,"failures":0,"size":0,"time":0},"internal":{"successes":0,"failures":0,"size":0,"time":0}},"disk":{"outside":{"successes":0,"failures":0,"size":0,"time":0},"internal":{"successes":13366,"failures":0,"size":0,"time":501808}},"total":{"storage":{"successes":0,"failures":0},"proxy":{"successes":13366,"failures":0}}},"clients":{}}}
$ zlib-flate -uncompress < test | python -m json.tool
{
"commands": {
"REVERSE_LOOKUP": {
"cache": {
....

源代码

package main

import (
"bytes"
"compress/flate"
"fmt"
"io/ioutil"
)

func main() {
fname := "./test"
content, err := ioutil.ReadFile(fname)
if err != nil {
panic(err)
}
fmt.Println("File content:\n", content)

enflated, err := ioutil.ReadAll(flate.NewReader(bytes.NewReader(content)))
if err != nil {
panic(err)
}
fmt.Println("Enflated:\n", enflated)
}

错误

$ go run uncompress.go 
File content:
[120 156 181 80 65 78 195 48 16 252 10 242 57 69 118 226 166 38 247 156 64 42 42 130 107 100 156 165 88 196 118 149 93 35 160 234 223 89 183 61 112 42 226 192 109 118 118 102 103 180 123 65 62 0 146 13 59 209 237 5 189 15 8 78 116 74 215 70 27 211 174 100 85 184 124 34 111 86 82 171 67 37 144 102 31 183 195 15 167 168 165 90 46 164 94 72 115 165 100 87 235 174 145 215 39 189 168 68 72 209 83 154 7 22 83 70 86 67 180 207 19 140 188 114 41 4 27 71 44 225 155 254 169 223 60 244 195 221 122 125 251 120 95 24 103 221 43 20 144 50 161 31 143 16 179 115 128 8 108 225 114 47 214 79 121 62 15 232 191 224 8 74 51 6 92 213 71 130 57 218 233 175 78 182 142 30 223 254 35 91 53 77 219 94 118 47 165 50 210 148 18 148 232 124 128 31 104 183 151 91 176 126 55 167 143 207 95 3 15 229 180 155 60 68 42 159 231 241 27 47 165 167 25]
panic: flate: corrupt input before offset 5

goroutine 1 [running]:
runtime.panic(0x4a7180, 0x5)
/usr/lib/go/src/pkg/runtime/panic.c:266 +0xb6
main.main()
/home/isaev/side-projects/elliptics-manager/uncompress.go:20 +0x2a3
exit status 2

PSUbuntu 14.10、Go 1.2.1

最佳答案

您的输入不是一个简单的压缩 block ,而是一个zlib流

根据ZLIB Compressed Data Format Specification 3.3前 2 个字节是:

-------------
| CMF | FLG |
-------------

压缩方法和标志。您的输入以 [120, 156] 开头,即十六进制的 78 9C。这是默认压缩。后面也没有字典,所以后面的数据是压缩后的数据。

位 0 到 3 是 CM 压缩方法,位 4 到 7 是 CINFO 压缩信息。在这种情况下,CINFO=7 表示 32K 窗口大小,CM=8 表示“deflate”压缩方法。 FLG 位 5 指示是否预设了字典,在本例中就是这样。 FLG 的详细信息也在链接 RFC 1950 中.

因此,您的输入基本上表明其余数据是使用默认压缩构建的,但 go flate 包不会对此进行解码。

更改您的解压缩以省略前 2 个字节,如下所示,它将起作用:

enflated, err := ioutil.ReadAll(flate.NewReader(bytes.NewReader(content[2:])))

Go Playground 上尝试一下。但是...

使用正确的 ZLib 解压!

这次我们很幸运,因为压缩级别是默认的,并且字典是预设的。如果没有,您将无法使用 flate 包对其进行解码。由于输入是 zlib 流,因此您应该使用 compress/zlib包正确解码它而不是依靠运气:

r, err := zlib.NewReader(bytes.NewReader(content))
if err != nil {
panic(err)
}
enflated, err := ioutil.ReadAll(r)
if err != nil {
panic(err)
}
fmt.Println(string(enflated))

尝试 Go Playground 上的 zlib 变体.

关于戈兰 : "compress/flate" module can't decompress valid deflate compressed HTTP body,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29513472/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com