gpt4 book ai didi

http - 写入响应正文等待客户端在 Go 中读取?

转载 作者:IT王子 更新时间:2023-10-29 01:43:00 27 4
gpt4 key购买 nike

我正在使用 Go 中的 httptest 包来测试我的应用程序。最近我注意到我的一个测试未能完成,因为我的测试没有读取响应的主体

func Test_AnyTest(t *testing.T) {
serve := newServer()
s := httptest.NewServer(serve)
defer s.Close()

testUrl := "/any/old/url"

c := &http.Client{}
r, _ := http.NewRequest("GET", s.URL+testUrl, new(bytes.Buffer))
r.Header.Add("If-None-Match", cacheVersion)
res, _ := c.Do(r)

if res.StatusCode == 304 {
t.Errorf("Should not have got 304")
}
}

上面的代码阻塞了对 s.Close() 的延迟调用,因为测试服务器上有未完成的 http 连接。我的服务器有一些代码正在写入正文(使用 http.ResponseWriter 接口(interface))。事实证明这段代码实际上是阻塞的,直到我在测试中读取正文。

这样的调用就成功了。

ioutil.ReadAll(res.Body)

我不介意在我的测试中进行此调用,但我担心行为不当的客户端可能会导致此行为并消耗服务器资源。有谁知道这里发生了什么?这是正常情况下的预期行为还是只是测试框架的问题?

谢谢!

最佳答案

来自 http 文档:

The client must close the response body when finished with it:


resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

所以你的测试违反了http.Client的约定;添加 defer res.Close() 应该让服务器知道响应 channel 已关闭,并停止写入。您的 ioutil.ReadAll 的效果是相同的,因为它会在到达 EOF 时关闭 Reader

在野外,如果客户端打开连接并发送请求,服务器只发送响应然后关闭连接。它不会等待客户端关闭它。如果客户端太慢而无法确认服务器发送的 IP 数据包,操作系统最终会处理连接超时,http.Server 将通过退出为请求提供服务的 goroutine 来响应,没有小猫受到伤害。

关于http - 写入响应正文等待客户端在 Go 中读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26981344/

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