英文:
Gzip uncompressed http.Response.Body
问题
我正在构建一个Go应用程序,它接收一个http.Response
对象,并将其(包括响应头和正文)保存到Redis哈希中。当应用程序接收到未经gzip压缩的http.Response.Body
时,我希望在将其保存到缓存之前对其进行gzip压缩。
我的困惑源于我无法清晰地理解Go的io
接口,以及如何在http.Response.Body
的io.ReadCloser
和gzip的Writer
之间进行协调。我想象中应该有一种优雅的流式解决方案,但我无法完全使其工作。
英文:
I am building a Go application that takes an http.Response
object and saves it (response headers and body) to a redis hash. When the application receives an http.Response.Body
that is not gzipped, I want to gzip it before saving it to the cache.
My confusion stems from my inability to make clear sense of Go's io
interfaces, and how to negotiate between http.Response.Body
's io.ReadCloser
and the gzip Writer
. I imagine there is an elegant, streaming solution here, but I can't quite get it to work.
答案1
得分: 11
如果你已经确定了body是未压缩的,并且如果你需要一个[]byte
类型的压缩数据(而不是已经有一个可以写入的io.Writer
,例如如果你想将body保存到文件中,那么你需要将其流式传输到文件而不是缓冲区),那么可以使用以下代码:
func getCompressedBody(r *http.Response) ([]byte, error) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := io.Copy(gz, r.Body); err != nil {
return nil, err
}
err := gz.Close()
return buf.Bytes(), err
}
(这只是一个示例,可能会内联使用,而不是作为一个函数;如果你想将其作为一个函数,那么它应该接受一个io.Reader
而不是*http.Response
)。
英文:
If you've already determined the body is uncompressed, and if you need a []byte
of the compressed data (instead of for example already having an io.Writer
you could write to, e.g. if you wanted to save the body to a file then you'd want to stream into the file not into a buffer) then something like this should work:
func getCompressedBody(r *http.Response) ([]byte, error) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := io.Copy(gz, r.Body); err != nil {
return nil, err
}
err := gz.Close()
return buf.Bytes(), err
}
(this is just an example and would probably be in-line instead of as a function; if you wanted it as a fuction then it should probably take an io.Reader
instead of an *http.Response
).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论