diff options
Diffstat (limited to 'src/net/http/httptest/server_test.go')
-rw-r--r-- | src/net/http/httptest/server_test.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/net/http/httptest/server_test.go b/src/net/http/httptest/server_test.go index 39568b358c..5313f65456 100644 --- a/src/net/http/httptest/server_test.go +++ b/src/net/http/httptest/server_test.go @@ -9,6 +9,7 @@ import ( "io" "net" "net/http" + "sync" "testing" ) @@ -203,6 +204,59 @@ func TestServerZeroValueClose(t *testing.T) { ts.Close() // tests that it doesn't panic } +// Issue 51799: test hijacking a connection and then closing it +// concurrently with closing the server. +func TestCloseHijackedConnection(t *testing.T) { + hijacked := make(chan net.Conn) + ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer close(hijacked) + hj, ok := w.(http.Hijacker) + if !ok { + t.Fatal("failed to hijack") + } + c, _, err := hj.Hijack() + if err != nil { + t.Fatal(err) + } + hijacked <- c + })) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + req, err := http.NewRequest("GET", ts.URL, nil) + if err != nil { + t.Log(err) + } + // Use a client not associated with the Server. + var c http.Client + resp, err := c.Do(req) + if err != nil { + t.Log(err) + return + } + resp.Body.Close() + }() + + wg.Add(1) + conn := <-hijacked + go func(conn net.Conn) { + defer wg.Done() + // Close the connection and then inform the Server that + // we closed it. + conn.Close() + ts.Config.ConnState(conn, http.StateClosed) + }(conn) + + wg.Add(1) + go func() { + defer wg.Done() + ts.Close() + }() + wg.Wait() +} + func TestTLSServerWithHTTP2(t *testing.T) { modes := []struct { name string |