@@ -164,6 +164,8 @@ func (rx *ResumableUpload) transferChunk(ctx context.Context) (*http.Response, e
164
164
// and calls the returned functions after the request returns (see send.go).
165
165
// rx is private to the auto-generated API code.
166
166
// 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.
167
169
func (rx * ResumableUpload ) Upload (ctx context.Context ) (resp * http.Response , err error ) {
168
170
169
171
// 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
256
258
rCtx , cancel = context .WithTimeout (ctx , rx .ChunkTransferTimeout )
257
259
}
258
260
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
+ }
259
273
resp , err = rx .transferChunk (rCtx )
260
274
261
275
var status int
@@ -282,15 +296,11 @@ func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err
282
296
283
297
rx .attempts ++
284
298
pause = bo .Pause ()
285
- if resp != nil && resp .Body != nil {
286
- resp .Body .Close ()
287
- }
288
299
}
289
300
290
301
// If the chunk was uploaded successfully, but there's still
291
302
// more to go, upload the next chunk without any delay.
292
303
if statusResumeIncomplete (resp ) {
293
- resp .Body .Close ()
294
304
continue
295
305
}
296
306
0 commit comments