为了账号安全,请及时绑定邮箱和手机立即绑定

如何保留 HTTP 正文的 gzip 表示

如何保留 HTTP 正文的 gzip 表示

Go
慕妹3242003 2023-08-07 10:51:13
在 go web 应用程序的上下文中,我使用响应缓存并压缩它们,因此我节省了带宽(响应更大)。我正在使用框架和压缩gin-gonic包。gzip这个包工作得很好,可以满足我接收和回复 gzip 压缩正文所需的一切。这几行就足够了:router := gin.Default() router.Use(gzip.Gzip(gzip.DefaultCompression))一切都是魔法。现在,我还使用存储响应的缓存。为了节省空间和CPU,我想将已经压缩的响应存储在缓存中,所以我也不重复压缩。作为包装 HTTP 正文处理的中间件,gzip透明地解压缩请求并压缩响应。然而,在我的处理程序级别,我希望获得响应的压缩表示,以便我可以将其存储到我的缓存中。另外,我需要告诉大家gzip我的身体已经被压缩了。我已经进行了一些搜索,寻找一种使用gzip包或任何其他方式的自动化方式,这可以防止我干预某些库、HTTP 堆栈中的执行路径,或者最糟糕的是,为自己编写其他库(例如gzip.有人知道gzip包如何解决这个问题吗?
查看完整描述

1 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

首先,我继续使用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 标头来告诉响应已被压缩。


八个月以来,它已经在五个不同的 API 上进行了测试。


我希望它对其他人有用,就像对我有用一样。


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信