如何保持 HTTP 的 gzip 表示 body
How to keep the gzip representation of HTTP body
在 go web 应用程序的上下文中,我使用响应缓存并压缩它们,因此我节省了带宽(响应更大)。我正在使用 gin-gonic
框架和包 gzip
进行压缩。这个包工作得很好,可以满足我接收和回复 gzip-compressed 正文所需的一切。这两行就足够了:
router := gin.Default()
router.Use(gzip.Gzip(gzip.DefaultCompression))
一切都是神奇的。现在,我还使用了一个存储响应的缓存。为了保存 space 和 CPU,我想将已经压缩的响应存储在缓存中,所以我也不会重复压缩。作为包装 HTTP body 处理的中间件,gzip
透明地解压缩请求并压缩响应。但是,在我的处理程序级别,我想获得我的响应的压缩表示,以便我可以将其存储到我的缓存中。另外,我需要告诉 gzip
我的 body 已经压缩了。
我已经搜索了一些使用 gzip
包或任何其他包的自动化方式,这阻止了我干预某些库、HTTP 堆栈中的执行路径,或者更糟糕的是,我自己编写一些东西已经由另一个库制作,例如 gzip
.
有人body知道gzip
包如何解决这个问题吗?
首先,我继续使用 gzip
和 gin
软件包。
现在,我用类似这样的函数压缩我的回复:
func compress(response interface{}) ([]byte, error) {
body, err := json.Marshal(response)
if err != nil {
return nil, err
}
var buffer bytes.Buffer
zw := gzip.NewWriter(&buffer)
_, err = zw.Write(body)
closeErr := zw.Close()
if err != nil {
return nil, err
}
if closeErr != nil {
return nil, err
}
return buffer.Bytes(), nil
}
当我需要响应请求时,我会执行这样的操作:
gzipOutput, err := compressResponse(output)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.Writer.Header().Set("Accept-Encoding", "gzip")
c.Writer.Header().Set("Content-Encoding", "gzip")
c.Writer.Header().Set("Content-Type", "application/json")
c.Data(http.StatusOK, "gzip", gzipOutput)
正如我们所见,这个想法是告诉 gin
通过设置 HTML header.
来压缩响应
八个月以来,它已经在五个不同的 API 上进行了测试。
我希望它对其他人有用,就像对我一样。
在 go web 应用程序的上下文中,我使用响应缓存并压缩它们,因此我节省了带宽(响应更大)。我正在使用 gin-gonic
框架和包 gzip
进行压缩。这个包工作得很好,可以满足我接收和回复 gzip-compressed 正文所需的一切。这两行就足够了:
router := gin.Default()
router.Use(gzip.Gzip(gzip.DefaultCompression))
一切都是神奇的。现在,我还使用了一个存储响应的缓存。为了保存 space 和 CPU,我想将已经压缩的响应存储在缓存中,所以我也不会重复压缩。作为包装 HTTP body 处理的中间件,gzip
透明地解压缩请求并压缩响应。但是,在我的处理程序级别,我想获得我的响应的压缩表示,以便我可以将其存储到我的缓存中。另外,我需要告诉 gzip
我的 body 已经压缩了。
我已经搜索了一些使用 gzip
包或任何其他包的自动化方式,这阻止了我干预某些库、HTTP 堆栈中的执行路径,或者更糟糕的是,我自己编写一些东西已经由另一个库制作,例如 gzip
.
有人body知道gzip
包如何解决这个问题吗?
首先,我继续使用 gzip
和 gin
软件包。
现在,我用类似这样的函数压缩我的回复:
func compress(response interface{}) ([]byte, error) {
body, err := json.Marshal(response)
if err != nil {
return nil, err
}
var buffer bytes.Buffer
zw := gzip.NewWriter(&buffer)
_, err = zw.Write(body)
closeErr := zw.Close()
if err != nil {
return nil, err
}
if closeErr != nil {
return nil, err
}
return buffer.Bytes(), nil
}
当我需要响应请求时,我会执行这样的操作:
gzipOutput, err := compressResponse(output)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.Writer.Header().Set("Accept-Encoding", "gzip")
c.Writer.Header().Set("Content-Encoding", "gzip")
c.Writer.Header().Set("Content-Type", "application/json")
c.Data(http.StatusOK, "gzip", gzipOutput)
正如我们所见,这个想法是告诉 gin
通过设置 HTML header.
八个月以来,它已经在五个不同的 API 上进行了测试。
我希望它对其他人有用,就像对我一样。