From 5961165da77ad3a2abf3a77ea904c13a76b0b073 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 22 May 2017 23:30:54 +0000 Subject: [PATCH] http2: mostly test for Transport memory issue Updates golang/go#20448 Change-Id: I6366b0b0b36d81095ab347ca35e1e72169c05c15 Reviewed-on: https://go-review.googlesource.com/43853 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Tom Bergan --- http2/transport_test.go | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/http2/transport_test.go b/http2/transport_test.go index 1ffa92a7..0b4d3750 100644 --- a/http2/transport_test.go +++ b/http2/transport_test.go @@ -2915,3 +2915,58 @@ func TestAuthorityAddr(t *testing.T) { } } } + +// Issue 20448: stop allocating for DATA frames' payload after +// Response.Body.Close is called. +func TestTransportAllocationsAfterResponseBodyClose(t *testing.T) { + megabyteZero := make([]byte, 1<<20) + + writeErr := make(chan error, 1) + + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + w.(http.Flusher).Flush() + var sum int64 + for i := 0; i < 100; i++ { + n, err := w.Write(megabyteZero) + sum += int64(n) + if err != nil { + writeErr <- err + return + } + } + t.Logf("wrote all %d bytes", sum) + writeErr <- nil + }, optOnlyServer) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + res, err := c.Get(st.ts.URL) + if err != nil { + t.Fatal(err) + } + var buf [1]byte + if _, err := res.Body.Read(buf[:]); err != nil { + t.Error(err) + } + if err := res.Body.Close(); err != nil { + t.Error(err) + } + + trb, ok := res.Body.(transportResponseBody) + if !ok { + t.Fatalf("res.Body = %T; want transportResponseBody", res.Body) + } + if trb.cs.bufPipe.b != nil { + // TODO(tombergan,bradfitz): turn this into an error: + t.Logf("response body pipe is still open") + } + + gotErr := <-writeErr + if gotErr == nil { + t.Errorf("Handler unexpectedly managed to write its entire response without getting an error") + } else if gotErr != errStreamClosed { + t.Errorf("Handler Write err = %v; want errStreamClosed", gotErr) + } +}