aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/responsecontroller_test.go
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2023-03-01 15:17:35 -0800
committerDamien Neil <dneil@google.com>2023-03-07 22:52:18 +0000
commit457fd1d52d17fc8e73d4890150eadab3128de64d (patch)
tree63f4721598847e5a894b82dd1c52ba6d08d765a8 /src/net/http/responsecontroller_test.go
parent73ca5c0dace9e43330d92b751547759075d3b828 (diff)
downloadgo-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.go48
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()
+}