@@ -164,6 +164,8 @@ func (rx *ResumableUpload) transferChunk(ctx context.Context) (*http.Response, e
164164// and calls the returned functions after the request returns (see send.go).
165165// rx is private to the auto-generated API code.
166166// Exactly one of resp or err will be nil. If resp is non-nil, the caller must call resp.Body.Close.
167+ // Upload does not parse the response into the error on a non 200 response;
168+ // it is the caller's responsibility to call resp.Body.Close.
167169func (rx * ResumableUpload ) Upload (ctx context.Context ) (resp * http.Response , err error ) {
168170
169171 // There are a couple of cases where it's possible for err and resp to both
@@ -256,6 +258,18 @@ func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err
256258 rCtx , cancel = context .WithTimeout (ctx , rx .ChunkTransferTimeout )
257259 }
258260
261+ // We close the response's body here, since we definitely will not
262+ // return `resp` now. If we close it before the select case above, a
263+ // timer may fire and cause us to return a response with a closed body
264+ // (in which case, the caller will not get the error message in the body).
265+ if resp != nil && resp .Body != nil {
266+ // Read the body to EOF - if the Body is not both read to EOF and closed,
267+ // the Client's underlying RoundTripper may not be able to re-use the
268+ // persistent TCP connection to the server for a subsequent "keep-alive" request.
269+ // See https://pkg.go.dev/net/http#Client.Do
270+ io .Copy (io .Discard , resp .Body )
271+ resp .Body .Close ()
272+ }
259273 resp , err = rx .transferChunk (rCtx )
260274
261275 var status int
@@ -282,15 +296,11 @@ func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err
282296
283297 rx .attempts ++
284298 pause = bo .Pause ()
285- if resp != nil && resp .Body != nil {
286- resp .Body .Close ()
287- }
288299 }
289300
290301 // If the chunk was uploaded successfully, but there's still
291302 // more to go, upload the next chunk without any delay.
292303 if statusResumeIncomplete (resp ) {
293- resp .Body .Close ()
294304 continue
295305 }
296306
0 commit comments