From: Damien Neil Date: Mon, 8 Apr 2024 18:43:03 +0000 (-0700) Subject: net/http: update HandlerWritesTooMuch test to allow different h1/h2 behavior X-Git-Tag: go1.23rc1~669 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=50a5059056e2233c5112e1dbb65c19bfc79ebb5d;p=gostls13.git net/http: update HandlerWritesTooMuch test to allow different h1/h2 behavior Rather than requiring that HTTP/1 and HTTP/2 servers behave identically when a misbehaving handler writes too many bytes, check only that both behave reasonably. In particular, allow the handler to defer detection of a write overrun until flush time, and permit the HTTP/2 handler to reset the stream rather than requring it to return a truncated body as HTTP/1 must. For #56019 Change-Id: I0838e550c4fc202dcbb8bf39ce0fa4a367ca7e71 Reviewed-on: https://go-review.googlesource.com/c/go/+/577415 LUCI-TryBot-Result: Go LUCI Reviewed-by: Jonathan Amsterdam --- diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go index 32948f3aed..1fe4eed3f7 100644 --- a/src/net/http/clientserver_test.go +++ b/src/net/http/clientserver_test.go @@ -510,19 +510,35 @@ func TestH12_HandlerWritesTooLittle(t *testing.T) { // doesn't make it possible to send bogus data. For those tests, see // transport_test.go (for HTTP/1) or x/net/http2/transport_test.go // (for HTTP/2). -func TestH12_HandlerWritesTooMuch(t *testing.T) { - h12Compare{ - Handler: func(w ResponseWriter, r *Request) { - w.Header().Set("Content-Length", "3") - w.(Flusher).Flush() - io.WriteString(w, "123") - w.(Flusher).Flush() - n, err := io.WriteString(w, "x") // too many - if n > 0 || err == nil { - t.Errorf("for proto %q, final write = %v, %v; want 0, some error", r.Proto, n, err) - } - }, - }.run(t) +func TestHandlerWritesTooMuch(t *testing.T) { run(t, testHandlerWritesTooMuch) } +func testHandlerWritesTooMuch(t *testing.T, mode testMode) { + wantBody := []byte("123") + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { + rc := NewResponseController(w) + w.Header().Set("Content-Length", fmt.Sprintf("%v", len(wantBody))) + rc.Flush() + w.Write(wantBody) + rc.Flush() + n, err := io.WriteString(w, "x") // too many + if err == nil { + err = rc.Flush() + } + // TODO: Check that this is ErrContentLength, not just any error. + if err == nil { + t.Errorf("for proto %q, final write = %v, %v; want _, some error", r.Proto, n, err) + } + })) + + res, err := cst.c.Get(cst.ts.URL) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + + gotBody, _ := io.ReadAll(res.Body) + if !bytes.Equal(gotBody, wantBody) { + t.Fatalf("got response body: %q; want %q", gotBody, wantBody) + } } // Verify that both our HTTP/1 and HTTP/2 request and auto-decompress gzip.