|
| 1 | +# QUIC and HTTP/3 transport notes |
| 2 | + |
| 3 | +This module now contains prototype Netty transports for: |
| 4 | + |
| 5 | +- `quic://` via `QuicClientTransport` and `QuicServerTransport` |
| 6 | +- `h3://` via `Http3ClientTransport` and `Http3ServerTransport` |
| 7 | + |
| 8 | +## Current HTTP/3 transport contract |
| 9 | + |
| 10 | +The current `h3://` transport uses a long-lived HTTP/3 `POST` request stream: |
| 11 | + |
| 12 | +- path defaults to `/rsocket` |
| 13 | +- content type defaults to `application/rsocket` |
| 14 | +- the request body carries raw RSocket frames in both directions once the server accepts the stream |
| 15 | +- `Http3ClientTransport.connect()` completes only after the client receives a successful response headers frame |
| 16 | + |
| 17 | +This is intentionally narrower than a general-purpose HTTP/3 tunnel, but it is the shape that is currently proven by the local integration tests in this repository. |
| 18 | + |
| 19 | +## Why the transport still uses `POST` |
| 20 | + |
| 21 | +An investigation was done into moving the transport to HTTP/3 `CONNECT`, including: |
| 22 | + |
| 23 | +- switching the request method from `POST` to `CONNECT` |
| 24 | +- enabling the HTTP/3 `ENABLE_CONNECT_PROTOCOL` setting on both peers |
| 25 | +- trying the newer Netty incubator pair `netty-incubator-codec-http3:0.0.30.Final` and `netty-incubator-codec-classes-quic:0.0.73.Final` |
| 26 | +- attempting an extended `CONNECT` request shape with the `:protocol` pseudo-header |
| 27 | + |
| 28 | +Those experiments still caused the request stream to close before the client observed a successful handshake response, so they were not kept in the working transport implementation. |
| 29 | + |
| 30 | +## Upstream findings that matter |
| 31 | + |
| 32 | +The current Netty HTTP/3 codec line does model both regular and extended `CONNECT`, but the details are stricter than a simple method flip: |
| 33 | + |
| 34 | +- regular `CONNECT` expects only `:method` and `:authority` |
| 35 | +- extended `CONNECT` expects `:method`, `:scheme`, `:authority`, `:path`, and `:protocol` |
| 36 | +- `ENABLE_CONNECT_PROTOCOL` is negotiated through HTTP/3 settings and is disabled by default |
| 37 | + |
| 38 | +In practice, that means a future `CONNECT`-based RSocket transport likely needs a more complete negotiation flow than the current prototype has. |
| 39 | + |
| 40 | +## Good next steps |
| 41 | + |
| 42 | +- keep `POST` as the default transport contract until the `CONNECT` path is validated end-to-end |
| 43 | +- if `CONNECT` is revisited, start with a dedicated experiment around response-header timing and remote settings negotiation |
| 44 | +- add a focused handshake-level test before changing the public default again |
0 commit comments