Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
net/http: ReadTimeout is not honored when ReadHeaderTimeout > ReadTimeout #35626
What version of Go are you using (
@fraenkel I think that isn't true either... I actually assumed as you that this was the case, and tried to use a ReadHeaderTimeout > ReadTimeout in my application. But it turns out it's actually not, and having such a relationship shows an interesting behavior. Observe the following if we alter the example to read:
Then create the following shell script with a client payload:
And run it:
The server happily waits up to ReadHeaderTimeout for headers, but after getting them, if ReadTimeout is elapsed, it instantly times out the request when trying to read the body. (Note therefore that it doesn't affect GET requests where there's no body.) It seems like kind of a useless behavior in real life, and therefore an error for anyone to ever be setting ReadHeaderTimeout > ReadTimeout.
I accidentally set ReadHeaderTimeout > ReadTimeout in my application because ReadHeaderTimeout documentation says:
The question is: the read deadline is reset to what? I assumed it would be reset to a new deadline based off of whenever the headers had stopped reading. i.e. that something sensible would happen when ReadHeaderTimeout > ReadTimeout. For example, reset deadline to
I think that documentation could also use clarification to indicate what value the read deadline is reset to, and then explicitly call out this interesting behavior as a warning.
Sorry I should have been more clear. I dont think the current behavior is valuable given what I would have expected the proper behavior to be.
If there is no ReadHeaderTimeout, the request timeout is exactly the read timeout. If there is a ReadHeaderTimeout set, the headers must be read within that timeout window, but the request timeout is the remaining amount given the sum of ReadHeaderTimeout + ReadTimeout.
What you see above seems correct to me. The header timeout expired and so does the request. For a GET request, having this split timeout doesn't make much sense given there is usually no body. It would have been useful if the timeouts were disconnected so one could guarantee headers are read within time X and bodies within time Y.
I guess if one looks at the current ReadHeaderTimeout usage, we could determine if changing the behavior affects people and whether it would be for the better.