为什么golang中的响应体是readCloser?

sam*_*eri 1 http go

我想知道 golang 中的 http 包是如何工作的。我可以看到http响应的正文是这样的:

type Response struct {
    StatusCode int
    Header     Header
    Body       io.ReadCloser
}
Run Code Online (Sandbox Code Playgroud)

Body是一个 ReadCloser。这是为什么?

主要问题是: http 包是否同时完整地读取 header 和 body 然后返回,Response或者它只读取Header部分,当我们读取时,Body我们实际上是从连接读取?我们是否有可能在完成整个正文之前遇到错误(例如因为连接断开)?或者当我们收到响应时,正文已完全接收并驻留在内存中?

Vol*_*ker 6

正文是一个 ReadCloser。这是为什么?

因为您可以从中读取内容,并且完成后必须关闭它。

主要问题是:http包是否同时完整地读取header和body,然后返回Response[?]

不。

或者它只是读取标题部分,而当我们从正文中读取时,我们实际上是从连接中读取?

是的

我们是否有可能在完成整个正文之前遇到错误(例如因为连接断开)?

是的。

或者当我们收到响应时,正文已完全接收并驻留在内存中?

不。想想 4.5 TByte 的流。

  • @samadmontazeri,...添加到`net/http`包透明地处理其客户端和服务器之间的任何所谓的“传输编码”(对客户端完全透明),并且还可以透明地处理内容编码,如果它不是由客户端明确控制的。换句话说,您最好 1) 详细了解 HTTP 的工作原理;2)通过阅读“net/http”包的源代码来扩充这些知识。 (4认同)
  • @samadmontazeri,“分块”,而不是“分块”。好吧,您可以从[这里](https://datatracker.ietf.org/doc/html/rfc7230)开始——实际上很容易理解。您可能会感兴趣的另一点是:在我的 $dayjob 中,我们使用连续的 HTTP 响应(长度未知的响应)在客户端之间传输实时数据。在这种情况下,不存在“完全读取请求正文”的概念,因为只要服务器和客户端启动并连接,就会读取它。 (4认同)
  • @samadmontazeri,还请注意,正文读取器的实现很复杂——虽然 Volker 的说法是正确的,“net/http.Response.Body”的实现“从套接字读取”,但它不是直接完成的——有几个软件层层发挥作用。另请注意,实际读取代码取决于所使用的 HTTP 协议版本(HTTP2 与 HTTP 1.x 有很大不同),甚至 HTTP 1.x 中的“固定长度”响应与使用特殊主体的“连续”响应之间也有所不同称为“分块”的编码... (3认同)
  • @samadmontazeri,我不太同意您对这些附加信息的要求。文档修复了行为,而不是实现。实现位于源代码中(可以免费获得——就在 Go 安装的 src 目录中),甚至在 Go 的不同版本之间也可能以任何方式发生变化。`net/http` 包的源代码位于 `src/net/http` 中。 (2认同)