-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
What causes "response.Write on hijacked connection" when using CompressHandler? #589
Comments
To upgrade from the HTTP protocol to the WebSocket protocol, this package hijacks the network connection from the HTTP server. The response writer cannot be used after the network connection is pulled out from underneath it. The application should not use the compression middleware on WebSocket connections. Separate from that, the middleware should not close the gzip writer on hijacked connections. |
@srybacki thank you very much, I really appreciate the answer! I feel my confusion- potentially that of others- might come from the terminology:
Frankly- I don't comprehend. I'm doing:
The response writer is inside the handler:
There are also the http handlers, example:
How would I "pull (the connection) out from underneath it."? Do you mean a (shared) network connection owned by an What I'm trying to say is that I'm only dealing with response writers, never with connection except in case of the web socket handler which deals with client connections.
Is that what I'm doing? I'm failing to see where I'm using a websocket connection?
Again- I'm not doing that, at least not consciously. The websocket handler is eventually This is the general structure, probobly a familar (but flawed?) approach:
It would be great to understand the root cause, thank you for bearing with me. |
The application's call to Upgrader.Upgrade hijacks the network connection from the HTTP server. The hijacked connection is the connection used by the HTTP server to receive HTTP requests from the client and send HTTP responses to the client. After the connection is upgraded from the HTTP protocol to the WebSocket protocol, the network connection cannot be used for HTTP. The net/http server panics when the application attempts to write an HTTP response to a hijacked connection. The compression middleware does this automatically on the line of code linked from my previous comment. The application applies the compression middleware to all handlers using the function call.
Do not apply this middleware to the websocket handler. A rather blunt fix is to remove compression from all handlers by deleting the line of code. Because I am not familiar with the mux package, I don't have a suggestion for a more focused fix. |
I still don't get how the pieces connect.
Is that really true? Imho what happens in the HTTP server is:
There is no "connection used by the HTTP server per se", connections only exist at the point the client connects.
That's clear. Once a websocket client connects that connection must not be used for gzip or anything else.
I think my confusion came from the fact that regular responses don't trigger the problem, gzip middleware does. The reason is clear now: gzip applies to all handlers, i.e. it cascades down.
Right. I MUST not apply additional handler to the router if it handles websockets on one of it's paths.
I'l check if that can be done using sub routers. Would propose to keep this open to add a suggested solution once I found one. |
Here is what works for me. Don't add the
Even when serving from
That way, the websocket handler's response writer will not be affected by the |
I spent more time looking at the interaction between the interaction between the compression middleware and the websocket package. The compression middleware should step out of the way on an upgrade request. See gorilla/handlers#182. This issue can be closed.
... and the HTTP server uses this connection to receive requests and send responses to the client. This is the connection that upgrade hijacks from the HTTP server. |
I realize this is old (#212, #494). I understand
Yet I'm failing to identify the cause. I have a web socket on
/ws
and a routerHandleFunc
on/
for the index. There is alsoThe CompressHandler causes the problem and gives the following stack trace:
Versions
The websocket conn is closed when the client goes away. The http part is only dealing with
HandlerFunc
s:...but not with connections. I'm never writing to a connection explicitly and only write bodies after writing headers. I'm totally stumped where or how I might be writing to a hijacked connection?
The text was updated successfully, but these errors were encountered: