Skip to content

Large response payload cannot be fully read due to context cancelled #4

@jkosecki

Description

@jkosecki

Hi,

I've noticed that for some larger payloads in the response (in my case it was just an array of 40 objects or so) I was getting context cancelled error when reading the response body. After digging a bit more into the code and reading the docs of net/http I' found that it was caused by use of timed context within your sendReq method.

reqCtx, cancel := context.WithTimeout(ctx, c.timeout)
defer cancel()

Following the docs of NewRequestWithContext:

For an outgoing client request, the context controls the entire lifetime of a request and its response: obtaining a connection, sending the request, and reading the response headers and body.

So what happens here is that once a request is made, you return Response object that might be still buffering response payload. However, cancel() happens around the same time, which, in case of larger payloads that are not fully buffered before sendReq's defer is called, results in partial response body and error returned when calling response.Body()

One thing would be to pass ctxCancel function to the response object returned and call cancel as part of reading the response payload - however, docs of net/http.Client says:

// Timeout specifies a time limit for requests made by this
// Client. The timeout includes connection time, any
// redirects, and reading the response body. The timer remains
// running after Get, Head, Post, or Do return and will
// interrupt reading of the Response.Body.
suggest that timeout set when the client is created does most likely exactly the same what your reqCtx, cancel := context.WithTimeout(ctx, c.timeout) does. So keeping it in sendReq is unnecessary and one can rely on the internal implementation of the client.timeout

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions