Skip to content
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

net/http: TimeoutHandler hides panic after timeout #34608

Open
pam4 opened this issue Sep 30, 2019 · 3 comments
Open

net/http: TimeoutHandler hides panic after timeout #34608

pam4 opened this issue Sep 30, 2019 · 3 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@pam4
Copy link

pam4 commented Sep 30, 2019

If TimeoutHandler's inner handler panics after the timeout, the panic is discarded:
https://play.golang.org/p/GT7lVCBu163

This happens because after the timeout, TimeoutHandler.ServeHTTP doesn't wait for the inner handler to complete, and anything on panicChan is lost.
I understand that waiting for the inner handler would partly defeat the purpose of TimeoutHandler. If waiting is not acceptable, perhaps the docs should warn about dropped panics.

Also, timeoutWriter.Push panics if called after the timeout:
https://play.golang.org/p/-AZj5t-ViyJ
(Not sure if this should be a separate issue.)

This happens because timeoutWriter.Push may call the underlying Push after or concurrently with the completion of TimeoutHandler.ServeHTTP (after which http2responseWriter.rws is set to nil).
Of course the panic is not logged for the reason already mentioned.

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 30, 2019
@bcmills bcmills added this to the Go1.14 milestone Sep 30, 2019
@bcmills
Copy link
Contributor

bcmills commented Sep 30, 2019

CC @bradfitz @cuonglm

@cuonglm
Copy link
Member

cuonglm commented Sep 30, 2019

I think adding document for dropping panic seems ok. But Push panics after timeout reached is not an issue at all. We can easily adding a check but it's not worth and meaningless.

@pam4
Copy link
Author

pam4 commented Oct 2, 2019

The docs clearly state:

A ResponseWriter may not be used after the Handler.ServeHTTP method has returned.

Any caller of ServeHTTP takes this rule for granted and may break in unexpected ways if it's not respected (for http2responseWriter, it leads to dereferencing a pointer that is concurrently set to nil).

Calling the Push overlay after timeout is nothing abnormal, in fact there's no way to make sure it won't happen.
It should be safe to use the overlay ResponseWriter for as long as the corresponding handler is running, OTOH the underlying one has a different lifespan and is TimeoutHandler's responsibility.

Concurrency aside, panic equals interrupted goroutine (I fail to see how it doesn't make a big difference in a non-fatal condition), but in this case it's worse because no clue is left behind! (No logs, see first part of the issue.)

There's also another concurrency issue: timeoutWriter.Push calls the underlying Push while the other goroutine calls the underlying Write/WriteHeader. Even if this is safe for http2responseWriter, it may break for a custom ResponseWriter (not required to be safe for concurrent use).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants