diff options
| author | Damien Neil <dneil@google.com> | 2023-03-01 15:17:35 -0800 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2023-03-07 22:52:18 +0000 |
| commit | 457fd1d52d17fc8e73d4890150eadab3128de64d (patch) | |
| tree | 63f4721598847e5a894b82dd1c52ba6d08d765a8 /src/net/http/responsecontroller_test.go | |
| parent | 73ca5c0dace9e43330d92b751547759075d3b828 (diff) | |
| download | go-457fd1d52d17fc8e73d4890150eadab3128de64d.tar.xz | |
net/http: support full-duplex HTTP/1 responses
Add support for concurrently reading from an HTTP/1 request body
while writing the response.
Normally, the HTTP/1 server automatically consumes any remaining
request body before starting to write a response, to avoid deadlocking
clients which attempt to write a complete request before reading the
response.
Add a ResponseController.EnableFullDuplex method which disables this
behavior.
For #15527
For #57786
Change-Id: Ie7ee8267d8333e9b32b82b9b84d4ad28ab8edf01
Reviewed-on: https://go-review.googlesource.com/c/go/+/472636
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Diffstat (limited to 'src/net/http/responsecontroller_test.go')
| -rw-r--r-- | src/net/http/responsecontroller_test.go | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/net/http/responsecontroller_test.go b/src/net/http/responsecontroller_test.go index 0dca7332b7..ee8b55a89f 100644 --- a/src/net/http/responsecontroller_test.go +++ b/src/net/http/responsecontroller_test.go @@ -263,3 +263,51 @@ func testWrappedResponseController(t *testing.T, mode testMode) { io.Copy(io.Discard, res.Body) defer res.Body.Close() } + +func TestResponseControllerEnableFullDuplex(t *testing.T) { + run(t, testResponseControllerEnableFullDuplex) +} +func testResponseControllerEnableFullDuplex(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, req *Request) { + ctl := NewResponseController(w) + if err := ctl.EnableFullDuplex(); err != nil { + // TODO: Drop test for HTTP/2 when x/net is updated to support + // EnableFullDuplex. Since HTTP/2 supports full duplex by default, + // the rest of the test is fine; it's just the EnableFullDuplex call + // that fails. + if mode != http2Mode { + t.Errorf("ctl.EnableFullDuplex() = %v, want nil", err) + } + } + w.WriteHeader(200) + ctl.Flush() + for { + var buf [1]byte + n, err := req.Body.Read(buf[:]) + if n != 1 || err != nil { + break + } + w.Write(buf[:]) + ctl.Flush() + } + })) + 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() + for i := byte(0); i < 10; i++ { + if _, err := pw.Write([]byte{i}); err != nil { + t.Fatalf("Write: %v", err) + } + var buf [1]byte + if n, err := res.Body.Read(buf[:]); n != 1 || err != nil { + t.Fatalf("Read: %v, %v", n, err) + } + if buf[0] != i { + t.Fatalf("read byte %v, want %v", buf[0], i) + } + } + pw.Close() +} |
