gpt4 book ai didi

json - 我可以在发布之前获取 http.NewRequest 的大小吗?

转载 作者:数据小太阳 更新时间:2023-10-29 03:08:25 26 4
gpt4 key购买 nike

我们有一个接受 JSON 的 API。我们鼓励人们在发布之前对有效负载进行 gzip 压缩,因为我们对大小施加了限制。我想查看原始 JSON 和 gzip 压缩后的实际大小差异,但我似乎无法在构建后可靠准确地获取 http 请求的大小。

对于非压缩版本,MyJSON []byte 是我将其填充到 http 请求之前的原始数据,如下所示:

req, err := http.NewRequest("POST", url, bytes.NewBuffer(MyJSON))

对于 gzip 版本,我将数据压缩到缓冲区中,然后像这样将其添加到 http 请求中:

req, err := http.NewRequest("POST", url, &buffer)

是否可以获取http请求的大小?如果没有,我应该能够使用 len() 获取原始 MyJSON []byte 的大小,但我似乎无法获取bytes.Buffer 用于压缩版本。

最佳答案

一句话:没有。

这是因为 http.Request 对象的主体是一个 io.Reader,它可以有任何大小,并且是知道 大小的唯一方法>io.Reader 就是全部读完,然后计数。在实践中,io.Reader 甚至在数据已经传输之后才被使用。

这对您的应用程序意味着您有两个选择:

  1. 您可以先读取整个正文,然后将其缓冲(在内存或磁盘上),计算其大小,然后发送。
  2. 在通过网络发送请求后,您可以找到计算(或估计)大小的方法。

后者会更有效率,但意味着您无法在发送请求之前主动对数据采取行动。如果您选择第二种方法,您可以编写一个自定义 io.Reader 来计算读取的字节数,并将其传递给您的 NewRequest() 调用。


另请注意:将 JSON 放在字节 slice ([]byte) 中这一事实有点代码味道。这在某些情况下可能是合适的,但大多数时候,将 JSON 直接流式传输到 HTTP 请求更有效(就内存和时间而言)。示例:

var someBigHairyObject = /* Perhaps a struct or map */
r, w := io.Pipe()
go func() {
err := json.NewEncoder(w).Encode(someBigHairyObject)
w.CloseWithError(err)
}()
req, _ := http.NewRequest("POST", "http://example.com/", r)

通过这种方式,JSON 编码(marshal)处理(您也可以在此处包括 gzip)“直接”完成到网络,没有使用内存并推迟您的请求的中间缓冲区。

关于json - 我可以在发布之前获取 http.NewRequest 的大小吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57004716/

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