Skip to content
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

Add support for HTTP/2 originated Websockets (RFC 8441) #91

Open
jeregrine opened this issue Feb 3, 2023 · 8 comments
Open

Add support for HTTP/2 originated Websockets (RFC 8441) #91

jeregrine opened this issue Feb 3, 2023 · 8 comments
Labels
enhancement New feature or request h2

Comments

@jeregrine
Copy link

jeregrine commented Feb 3, 2023

I was talking to @mtrudel on slack and he came up with a list of steps in order to support http/2 h2c and http2 websockets:

  1. Add support for upgrade support to bandit/http1/{adapter,handler}.ex. This can mostly be cribbed directly from websocket support. I wouldn’t worry about parsing the request details here; just assume that a Plug will parse them out and pass it through as part of the opts in some format.
  2. Get it ending up as a {:switch, Bandit.HTTP2.Handler, opts} call that passes the opts through to the HTTP2 handler
  3. Add support to bandit/http2/handler.ex ’s handle_connection/2 function for starting up an HTTP2 request based on the opts passed in above. Per RFC7540§3.2 this will need to know about settings & the HTTP/1 request that included the upgrade request.
  4. Implement a Plug that knows how to read Upgrade requests, package the request & settings header up, and call the Plug.Conn.upgrade_adpater/4 that was added in step 1 above.
  5. Finally, we can shim this plug in as part of the overall plug pipeline internal to Bandit, at least for HTTP/1 requests.

May make sense to tackle step 4 first, depending on how you break the problem down in your head

@mtrudel
Copy link
Owner

mtrudel commented Feb 3, 2023

Happy to take on any / all of this, but @jeregrine indicated they may be taking some on first.

Let's coordinate here.

@mtrudel mtrudel added enhancement New feature or request h2 labels Mar 8, 2023
@mtrudel
Copy link
Owner

mtrudel commented Apr 20, 2023

Reviewing RFC9113§3.1, h2c upgrades have been deprecated. As we've standardized on the newer interpretations in RFC911x, this work won't be undertaken. The work in RFC8441 for h2 WebSocket upgrades continues to stand. We've landed h2c support

@mtrudel
Copy link
Owner

mtrudel commented Jun 28, 2023

h2c support just landed in 1.0.0-pre.10 thanks to the hard work of @alisinabh! Let us know if you're able to make productive use of it @jeregrine !

RFC 8441 support is a separate (and in progress) workup, slated to land as part of 1.1, most likely later this summer. I'll update the scope of this issue to reflect that support; if there are any issues with h2c support please open them as a separate issue.

@mtrudel mtrudel changed the title Add HTTP/2 h2c Support, and HTTP/2 Websockets Add support for HTTP/2 originated Websockets (RFC 8441) Jun 28, 2023
@jeregrine
Copy link
Author

WHOA NICE! @alisinabh !!

@mtrudel
Copy link
Owner

mtrudel commented Jun 28, 2023

WHOA NICE! @alisinabh !!

One hell of a first-time contribution, amirite?

@alisinabh
Copy link
Collaborator

I'm flattered guys :)
To be honest, bandit code is super easy to understand. Thank you all and looking forward to help with other tasks here.

@michealp-coder
Copy link

Is this still an open issue?

@mtrudel
Copy link
Owner

mtrudel commented Jan 18, 2024

Is this still an open issue?

It is! It's a bit of a yak shave to land this properly, which is why it's taking so long. Current progress:

  • Refactor H2 stack to be GenServer based, and to push as much logic down into stream as possible. This is being done on Refactor H2 #286 and is progressing really well
  • Refactor both http1 & h2 stacks to split out transport (which obv greatly differs between the two) and higher level HTTP semantics. Share a common HTTP semantics module between the two transports with a clean interface to/from between the two layers. Basically, split out the bits of RFC 9110 into their own shared 'semantics' module, and have the existing http1 and h2 modules handle just the concerns in RFC 9112 and RFC 9113 respectively
  • Use this same interface to power the websocket implementation. This will allow a single websocket implementation to 'just work' on both http1 & h2 stacks
  • The only thing left at that point is to write up the h2-specific WS upgrade implementation (ie: the stuff that's ACTUALLY in RFC 8441). That will be easy.

By the end of this workup, the fundamental architecture of Bandit will have changed to look like so (square brackets are modules, ---delimited text are interfaces)


       --- Plug---                ---WebSock---
 [HTTP Semantics (RFC 9110)] & [WebSockets RFC 6441]
  --- HTTP transport-semantics interface (TBD) ---
       [HTTP1 (RFC 9112)] & [H2 (RFC 9113)]
            --- Handler Interface---
               [Thousand Island]

@mtrudel mtrudel mentioned this issue Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request h2
Projects
None yet
Development

No branches or pull requests

4 participants