mirror of
https://github.com/golang/net.git
synced 2026-04-01 02:47:08 +09:00
http2: ignore read errors after closing the request body
We close the request body after receiving an error status code. This is supposed to cause cs.writeRequestBody to return errStopReqBodyWrite. Ensure that it does so if it gets an error reading from the post-close body, rather than returning an error which causes the entire request to be aborted. Change-Id: I7c51928cb678f5baf37148f0df6ab196518d39d4 Reviewed-on: https://go-review.googlesource.com/c/net/+/356969 Trust: Damien Neil <dneil@google.com> Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
@@ -1539,11 +1539,19 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
sawEOF = true
|
||||
err = nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
if err != nil {
|
||||
cc.mu.Lock()
|
||||
bodyClosed := cs.reqBodyClosed
|
||||
cc.mu.Unlock()
|
||||
switch {
|
||||
case bodyClosed:
|
||||
return errStopReqBodyWrite
|
||||
case err == io.EOF:
|
||||
sawEOF = true
|
||||
err = nil
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
remain := buf[:n]
|
||||
|
||||
@@ -5701,3 +5701,38 @@ func TestTransportCloseResponseBodyWhileRequestBodyHangs(t *testing.T) {
|
||||
res.Body.Close()
|
||||
pw.Close()
|
||||
}
|
||||
|
||||
func TestTransport300ResponseBody(t *testing.T) {
|
||||
reqc := make(chan struct{})
|
||||
body := []byte("response body")
|
||||
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(300)
|
||||
w.(http.Flusher).Flush()
|
||||
<-reqc
|
||||
w.Write(body)
|
||||
}, optOnlyServer)
|
||||
defer st.Close()
|
||||
|
||||
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
|
||||
defer tr.CloseIdleConnections()
|
||||
|
||||
pr, pw := net.Pipe()
|
||||
req, err := http.NewRequest("GET", st.ts.URL, pr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := tr.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
close(reqc)
|
||||
got, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("error reading response body: %v", err)
|
||||
}
|
||||
if !bytes.Equal(got, body) {
|
||||
t.Errorf("got response body %q, want %q", string(got), string(body))
|
||||
}
|
||||
res.Body.Close()
|
||||
pw.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user