登录
首页 >  Golang >  Go问答

我是否可以在发送 POST 请求之前获取 http.NewRequest 的大小?

来源:stackoverflow

时间:2024-03-24 17:33:32 233浏览 收藏

在向服务器发送 POST 请求之前,无法准确获取 HTTP 请求的大小。这是因为请求主体是一个 io.Reader,它可以在传输过程中任意增长,并且只有在数据传输后才能确定其大小。因此,应用程序有两种选择:先读取并缓冲整个请求正文,或使用自定义 io.Reader 来计算传输的字节数。

问题内容

我们有一个接受 json 的 api。我们鼓励人们在 post 之前对其进行 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 位于字节切片 ([]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 封送处理(您也可以在此处包含 gzip)“直接”在网络上完成,无需使用内存并推迟您的请求的中间缓冲区。

本篇关于《我是否可以在发送 POST 请求之前获取 http.NewRequest 的大小?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>