-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: x/net/http2: support for WebSockets over HTTP/2 #49918
Comments
also related #27244 |
Just for reference https://datatracker.ietf.org/doc/html/rfc8441 it seems this requires (please correct me if I'm wrong, not very familiar with the stdlib implemententation):
Requires adding an HTTP2 server option to enable the setting
and adding the logic to use the field if SETTINGS_ENABLE_CONNECT_PROTOCOL has been received. EDIT1 :/ Lines 107 to 109 in 90fb5a4
EDIT2, so this seems to be on purpose
|
I think that this will only require adding a new option on the http2 server to enable the SETTINGS_ENABLE_CONNECT_PROTOCOL option and another one in the client to let the user know if that setting is enable. If I understand correctly how CONNECT works in golang, the rest of the logic can be done at a higher level in a similar way that is being done with https://github.com/golang/net/tree/master/websocket |
Considering the gorilla/websocket library is currently unmaintained, which is causing a lot of concern in the community, I think this is a great opportunity to solidify and complete websocket support in the standard library |
I did a prototype https://github.com/aojea/net/pull/1/files to get a better idea on what will be required to implement this. My main concern is that golang seems to avoid implementing the CONNECT semantics in the stdlib #22554 (comment), leaving the implementation to the users. |
I've started poking at this a bit and it seems that a resolution will require two patches: one to the x/net/http2 package to allow stream oriented interaction with an http2 stream, and then a followup change to x/net/websocket to add the actual websocket support. I've talked about this a bit on the go-nuts mailing list, but it really should be a public discussion, so I'm moving it here. Here's the most recent message I posted about a strawman patch I've put together: I've got something working for exposing HTTP/2 streams as On the server side of things, it seems that the current interface is basically already adequate except for the fact that the server currently rejects any requests using non
In terms of the client side of things, I'm relatively happy with the interface for the
|
I just noticed https://datatracker.ietf.org/doc/html/rfc8441#section-5 saying that for HTTP/2 |
Commented on https://go.dev/cl/408835: Do we need a new stream-oriented We'd need to add support for We also need a way to set/get the Unless we put some level of websocket bootstrap support directly into |
Yeah, I think those are all good points. The suggestion you made in the CL works with no changes to I've started poking at SETTINGS_ENABLE_CONNECT_PROTOCOL support a bit. It seems like it should be easy enough to just advertise it in the initial settings frame on the server side and then set it as a flag on the ClientConn on the server side. We probably don't even need to expose it to users on the client side, we could just check the flag and return an error if they try to send a CONNECT message and the setting is not enabled. Currently, the client seems to clobber the scheme and path when you try sending a |
HTTP/2 The
|
Ah, that makes sense. I had thought it was just an advertisement that the server knew how to handle the connect protocol, but a mode switch makes more sense. Then it probably sense to just add an option to |
I'm not sure we even need an option; maybe just always send |
I was thinking that someone might be using the http package to implement a proxy, though that seems like a pretty strange usecase. If you think we don't have to worry about that, then having no public API changes would be awesome. I'll make my reworking of the patch I posted just send it all the time. |
It is true that if we advertise it unconditionally, then existing |
I've had the time to rework that straw-man patch to just use the request and response body on the client side as suggested and it results in a much cleaner implementation with basically no public API impact. The one issue is that it is not totally clear from the existing interface how to ask the http client to set the
If that all sounds reasonable, no need to look at any of this too closely until I get to those proposals. |
This patch adds a stream oriented API to the x/net/http2 package. It's not meant to be a final change since I have not yet even written a proposal. I'm just posting it to have some concrete code to be able to reference in the discussion about the actual interface changes we want to do. If my posting this triggers a review request, sorry abou that. It's my first time using gerrit. See the discussion on github[1] for more details. DO NOT REVIEW DO NOT SUBMIT [1]: golang/go#49918 (comment) Change-Id: Ifbcc6f86480a585eb92e801563708e91fe879b24
Fortunately, it seems like implementing websocket support in terms of that SETTINGS_ENABLE_CONNECT_PROTOCOL patch is fairly straightforward. I put together a strawman patch here: ethanpailes/golang-org-x-net@df38e5d |
#53208 is a more formal proposal for the SETTINGS_ENABLE_CONNECT_PROTOCOL support. I'll work on one for the websocket support now. |
Due to a bug in Chrome, secure websockets in Teleport work intermittently on the Chrome browser when using HTTP/2. Prioritizing HTTP/1.1 fixes this issue, though the reasons for this are not 100% clear. When or if https://bugs.chromium.org/p/chromium/issues/detail?id=1379017 is resolved, we should be able to revert this. When golang/go#49918 is implemented, we may be able to revert this if enabling HTTP/2 websockets fixes the issue on our end.
Due to a bug in Chrome, secure websockets in Teleport work intermittently on the Chrome browser when using HTTP/2. Prioritizing HTTP/1.1 fixes this issue, though the reasons for this are not 100% clear. When or if https://bugs.chromium.org/p/chromium/issues/detail?id=1379017 is resolved, we should be able to revert this. When golang/go#49918 is implemented, we may be able to revert this if enabling HTTP/2 websockets fixes the issue on our end.
Due to a bug in Chrome, secure websockets in Teleport work intermittently on the Chrome browser when using HTTP/2. Prioritizing HTTP/1.1 fixes this issue, though the reasons for this are not 100% clear. When or if https://bugs.chromium.org/p/chromium/issues/detail?id=1379017 is resolved, we should be able to revert this. When golang/go#49918 is implemented, we may be able to revert this if enabling HTTP/2 websockets fixes the issue on our end.
Due to a bug in Chrome, secure websockets in Teleport work intermittently on the Chrome browser when using HTTP/2. Prioritizing HTTP/1.1 fixes this issue, though the reasons for this are not 100% clear. When or if https://bugs.chromium.org/p/chromium/issues/detail?id=1379017 is resolved, we should be able to revert this. When golang/go#49918 is implemented, we may be able to revert this if enabling HTTP/2 websockets fixes the issue on our end.
Due to a bug in Chrome, secure websockets in Teleport work intermittently on the Chrome browser when using HTTP/2. Prioritizing HTTP/1.1 fixes this issue, though the reasons for this are not 100% clear. When or if https://bugs.chromium.org/p/chromium/issues/detail?id=1379017 is resolved, we should be able to revert this. When golang/go#49918 is implemented, we may be able to revert this if enabling HTTP/2 websockets fixes the issue on our end.
Any update? |
Any update? |
@masx200 the main update is #53208 (comment), the key proposal blocking this proposal has entered the "likely accept" state which means that if nothing else comes up work can begin to implement that. That proposal is probably more important because without it not even third party crates can do a reasonable WebSocket implementation for http2 (technically they could, but they would need to make an entire http stack themselves). |
@ethanpailes Now that the proposal is accepted, will you continue work on this or perhaps I can give it a go? As a member of caddy I want to work on this issue. |
+1 for status update and integration. |
@WeidiDeng my original reason for wanting this feature is no longer relevant to me, so I'm not doing it as part of my day job anymore. I would like to see it go over the finish line though so I do intend to pick it up eventually. If you're feeling modivated to work on it, I won't stand in your way though. |
Change https://go.dev/cl/610977 mentions this issue: |
Change https://go.dev/cl/630875 mentions this issue: |
For golang/go#49918 Change-Id: Ibcd8fb189200c0976cf1bd03a796abae4afa4cfd GitHub-Last-Rev: cba5ecd GitHub-Pull-Request: #221 Reviewed-on: https://go-review.googlesource.com/c/net/+/610977 Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Damien Neil <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]>
+1 cause I stumbled upon this when trying to set up Caddy as a reverse proxy |
Testing out his change and im hitting a panic with echo and processing the websocket:
usage:
My guess is if its a http2 stream not a http1 connection the net package shouldnt need to hijack the connection when processing the websocket |
Hacking up the net package i did make it work with chrome -> envoy -> go over http. |
@mchandler-plato thanks for the snippet, I was not able to find your email to add you as co-author but if you share it I will add you to https://go-review.googlesource.com/c/net/+/632755 It seems is now easy to support websockets over http2 |
Sent you an email with details. Thanks! |
Change https://go.dev/cl/632899 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What did you do?
I wanted to use Websockets over HTTP2.
What did you expect to see?
Support for it in Go standard library.
What did you see instead?
It does not support it yet.
See #46319 for background.
WebSockets over HTTP2 have been standardized as RFC 8441 and Firefox and Chromium supports that. Thus, I suggest that support is added for Websockets over HTTP2. The server should also be able to specify using HTTP/2 SETTINGS parameter that it supports Websockets over HTTP2.
The text was updated successfully, but these errors were encountered: