gpt4 book ai didi

http.ResponseWriter.WriteHeader() 导致死锁

转载 作者:IT王子 更新时间:2023-10-29 02:21:23 27 4
gpt4 key购买 nike

我试图在 golang 中使用 httptest 包。我发现了一些我不明白的东西。这是 code :

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)

func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello1"))
}))
ts.Close()
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello2"))
}))
ts.Close()
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(100)
w.Write([]byte("Hello3"))
}))

res, err := http.Get(ts.URL)
if err != nil {
log.Fatal(err)
}
greeting, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}

ts.Close()
fmt.Printf("%s", greeting)
}

在此代码示例中,我多次尝试打开和关闭 httptest 服务器。它以某种方式在 The Go Playground 中造成了僵局。我在自己的环境(Go版本:go1.7.4 darwin/amd64)上试了一下,导致挂了,一点 react 都没有。

我的问题是:为什么 w.WriteHeader(100) 导致了死锁,而 w.WriteHeader(200) 却没有?是 Golang 核心库的错误还是我误解了一些用法?谢谢!

最佳答案

如果稍微修改一下代码:

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)

func main() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello1"))
}))
ts.Close()
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello2"))
}))
ts.Close()
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(100)
w.Write([]byte("Hello3"))
}))

fmt.Println("before get") ///// . <----
res, err := http.Get(ts.URL)
fmt.Println("after get") ///// . <----
if err != nil {
log.Fatal(err)
}
greeting, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}

ts.Close()
fmt.Printf("%s", greeting)
}

然后运行它 - 你只会看到第一行。

这意味着 Go http 客户端需要您提供更多数据。所以就挂线上了

    res, err := http.Get(ts.URL)

并且无法到达下面的 ts.Close()

下一步 - 让我们修改一个测试,它会关闭一个连接,并以此方式释放一个客户端等待锁:

ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(100)
w.Write([]byte("Hello3"))
hj, _ := w.(http.Hijacker)
conn, _, _ := hj.Hijack()
conn.Close()
}))

我明确地关闭了连接,但是这样你就可以同时获得检查字符串和测试完成。试试吧。

当然这是违反 HTTP 协议(protocol)的,所以我得到一个错误:

Get http://127.0.0.1:54243: net/http: HTTP/1.x transport connection broken: unexpected EOF

关于http.ResponseWriter.WriteHeader() 导致死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47923284/

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