func TestResponseControllerFlush(t *testing.T) { run(t, testResponseControllerFlush) }
func testResponseControllerFlush(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
continuec := make(chan struct{})
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
ctl := NewResponseController(w)
func TestResponseControllerHijack(t *testing.T) { run(t, testResponseControllerHijack) }
func testResponseControllerHijack(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
const header = "X-Header"
const value = "set"
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
run(t, testResponseControllerSetPastWriteDeadline)
}
func testResponseControllerSetPastWriteDeadline(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
ctl := NewResponseController(w)
w.Write([]byte("one"))
if err := ctl.Flush(); err != nil {
t.Errorf("before setting deadline: ctl.Flush() = %v, want nil", err)
}
- if err := ctl.SetWriteDeadline(time.Now()); err != nil {
+ if err := ctl.SetWriteDeadline(time.Now().Add(-10 * time.Second)); err != nil {
t.Errorf("ctl.SetWriteDeadline() = %v, want nil", err)
}
run(t, testResponseControllerSetFutureWriteDeadline)
}
func testResponseControllerSetFutureWriteDeadline(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
errc := make(chan error, 1)
startwritec := make(chan struct{})
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
run(t, testResponseControllerSetPastReadDeadline)
}
func testResponseControllerSetPastReadDeadline(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
readc := make(chan struct{})
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
ctl := NewResponseController(w)
run(t, testResponseControllerSetFutureReadDeadline)
}
func testResponseControllerSetFutureReadDeadline(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
respBody := "response body"
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, req *Request) {
ctl := NewResponseController(w)
func TestWrappedResponseController(t *testing.T) { run(t, testWrappedResponseController) }
func testWrappedResponseController(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("skip until h2_bundle.go is updated")
- }
cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
ctl := NewResponseController(w)
if err := ctl.Flush(); err != nil {
func TestServerReadTimeout(t *testing.T) { run(t, testServerReadTimeout) }
func testServerReadTimeout(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("https://go.dev/issue/49837")
- }
respBody := "response body"
- cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
- _, err := io.Copy(io.Discard, req.Body)
- if !errors.Is(err, os.ErrDeadlineExceeded) {
- t.Errorf("server timed out reading request body: got err %v; want os.ErrDeadlineExceeded", err)
+ for timeout := 5 * time.Millisecond; ; timeout *= 2 {
+ cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
+ _, err := io.Copy(io.Discard, req.Body)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Errorf("server timed out reading request body: got err %v; want os.ErrDeadlineExceeded", err)
+ }
+ res.Write([]byte(respBody))
+ }), func(ts *httptest.Server) {
+ ts.Config.ReadHeaderTimeout = -1 // don't time out while reading headers
+ ts.Config.ReadTimeout = timeout
+ })
+ pr, pw := io.Pipe()
+ res, err := cst.c.Post(cst.ts.URL, "text/apocryphal", pr)
+ if err != nil {
+ t.Logf("Get error, retrying: %v", err)
+ cst.close()
+ continue
}
- res.Write([]byte(respBody))
- }), func(ts *httptest.Server) {
- ts.Config.ReadTimeout = 5 * time.Millisecond
- })
- pr, pw := io.Pipe()
- res, err := cst.c.Post(cst.ts.URL, "text/apocryphal", pr)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- got, err := io.ReadAll(res.Body)
- if string(got) != respBody || err != nil {
- t.Errorf("client read response body: %q, %v; want %q, nil", string(got), err, respBody)
+ defer res.Body.Close()
+ got, err := io.ReadAll(res.Body)
+ if string(got) != respBody || err != nil {
+ t.Errorf("client read response body: %q, %v; want %q, nil", string(got), err, respBody)
+ }
+ pw.Close()
+ break
}
- pw.Close()
}
func TestServerWriteTimeout(t *testing.T) { run(t, testServerWriteTimeout) }
func testServerWriteTimeout(t *testing.T, mode testMode) {
- if mode == http2Mode {
- t.Skip("https://go.dev/issue/56478")
- }
for timeout := 5 * time.Millisecond; ; timeout *= 2 {
errc := make(chan error, 2)
cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
if err == nil {
t.Errorf("client reading from truncated request body: got nil error, want non-nil")
}
- cst.close()
select {
case <-errc:
err = <-errc // io.Copy error
default:
// The write timeout expired before the handler started.
t.Logf("handler didn't run, retrying")
+ cst.close()
}
}
}
if !p.rDeadline.IsZero() {
d := time.Until(p.rDeadline)
if d <= 0 {
- return 0, syscall.EAGAIN
+ return 0, os.ErrDeadlineExceeded
}
time.AfterFunc(d, p.rCond.Broadcast)
}
if !p.wDeadline.IsZero() {
d := time.Until(p.wDeadline)
if d <= 0 {
- return 0, syscall.EAGAIN
+ return 0, os.ErrDeadlineExceeded
}
time.AfterFunc(d, p.wCond.Broadcast)
}