-
Notifications
You must be signed in to change notification settings - Fork 437
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
grpcwebproxy websocket implementation fails on multiple subprotocols #1111
Comments
Correctly reads all Sec-Websocket-Protocol headers and reads all values in those headers, and only succeeds if the expected subprotcol value of "grpc-websockets" is present. This implementation roughly mirrors what the nhooyr.io/websocket Accept() method does, with a few simplifications. Fixes improbable-eng#1111
Hi, thanks for your issue! This is great, thanks for all the explanation and research. Please note that this repo is in maintenance mode, and we recommend users migrate to the official grpc-web client: https://github.com/grpc/grpc-web. That said, I'm happy to review PRs that fix bugs in the existing code. |
Thanks for the heads up - we've found the upstream grpc/grpc-web to be lacking with no binary streaming support, and in the absence of tls browsers cannot use h2, so there is a very low limit on the number of concurrent streams (not unlike with websockets). We are trying to reduce our dependence (but not our support for) the improbably-eng/grpc-web grpcwebproxy, but if we should migrate away entirely, perhaps we will need to manage our own implementation entirely. |
…ls (#1112) * Server websocket implementation should allow, ignore other subprotocols Correctly reads all Sec-Websocket-Protocol headers and reads all values in those headers, and only succeeds if the expected subprotcol value of "grpc-websockets" is present. This implementation roughly mirrors what the nhooyr.io/websocket Accept() method does, with a few simplifications. Fixes #1111 * Manually update docs, correct indentation * Review feedback Canonicalize the header key before read, normalizing the possible values. Co-authored-by: Johan Brandhorst-Satzkorn <[email protected]> Co-authored-by: Johan Brandhorst-Satzkorn <[email protected]>
Versions of relevant software used
At least 0.12 through latest
What happened
Websockets support a mechanism known as "subprotocols" where a connecting client can offer zero to many options, and the server can pick from that list the best suited. The server then should communicate that negotiated protocol back to the client so both sides know which protocol is in use for the duration of the connection as the websocket finishes opening, and both client and server then can proceed sending messages using that protocol.
The websocket spec calls for the
Sec-Websocket-Protocol
header(s) to be defined by the client (multiple headers can be set, each header entry should be comma separated). The server then must select one of these values, or respond that it does not accept these options. See https://datatracker.ietf.org/doc/html/rfc6455#section-4.1, See https://datatracker.ietf.org/doc/html/rfc6455#section-4.2 for more details.The use case here is to implement an alternative but compatible websocket client/server (see #1081, #198) that is able to share a single websocket for all active streams. The proposed client implementation would support both
grpc-websockets
andgrpc-websockets-multiplex
. Server negotiation should inform the client which implementation will be used.Presently, grpcwebproxy's websocket implementation when offered multiple protocols will simply fail the connection, rather than pick the acceptable option
grpc-websockets
.What you expected to happen
If the client websocket contains
grpc-websockets
as an option, it is expected that the server will respond by opening the websocket selecting that as the negotiated subprotocol. Note that thenhooyr.io/websocket
library correctly handles this, but only theIsGrpcWebSocketRequest
check incorrectly fails.How to reproduce it (as minimally and precisely as possible):
The simplest way is to modify client/grpc-web/src/transports/websocket/websocket.ts to also offer any other protocol along with
grpc-websockets
, under the assumption that any server which can use that protocol will respond back with that same string. For example:Anything else we need to know
I'll offer a pull request to fix this. The project github.com/deephaven/deephaven-core has an in-process grpc-web and grpc-websockets proxy, and is seeking to add a grpc-websockets-multiplex proxy for faster non-tls stream initiation (and to avoid exhausting the browser's allowed websocket count). If there is interest, we can provide a ts client here, and see about an update to the Go proxy provided by improbable-eng/grpc-web.
The text was updated successfully, but these errors were encountered: