diff options
author | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
commit | a16e30d162c1c7408db7821e7b9513cefa09c6ca (patch) | |
tree | af752ba9ba44c547df39bb0af9bff79f610ba9d5 /src/net/http/request.go | |
parent | 91e4d2d57bc341dd82c98247117114c851380aef (diff) | |
parent | cf6cfba4d5358404dd890f6025e573a4b2156543 (diff) | |
download | go-git-dev.link.tar.gz |
[dev.link] all: merge branch 'master' into dev.linkdev.link
Clean merge.
Change-Id: Ia7b2808bc649790198d34c226a61d9e569084dc5
Diffstat (limited to 'src/net/http/request.go')
-rw-r--r-- | src/net/http/request.go | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go index fe6b60982c..adba5406e9 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -15,7 +15,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "mime/multipart" "net" @@ -175,6 +174,10 @@ type Request struct { // but will return EOF immediately when no body is present. // The Server will close the request body. The ServeHTTP // Handler does not need to. + // + // Body must allow Read to be called concurrently with Close. + // In particular, calling Close should unblock a Read waiting + // for input. Body io.ReadCloser // GetBody defines an optional func to return a new copy of @@ -382,7 +385,7 @@ func (r *Request) Clone(ctx context.Context) *Request { if s := r.TransferEncoding; s != nil { s2 := make([]string, len(s)) copy(s2, s) - r2.TransferEncoding = s + r2.TransferEncoding = s2 } r2.Form = cloneURLValues(r.Form) r2.PostForm = cloneURLValues(r.PostForm) @@ -540,6 +543,7 @@ var errMissingHost = errors.New("http: Request.Write on Request with no Host or // extraHeaders may be nil // waitForContinue may be nil +// always closes body func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) { trace := httptrace.ContextClientTrace(r.Context()) if trace != nil && trace.WroteRequest != nil { @@ -549,6 +553,15 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF }) }() } + closed := false + defer func() { + if closed { + return + } + if closeErr := r.closeBody(); closeErr != nil && err == nil { + err = closeErr + } + }() // Find the target host. Prefer the Host: header, but if that // is not given, use the host from the request URL. @@ -667,6 +680,7 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF trace.Wait100Continue() } if !waitForContinue() { + closed = true r.closeBody() return nil } @@ -679,6 +693,7 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF } // Write body and trailer + closed = true err = tw.writeBody(w) if err != nil { if tw.bodyReadError == err { @@ -854,7 +869,7 @@ func NewRequestWithContext(ctx context.Context, method, url string, body io.Read } rc, ok := body.(io.ReadCloser) if !ok && body != nil { - rc = ioutil.NopCloser(body) + rc = io.NopCloser(body) } // The host's colon:port should be normalized. See Issue 14836. u.Host = removeEmptyPort(u.Host) @@ -876,21 +891,21 @@ func NewRequestWithContext(ctx context.Context, method, url string, body io.Read buf := v.Bytes() req.GetBody = func() (io.ReadCloser, error) { r := bytes.NewReader(buf) - return ioutil.NopCloser(r), nil + return io.NopCloser(r), nil } case *bytes.Reader: req.ContentLength = int64(v.Len()) snapshot := *v req.GetBody = func() (io.ReadCloser, error) { r := snapshot - return ioutil.NopCloser(&r), nil + return io.NopCloser(&r), nil } case *strings.Reader: req.ContentLength = int64(v.Len()) snapshot := *v req.GetBody = func() (io.ReadCloser, error) { r := snapshot - return ioutil.NopCloser(&r), nil + return io.NopCloser(&r), nil } default: // This is where we'd set it to -1 (at least @@ -1189,7 +1204,7 @@ func parsePostForm(r *Request) (vs url.Values, err error) { maxFormSize = int64(10 << 20) // 10 MB is a lot of text. reader = io.LimitReader(r.Body, maxFormSize+1) } - b, e := ioutil.ReadAll(reader) + b, e := io.ReadAll(reader) if e != nil { if err == nil { err = e @@ -1383,10 +1398,11 @@ func (r *Request) wantsClose() bool { return hasToken(r.Header.get("Connection"), "close") } -func (r *Request) closeBody() { - if r.Body != nil { - r.Body.Close() +func (r *Request) closeBody() error { + if r.Body == nil { + return nil } + return r.Body.Close() } func (r *Request) isReplayable() bool { |