将POST提交到Google App Engine上的Go网络应用程序时,出现500错误。在GAE日志中,错误为:
http: invalid Read on closed Body
Web应用程序中的处理程序从*http.Request.Body
阅读器流式传输,并逐步写入http.ResponseWriter
。
Body
阅读器在完全读取之前被意外关闭。为什么会这样?
答案 0 :(得分:7)
根据设计,Go中的HTTP / 1.x服务器在*http.Request.Body
的第一次刷新后关闭http.ResponseWriter
。有关说明,请参见this GitHub issue。
目前,从理论上来说,读写是可以的-从标准的角度来看并没有明确规定-但是Go不能处理。如果代码在Body完全耗尽之前开始写到Response,则很有可能Body意外关闭。
为避免这种情况,您可以:
写入bytes.Buffer
而不是直接写入http.ResponseWriter
。在确定主体已被完全读取之后,您可以一次将缓冲区写入响应中,例如使用bytes.Buffer.WriteTo或io.Copy。这是an example。
或者,您可以在进行任何写入之前使用ioutil.ReadAll阅读整个正文。
(在以上两种情况下,内存压力可能都超出您的期望,因为传入或传出字节都是在内存中收集而不是流式传输,但这似乎是不可避免的。)
(此行为并非App Engine特有。)