mirror of
https://github.com/golang/go
synced 2024-11-23 13:50:06 -07:00
net/http: update bundled http2
Updates bundled x/net/http2 to git rev cffdcf67 for: http2: use GetBody unconditionally on Transport retry, when available https://golang.org/cl/123476 http2: a closed stream cannot receive data https://golang.org/cl/111676 Updates #25009 Updates #25023 Change-Id: I84f50cc50c0fa5a3c34f0037a9cb1ef468e5f0d9 Reviewed-on: https://go-review.googlesource.com/123515 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
3df1f00bfc
commit
a7bcb5390d
@ -5320,6 +5320,12 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
|
|||||||
// type PROTOCOL_ERROR."
|
// type PROTOCOL_ERROR."
|
||||||
return http2ConnectionError(http2ErrCodeProtocol)
|
return http2ConnectionError(http2ErrCodeProtocol)
|
||||||
}
|
}
|
||||||
|
// RFC 7540, sec 6.1: If a DATA frame is received whose stream is not in
|
||||||
|
// "open" or "half-closed (local)" state, the recipient MUST respond with a
|
||||||
|
// stream error (Section 5.4.2) of type STREAM_CLOSED.
|
||||||
|
if state == http2stateClosed {
|
||||||
|
return http2streamError(id, http2ErrCodeStreamClosed)
|
||||||
|
}
|
||||||
if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
|
if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
|
||||||
// This includes sending a RST_STREAM if the stream is
|
// This includes sending a RST_STREAM if the stream is
|
||||||
// in stateHalfClosedLocal (which currently means that
|
// in stateHalfClosedLocal (which currently means that
|
||||||
@ -7022,27 +7028,36 @@ func http2shouldRetryRequest(req *Request, err error, afterBodyWrite bool) (*Req
|
|||||||
if !http2canRetryError(err) {
|
if !http2canRetryError(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !afterBodyWrite {
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
// If the Body is nil (or http.NoBody), it's safe to reuse
|
// If the Body is nil (or http.NoBody), it's safe to reuse
|
||||||
// this request and its Body.
|
// this request and its Body.
|
||||||
if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
|
if req.Body == nil || http2reqBodyIsNoBody(req.Body) {
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
// Otherwise we depend on the Request having its GetBody
|
|
||||||
// func defined.
|
// If the request body can be reset back to its original
|
||||||
|
// state via the optional req.GetBody, do that.
|
||||||
getBody := http2reqGetBody(req) // Go 1.8: getBody = req.GetBody
|
getBody := http2reqGetBody(req) // Go 1.8: getBody = req.GetBody
|
||||||
if getBody == nil {
|
if getBody != nil {
|
||||||
return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
|
// TODO: consider a req.Body.Close here? or audit that all caller paths do?
|
||||||
|
body, err := getBody()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
newReq := *req
|
||||||
|
newReq.Body = body
|
||||||
|
return &newReq, nil
|
||||||
}
|
}
|
||||||
body, err := getBody()
|
|
||||||
if err != nil {
|
// The Request.Body can't reset back to the beginning, but we
|
||||||
return nil, err
|
// don't seem to have started to read from it yet, so reuse
|
||||||
|
// the request directly. The "afterBodyWrite" means the
|
||||||
|
// bodyWrite process has started, which becomes true before
|
||||||
|
// the first Read.
|
||||||
|
if !afterBodyWrite {
|
||||||
|
return req, nil
|
||||||
}
|
}
|
||||||
newReq := *req
|
|
||||||
newReq.Body = body
|
return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
|
||||||
return &newReq, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func http2canRetryError(err error) bool {
|
func http2canRetryError(err error) bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user