【问题标题】:How to read gzipped data from http response in Golang如何从 Golang 中的 http 响应中读取压缩后的数据
【发布时间】:2019-07-15 18:34:30
【问题描述】:

我有一个经过 gzip 压缩的 http 响应。

resp, err := client.Do(req)
    if err != nil {
        return "", err
    }

    defer resp.Body.Close()

    if resp.StatusCode == http.StatusOK {
        var buf bytes.Buffer


    }

如何解压缩并将其解析到我的结构中?

我看到一个这样的问题: Reading gzipped HTTP response in Go

但它会将响应输出到标准输出中。该示例也遇到了错误,

reader, err = gzip.NewReader(response.Body)

将错误返回为“EOF”。我该如何调试?

【问题讨论】:

  • EOF 表示没有响应体,或者它太短而不能成为 gzip 流。是什么让你认为你有一个压缩的反应?是什么让您认为 Go 不会自动处理它?你如何构造请求和客户端?
  • 嗨 @Peter 感谢您的回复,我阅读了 api 文档,其中说响应已压缩。

标签: go


【解决方案1】:

Golang 默认会自动解码压缩响应的正文。所以实际上你只需要阅读响应正文就足够了,之后不需要做任何事情。

以下是来自https://golang.org/pkg/net/http/#Transport的解释:

... 如果 Transport 自己请求 gzip 并获得一个 gzip 响应,它会在 Response.Body 中透明地解码。 但是,如果用户明确请求 gzip,它不会自动解压缩。

因此,如果您收到EOF 错误,问题可能不是因为 gzip 编码的东西,而可能是因为响应正文中实际上没有数据。

顺便说一句,您可以通过检查Content-Encoding 响应标头来检查响应是否被压缩。

【讨论】:

  • 感谢您的信息,我确实检查了我的服务提供商的文档,响应是用 gzip 编码的。
【解决方案2】:

我通过阅读以下代码解决了这个问题: https://gist.github.com/xyproto/f4915d7e208771f3adc4

这是帮助我的代码。

// Write gunzipped data to a Writer
func gunzipWrite(w io.Writer, data []byte) error {
    // Write gzipped data to the client
    gr, err := gzip.NewReader(bytes.NewBuffer(data))
    defer gr.Close()
    data, err = ioutil.ReadAll(gr)
    if err != nil {
        return err
    }
    w.Write(data)
    return nil
}

【讨论】:

  • io.Copy 通常比 ReadAll 然后 Write 更有效。
猜你喜欢
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
相关资源
最近更新 更多