http.ResponseWriter.WriteHeader()导致死锁

时间:2017-12-21 10:47:46

标签: http testing go

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

httptest

在此代码示例中,我尝试多次打开和关闭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) } 服务器。不知怎的,它在The Go Playground引起了僵局。我尝试了自己的环境(Go版本:go1.7.4 darwin / amd64),它导致挂起而没有响应。

我的问题是:为什么httptest导致死锁但w.WriteHeader(100)没有?是来自Golang核心库的错误还是我误解了一些用法? TKS!

1 个答案:

答案 0 :(得分:0)

如果您稍微修改代码:

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协议,所以我收到错误:

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