-
Notifications
You must be signed in to change notification settings - Fork 10
handle websocket requests to non-websocket targets #27
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
Conversation
relay response status and body back to requester
Looks like this was removed in the typescript refactor. The code exactly as-is from node-http-proxy doesn't work anymore due to mishandling of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds functionality to handle WebSocket upgrade requests that are made to non-WebSocket backends. When a WebSocket connection attempt is made to an HTTP-only endpoint, the proxy now relays the HTTP response status and body back to the client before closing the connection.
- Added response event handler in the WebSocket proxy to detect non-WebSocket responses
- Implemented HTTP response forwarding with status code and body preservation
- Added comprehensive test coverage for WebSocket-to-HTTP scenarios
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
File | Description |
---|---|
lib/test/websocket/websocket-proxy-http.test.ts | New test file covering WebSocket client connections to non-WebSocket backends |
lib/http-proxy/passes/ws-incoming.ts | Added response event handler to relay HTTP responses when backend doesn't support WebSockets |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
I didn't quite follow how this relates to the rest of your PR. |
Just that one solution is to put back exactly what was there instead of what I did here, but it leads to:
|
applies full web-outgoing passes needs to declare an EditableResponse subset of Response in order to mock it for the proxy response
I figured out a way to fully proxy the response (unlike node-http-proxy, which didn't put response headers through the web-outgoing passes). I don't fully understand the transfer-encoding problem. Removing the transfer-encoding header from the response avoids an error. I suspect it has to do with using |
ok, I understand transfer-encoding better now - since it's hop-by-hop, the outgoing body shouldn't have any relation to the transfer-encoding of the proxied request, so removing this header is the right thing to do (always, not just for this websocket case). I also realize this issue: http-party/node-http-proxy#1488 is still unaddressed and that there are other headers that should likely be unconditionally rewritten (or just removed) in web-outgoing, but that's another PR:
|
- proxied response transfer-encoding is never relevant for the client response - need to reimplement transfer-encoding when proxying directly to the socket instead of the Response object
opened #28 for the hop-by-hop headers in general, but fixed transfer-encoding here because it's actually needed when writing directly to a socket instead of to a |
OK, this looks good to me. |
relay response status and body back to requester
Honestly, the most relevant part of this is just closing the socket on the
response
event, because browser websockets don't really handle HTTP errors at all, they are all just treated as "not a websocket".But in this PR, the status and body are proxied back. It doesn't go through the full behavior of
proxy.web
(notably: headers are not preserved). I couldn't figure out the easiest way to properly preserve proxy passes from web-outgoing since we don't have ares
object. If ares
can be accessed and/or mocked so that the web-outgoing passes can be applied as-is, that should be fully proxied. In the absence of correctly proxied headers, I'd also be okay discarding the body and just proxying the status line withConnection: close
.closes #26