1
0
mirror of https://github.com/golang/go synced 2024-11-16 16:54:39 -07:00

net/http: add tests with zero and negative read/write timeouts

Change-Id: I38ebd280c200b30692eb35640327034a5e898bd0
Reviewed-on: https://go-review.googlesource.com/c/go/+/570376
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Andy Pan 2024-03-10 23:08:31 +08:00 committed by Gopher Robot
parent 36cd880878
commit dc0527ee7d

View File

@ -792,6 +792,51 @@ func testServerReadTimeout(t *testing.T, mode testMode) {
} }
} }
func TestServerNoReadTimeout(t *testing.T) { run(t, testServerNoReadTimeout) }
func testServerNoReadTimeout(t *testing.T, mode testMode) {
reqBody := "Hello, Gophers!"
resBody := "Hi, Gophers!"
for _, timeout := range []time.Duration{0, -1} {
cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
ctl := NewResponseController(res)
ctl.EnableFullDuplex()
res.WriteHeader(StatusOK)
// Flush the headers before processing the request body
// to unblock the client from the RoundTrip.
if err := ctl.Flush(); err != nil {
t.Errorf("server flush response: %v", err)
return
}
got, err := io.ReadAll(req.Body)
if string(got) != reqBody || err != nil {
t.Errorf("server read request body: %v; got %q, want %q", err, got, reqBody)
}
res.Write([]byte(resBody))
}), func(ts *httptest.Server) {
ts.Config.ReadTimeout = timeout
ts.Config.IdleTimeout = 10 * time.Millisecond
t.Logf("Server.Config.ReadTimeout = %d", timeout)
})
pr, pw := io.Pipe()
res, err := cst.c.Post(cst.ts.URL, "text/plain", pr)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
// TODO(panjf2000): sleep is not so robust, maybe find a better way to test this?
time.Sleep(10 * time.Millisecond) // stall sending body to server to test server doesn't time out
pw.Write([]byte(reqBody))
pw.Close()
got, err := io.ReadAll(res.Body)
if string(got) != resBody || err != nil {
t.Errorf("client read response body: %v; got %v, want %q", err, got, resBody)
}
}
}
func TestServerWriteTimeout(t *testing.T) { run(t, testServerWriteTimeout) } func TestServerWriteTimeout(t *testing.T) { run(t, testServerWriteTimeout) }
func testServerWriteTimeout(t *testing.T, mode testMode) { func testServerWriteTimeout(t *testing.T, mode testMode) {
for timeout := 5 * time.Millisecond; ; timeout *= 2 { for timeout := 5 * time.Millisecond; ; timeout *= 2 {
@ -857,6 +902,29 @@ func testServerWriteTimeout(t *testing.T, mode testMode) {
} }
} }
func TestServerNoWriteTimeout(t *testing.T) { run(t, testServerNoWriteTimeout) }
func testServerNoWriteTimeout(t *testing.T, mode testMode) {
for _, timeout := range []time.Duration{0, -1} {
cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
_, err := io.Copy(res, neverEnding('a'))
t.Logf("server write response: %v", err)
}), func(ts *httptest.Server) {
ts.Config.WriteTimeout = timeout
t.Logf("Server.Config.WriteTimeout = %d", timeout)
})
res, err := cst.c.Get(cst.ts.URL)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
n, err := io.CopyN(io.Discard, res.Body, 1<<20) // 1MB should be sufficient to prove the point
if n != 1<<20 || err != nil {
t.Errorf("client read response body: %d, %v", n, err)
}
}
}
// Test that the HTTP/2 server handles Server.WriteTimeout (Issue 18437) // Test that the HTTP/2 server handles Server.WriteTimeout (Issue 18437)
func TestWriteDeadlineExtendedOnNewRequest(t *testing.T) { func TestWriteDeadlineExtendedOnNewRequest(t *testing.T) {
run(t, testWriteDeadlineExtendedOnNewRequest) run(t, testWriteDeadlineExtendedOnNewRequest)