0

在 Google App Engine 上向 Go 网络应用程序提交 POST 时,我收到 500 错误。在 GAE 日志中,错误是:

http: invalid Read on closed Body

Web 应用程序中的处理程序从*http.Request.Body阅读器流式传输,并逐渐写入http.ResponseWriter.

阅读器Body在被完全阅读之前被意外关闭。为什么会发生这种情况?

4

1 回答 1

8

按照设计,Go 中的 HTTP/1.x 服务器在*http.Request.Body第一次刷新http.ResponseWriter. 有关说明,请参阅此 GitHub 问题

并发读写在理论上是好的——从标准的角度来看它是未指定的——但 Go 不处理它。如果代码在 Body 完全消耗之前开始写入 Response,那么 Body 很可能会意外关闭。

为避免这种情况,您可以:

  • 写入 abytes.Buffer而不是直接写入http.ResponseWriter。在您确定 Body 被完全读取后,您可以一次将缓冲区全部写入响应,例如使用bytes.Buffer.WriteToio.Copy。这是一个例子

  • 或者,您可以在任何写入之前使用ioutil.ReadAll读取整个正文。

(在上述两种情况下,内存压力可能比您希望的要大,因为传入或传出的字节都收集在内存中而不是流式传输,但这似乎是不可避免的。)

(此行为并非 App Engine 独有。)

于 2018-11-02T00:15:09.827 回答