Skip to content

Commit 08b2f47

Browse files
committed
Document HTTP/3 transport contract and bump incubator deps
Signed-off-by: jeroen.veltman <jeroen.veltman@nextend.nl>
1 parent 2c521ad commit 08b2f47

3 files changed

Lines changed: 46 additions & 3 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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

rsocket-transport-netty/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ if (osdetector.classifier in ["linux-x86_64", "linux-aarch_64", "osx-x86_64", "o
2626
os_suffix = "::" + osdetector.classifier
2727
}
2828

29-
def netty_incubator_quic_version = "0.0.72.Final"
30-
def netty_incubator_http3_version = "0.0.29.Final"
29+
def netty_incubator_quic_version = "0.0.73.Final"
30+
def netty_incubator_http3_version = "0.0.30.Final"
3131

3232
dependencies {
3333
api project(':rsocket-core')

rsocket-transport-netty/src/main/java/io/rsocket/transport/netty/internal/Http3TransportBootstrap.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import reactor.netty.Connection;
5050

5151
public final class Http3TransportBootstrap {
52-
5352
private Http3TransportBootstrap() {}
5453

5554
public static Mono<DuplexConnection> connectClient(

0 commit comments

Comments
 (0)