Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
net/http: impossible to use both CloseNotify and Hijack in the same Server #9763
The existing implementation makes it impossible to run a Server with keep-alive that both gets notified about disconnecting clients and is capable of handling upgrade requests (such as to websocket protocol).
For example, consider the recent change to utilize CloseNotifier within the httputil.ReverseProxy: ececbe8
That's an important change for a reverse proxy because it allows upstream servers to stop doing work for clients that have gone away. Without that behavior, servers are much more vulnerable to resource exhaustion by misbehaving clients that disconnect immediately after making a request.
However, suppose that a Server not only wanted to defend against disconnecting clients, but also wanted to be able to handle HTTP Upgrade (or websocket) requests. That can only be implemented in http.Server by using the ResponseWriter's Hijacker interface to hijack the underlying net.Conn.
However, those two features are explicitly blocked from being used together. There's a good underlying reason for that: once CloseNotify() is called, there's an io.Copy reading from the underlying net.Conn that cannot be cleanly interrupted.
I think it's important to be able to use both of these features together in the same Server. One could imagine adding websocket or more general HTTP Upgrade support to the ReverseProxy, or simply supporting such features from a Server that also wants to know when clients go away on normal requests.
What version of Go are you using (go version)?
What operating system and processor architecture are you using?
What did you do?
I attempted to
What did you expect to see?
I expected to be able to hijack the connection, even though in a previous request I had asked to be notified about disconnecting clients.
What did you see instead?
I made an attempt to solve this in https://go-review.googlesource.com/#/c/3821/
This change allows connections that have been used with CloseNotify to
The necessary change should be quite small and overhead negligible: benburkert@3c2fd2f
I do like the idea of relying on a
To do that, you'd have to either add
This was referenced
Feb 4, 2015
referenced this issue
Jul 27, 2015
Are you trying to hijack after closenotify? I.e.
@bmizerany I think the situation is pretty well described in the original issue. You can't hijack a connection that previously had a CloseNotifier set up on it (even if it was set up on a previous request). Essentially this means that you can't reliably use both CloseNotify and Hijack in the same http.Server (sharing the same client connection pool).
CloseNotify is essential to a production server (protecting it from continuing to work when the client goes away). At the same time, Hijack is required for Websocket or just general HTTP Upgrade support. As a result, it's impossible to run an http.Server that has both production-ready support for regular HTTP requests, and also support for Websockets/HTTP upgrade.
Please read the original issue and let me know if anything is poorly explained
@bgentry, check out the latest version of https://golang.org/cl/17750 (patchset 2+), which has a fix for this bug. Unlike your change, it doesn't returned a custom