-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: TimeoutHandler prevents use of ResponseController #69777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
CC @neild |
One of |
The original
I don't remember why we specified it that way; it's possible we just felt that figuring out how TimeoutHandler and ResponseController timeouts interacted was a distraction from the proposal. I'm not sure what the correct behavior here is. How should the ResponseController deadlines interact with the TimeoutHandler deadline? Are they entirely separate? Should you be able to change the TimeoutHandler deadline using SetWriteDeadline? |
Thank you for the additional context, that's helpful! There is indeed an logical overlap between the timeout from TimeoutHandler and the read/write deadlines from ResponseController. If the deadline from TimeoutHandler is reached, it makes sense to cancel all active reads from the request by resetting the read deadline. In addition, writes to the ResponseWriter that is wrapped by TimeoutHandler should also be cancelled, as they won't reach the client anymore. The write deadline for the underlying ResponseWriter should be extended by a short period to allow TimeoutHandler to write its error response. When setting the read/write deadline via ResponseWriter, I expect the timeout for TimeoutHandler to not change. This allows the handler to react to reached read/write deadlines and respond to the client properly. What do you think about this? |
To recap:
Is that right? If so, seems reasonable to me. Perhaps TimeoutHandler should ensure that SetReadDeadline/SetWriteDeadline don't extend the deadlines after the TimeoutHandler deadline has passed. While we're in here, we should probably ensure that ResponseController.EnableFullDuplex works in a TimeoutHandler. Hijack should still return an unimplemented error. Flush should either return an unimplemented error or work correctly. |
I agree.
Depending on how this would be implemented, it could be the source of a race condition. If the TimeoutHandler and the read/write deadlines are set to the same point in time and this point is reached, either the TimeoutHandler sends its 503 Service Unavailable response first or the read/write deadline is reached first, allowing the handler to respond with a custom error message. The response would then be less deterministic. Could this be occurring or are there good ways to prevent this? It might also not be necessary to prevent the deadlines from exceeding the timeout at all if the deadlines are reset anyways when the timeout is hit.
👍 |
Go version
go version go1.23.1 darwin/arm64
Output of
go env
in your module/workspace:What did you do?
I have a
http.Handler
that useshttp.NewResponseController
on the response writer to control the response behavior. If my handler is wrapped in ahttp.TimeoutHandler
, calls toResponseController.SetReadTimeout
,ResponseController.EnableFullDuplex
return an error sayingfeature not supported
.https://go.dev/play/p/Bar7glioldQ contains an example for reproduction. Unfortunately, running the code in the playground often fails with an i/o timeout, but locally this problem does not appear.
What did you see happen?
Any interaction with the response controller functions returns an error saying
feature not supported
. Running the linked code locally produces the following output:The reason seems to be that
TimeoutHandler
wraps the response writer into its owntimeoutWriter
(https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/net/http/server.go;l=3658), which neither implements the methods forResponseController
(https://pkg.go.dev/net/http#NewResponseController) nor anUnwrap
function returning the original response writer. The easiest solution might be to add an Unwrap method totimeoutWriter
.I also checked if other handler wrappers in
net/http
interfere with ResponseController.AllowQuerySemicolons
,StripPrefix
, andMaxBytesHandler
don't cause issues as they don't wrap the response writer.What did you expect to see?
ResponseController
should be usable together withTimeoutHandler
. Running the linked code should produce the following output:The text was updated successfully, but these errors were encountered: