Skip to content

Commit

Permalink
[release-branch.go1.14] http2: send a nil error if we cancel a delaye…
Browse files Browse the repository at this point in the history
…d body write

Once a request body is scheduled to be written, a result of the write is always
expected. If the body writer is cancelled, and the write was never started,
send a successful result.

The test included is a modified version of the TestNoSniffExpectRequestBody_h2 found
in net/http.

Updates golang/go#42586

Change-Id: If3f23993170bdf10e9ae4244ec13ae269bd3877a
Reviewed-on: https://go-review.googlesource.com/c/net/+/269058
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 5d6afe9)
Reviewed-on: https://go-review.googlesource.com/c/net/+/288114
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
  • Loading branch information
fraenkel authored and dmitshur committed Jan 29, 2021
1 parent 9c81719 commit 4acb789
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
4 changes: 3 additions & 1 deletion http2/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -2560,7 +2560,9 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body

func (s bodyWriterState) cancel() {
if s.timer != nil {
s.timer.Stop()
if s.timer.Stop() {
s.resc <- nil
}
}
}

Expand Down
36 changes: 36 additions & 0 deletions http2/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4628,3 +4628,39 @@ func TestTransportBodyRewindRace(t *testing.T) {

wg.Wait()
}

// Issue 42498: A request with a body will never be sent if the stream is
// reset prior to sending any data.
func TestTransportServerResetStreamAtHeaders(t *testing.T) {
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusUnauthorized)
return
}, optOnlyServer)
defer st.Close()

tr := &http.Transport{
TLSClientConfig: tlsConfigInsecure,
MaxConnsPerHost: 1,
ExpectContinueTimeout: 10 * time.Second,
}

err := ConfigureTransport(tr)
if err != nil {
t.Fatal(err)
}
client := &http.Client{
Transport: tr,
}

req, err := http.NewRequest("POST", st.ts.URL, errorReader{io.EOF})
if err != nil {
t.Fatalf("unexpect new request error: %v", err)
}
req.ContentLength = 0 // so transport is tempted to sniff it
req.Header.Set("Expect", "100-continue")
res, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
res.Body.Close()
}

0 comments on commit 4acb789

Please sign in to comment.