aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/httptest/server_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http/httptest/server_test.go')
-rw-r--r--src/net/http/httptest/server_test.go54
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