Skip to content

Webtransport support quic/http 3#63827

Draft
martenrichter wants to merge 16 commits into
nodejs:mainfrom
martenrichter:webtransportinterfaces
Draft

Webtransport support quic/http 3#63827
martenrichter wants to merge 16 commits into
nodejs:mainfrom
martenrichter:webtransportinterfaces

Conversation

@martenrichter

Copy link
Copy Markdown
Contributor

This PR is done to discuss early changes required for webtransport.
It is not intended for merging, as it uses an experimental PR of nghttp3, so rebases are required in the end.
Main objective is to discuss also the API on the way.

Currently, I use during the development the higher level functions of my node.js package, which has a special branch for the webtransport implementation:
https://github.com/fails-components/webtransport/tree/nodenativequic (branch for the implementation)
Relevant files are in:
https://github.com/fails-components/webtransport/tree/nodenativequic/main/lib/http3native
I have only the bare minimum of functions in node.js, as I believe that will give developers more control. So W3C interface is my package for now. (but also here will be feedback valuable)

Currently client, session and stream are partially implemented.
I am going step by step through all test I have.
I pass test 1 of:
https://github.com/fails-components/webtransport/blob/nodenativequic/main/old_test/testsuite.js
(old test, usually first to check when implementing;).
Test 2 fails. (Probably not a WT specific issue #63784).

The plan is :

  • Make all old test run
  • Go to the newer tests and fix them
  • Implement server side
  • Make all old test run (server side)
  • Go to the newer tests and fix them (server side)
  • Convert tests to node.js tests

But it will take time.

@pimterry @jasnell : Please invite other people who should take part in the discussion.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/quic
  • @nodejs/security-wg

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. quic Issues and PRs related to the QUIC implementation / HTTP/3. labels Jun 10, 2026
@pimterry

Copy link
Copy Markdown
Member

Thanks @martenrichter, super interesting! This is great and I'd definitely be keen to include WebTransport as soon as we can, though it'll probably have to wait until nghttp3 merge the draft this depends on, which in turn looks like it's currently waiting on the final RFC.

This approach in rough concept looks like it'll fit neatly with the HTTP/3 API changes & internals split I'm going to propose shortly (aiming for a PR on Monday I think) so there shouldn't be a big practical issue to implement WebTransport with that. In practice for this code specifically I should warn you there's going to be massive conflicts line-by-line since I'm moving lots of things around, but it's largely just relocation rather than more substantial changes.

The only relevant that might change in approach is the ticket data and application options part, since I'm adding a new API to better split transport params from app ticket data, and pull application options entirely out from QUIC into the specific application implementation. It'll make sense shortly I hope 😄 watch this space.

@martenrichter

Copy link
Copy Markdown
Contributor Author

Thanks @martenrichter, super interesting! This is great and I'd definitely be keen to include WebTransport as soon as we can, though it'll probably have to wait until nghttp3 merge the draft this depends on, which in turn looks like it's currently waiting on the final RFC.

I also expected this. So I am prepared with branch to do the rebases from time to time.

This approach in rough concept looks like it'll fit neatly with the HTTP/3 API changes & internals split I'm going to propose shortly (aiming for a PR on Monday I think) so there shouldn't be a big practical issue to implement WebTransport with that. In practice for this code specifically I should warn you there's going to be massive conflicts line-by-line since I'm moving lots of things around, but it's largely just relocation rather than more substantial changes.

Ok, I will look into it and rebase after it is merged. Most of the wt stuff is in addition to the existing mechanism, so it should not be much work.

The only relevant that might change in approach is the ticket data and application options part, since I'm adding a new API to better split transport params from app ticket data, and pull application options entirely out from QUIC into the specific application implementation. It'll make sense shortly I hope 😄 watch this space.

I will see, but it looks quite orthogonal to the wt changes.

@martenrichter

Copy link
Copy Markdown
Contributor Author

"Make all old test run" (client side) done.

@martenrichter martenrichter force-pushed the webtransportinterfaces branch 4 times, most recently from 7ad3e62 to 39e2915 Compare June 27, 2026 06:18
@martenrichter

Copy link
Copy Markdown
Contributor Author

Go to the newer tests and fix them (done!) (Except the flow control features not implemented in nghttp3).

@martenrichter

Copy link
Copy Markdown
Contributor Author
  • Implement server side
  • Make all old test run (server side)

Both done. (No change no node.js required for these steps.)

@pimterry

Copy link
Copy Markdown
Member

Cool to see this making progress. How far off are we from putting one or two small tests to demo the whole setup into here? That'd make it easier to discuss the API and try it all our end-to-end. Looks like the only tests so far are for settings config.

I had a bit more of a look here after your comment in #64192, I was curious about the onsessionid events, and how that works.

I think similarly to the HTTP/3 split and the existing HTTP/2 API, it would be nice to aim for a protocol-specific API that hides those internals, to expose the low-level protocol primitives but not the protocol internal working. I.e. to use the API, imo you shouldn't need to think about control streams and session ids, you just get the WT session CONNECT headers, you can allow or reject, and then you get easy to use streams within.

Maybe we have a http3Session.onWebTransportSession callback which fires (headers, wtSession) with a WebTransportSession object, and each WT session has onStream event that emits a WebTransportStream in turn. WebTransportSession would manage the control stream & underlying HTTP/3 session interactions, and WebTransportStreams would just give you an API for raw data & stream-linked datagrams. For users who are interested in the raw workings underneath, they can always reach down into the underlying HTTP/3 or QUIC session directly.

Just food for thought, we don't need to define all this immediately anyway. We can focus on the internals in the short term and work out the user-facing surface later, I'm just starting to spitball about how it's all going to glue together.

@martenrichter

Copy link
Copy Markdown
Contributor Author

Cool to see this making progress. How far off are we from putting one or two small tests to demo the whole setup into here?

In principle, we have this already in my external test setup. I can also run it node server and node client. (Though I do it step by step). Once I am ready with these test I will port them over.

That'd make it easier to discuss the API and try it all our end-to-end. Looks like the only tests so far are for settings config.

That is because I have postponed it until my test are running. I know this is not ideal for looking into the api. But you can look here:
https://github.com/fails-components/webtransport/tree/nodenativequic/main/lib/http3native

All these files are in principle the steps to interact with the api, which would also be visible in a test.
And the layer is relatively thin.

I had a bit more of a look here after your comment in #64192, I was curious about the onsessionid events, and how that works.

Here are all event handlers of a wt session stream:

https://github.com/fails-components/webtransport/blob/b303d4d59cd15beb20046501d55b6ad1c11d6b44/main/lib/http3native/session.js#L66

(And if you want, I can also write, how to setup the tests, while I have not ported them to node native).

I think similarly to the HTTP/3 split and the existing HTTP/2 API, it would be nice to aim for a protocol-specific API that hides those internals, to expose the low-level protocol primitives but not the protocol internal working. I.e. to use the API, imo you shouldn't need to think about control streams and session ids, you just get the WT session CONNECT headers, you can allow or reject, and then you get easy to use streams within.

That is in principle, what my webtransport package is currently doing. Though its architecture aims at the old quiche binary addon. My plan is to make this layer thinner and then eventually, if it fits, put the remaining parts to node.js. So that it comes close to your idea. Though there are only minimal changes required to hide the id.
But I want to do it step by step, as I think I will be faster this way.

Note, I have also parsers for the capsule protocol (alternative transport on http/3 and http/2) currently only in js (what I would be happy to port it to C/C++).
Also for a WebSocket based fallback protocol which supports backpressure also in a polyfill.
All this are things, where one can think about integrating or using it in node.js, with a similar interface.

Maybe we have a http3Session.onWebTransportSession callback which fires (headers, wtSession) with a WebTransportSession object, and each WT session has onStream event that emits a WebTransportStream in turn. WebTransportSession would manage the control stream & underlying HTTP/3 session interactions, and WebTransportStreams would just give you an API for raw data & stream-linked datagrams. For users who are interested in the raw workings underneath, they can always reach down into the underlying HTTP/3 or QUIC session directly.

Yes something like this. But it is less dramatic.

Just food for thought, we don't need to define all this immediately anyway. We can focus on the internals in the short term and work out the user-facing surface later, I'm just starting to spitball about how it's all going to glue together.

Yes, first the internal and then the glue on top. But your vision is not so different from mine.

@martenrichter martenrichter force-pushed the webtransportinterfaces branch from fbb534d to ba65cd6 Compare July 4, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. quic Issues and PRs related to the QUIC implementation / HTTP/3.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants