This commit is contained in:
parent
cf3cccd3ca
commit
04760fd88d
15 changed files with 136 additions and 20 deletions
|
|
@ -11,8 +11,14 @@ Native clients and hosts share the same connection shape after the opening hands
|
|||
| `client_id` | Confirmed or assigned ID with `crypto` | Authenticated or guest client ID with `crypto` | Authenticated or guest client ID with `crypto` |
|
||||
| `auth_state` | Authentication result with `crypto` | Authentication result with `crypto` | Authentication result with `crypto` |
|
||||
| `request_path` | — | — | WebTransport CONNECT path (e.g. `/mtp`) |
|
||||
| `remote_addr` | Server `SocketAddr` when available | Peer `SocketAddr` | Peer `SocketAddr` |
|
||||
|
||||
`WebMTPConnection`, returned by `MTPWebServer::accept()`, exposes the same members as the native host connection plus `request_path`, which contains the HTTP/3 path used for the WebTransport extended CONNECT request.
|
||||
|
||||
Server-side MTP connections expose `remote_addr`, the peer address observed by
|
||||
QUIC. HTTP/3 route handlers receive the same address as `Http3Request::remote_addr`.
|
||||
It is transport metadata and should not be treated as an authenticated identity;
|
||||
behind a proxy, use the proxy's trusted forwarding mechanism separately.
|
||||
The host connection also exposes a version-scoped `codec` and, for an authenticated client, its `client_public_key`. The native client connection also exposes these methods:
|
||||
|
||||
| Method | Behavior |
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ not match the route. Query strings remain available through
|
|||
|
||||
## HTTP/3 Requests and Responses
|
||||
|
||||
`Http3Request` contains `method`, `uri`, `headers`, and an optional buffered `body` represented by `bytes::Bytes`. `Http3Response::status`, `header`, and `body` build a buffered response. `try_header` returns an error for invalid header names or values. `stream` takes a `tokio::sync::mpsc::Receiver<Bytes>` for incremental response chunks.
|
||||
`Http3Request` contains `method`, `uri`, `headers`, the connecting `remote_addr`, and an optional buffered `body` represented by `bytes::Bytes`. `Http3Response::status`, `header`, and `body` build a buffered response. `try_header` returns an error for invalid header names or values. `stream` takes a `tokio::sync::mpsc::Receiver<Bytes>` for incremental response chunks.
|
||||
|
||||
```rust
|
||||
use bytes::Bytes;
|
||||
|
|
@ -78,6 +78,10 @@ async fn health(_request: Http3Request, response: Http3Response) -> Http3Respons
|
|||
response.status(StatusCode::OK).body("ok")
|
||||
}
|
||||
|
||||
async fn whoami(request: Http3Request, response: Http3Response) -> Http3Response {
|
||||
response.body(format!("client: {}", request.remote_addr))
|
||||
}
|
||||
|
||||
async fn stream_numbers(_request: Http3Request, response: Http3Response) -> Http3Response {
|
||||
let (tx, rx) = mpsc::channel::<Bytes>(10);
|
||||
tokio::spawn(async move {
|
||||
|
|
@ -95,6 +99,7 @@ async fn stream_numbers(_request: Http3Request, response: Http3Response) -> Http
|
|||
|
||||
let web = WebServerConfig::new()
|
||||
.route("/health", health)?
|
||||
.route("/whoami", whoami)?
|
||||
.route_method(Method::GET, "/numbers", stream_numbers)?
|
||||
.fallback(|_request, response| async move {
|
||||
response.status(StatusCode::NOT_FOUND).body("not found")
|
||||
|
|
@ -124,7 +129,7 @@ while let Some(connection) = server.accept().await? {
|
|||
```
|
||||
> `MTPWebServer::new` consumes a `HostConfig` (not an `MTPHost` instance). It creates its own QUIC endpoint and does not share a port with a running `MTPHost`.
|
||||
|
||||
`server.accept()` returns `Option<WebMTPConnection>` for each WebTransport session. HTTP/3 routes do not surface through `accept()` because the server dispatches them internally. `WebMTPConnection` retains the negotiated version, codec, request path, description, sender, and receiver used by native MTP connections.
|
||||
`server.accept()` returns `Option<WebMTPConnection>` for each WebTransport session. HTTP/3 routes do not surface through `accept()` because the server dispatches them internally. `WebMTPConnection` retains the negotiated version, codec, request path, remote address, description, sender, and receiver used by native MTP connections.
|
||||
|
||||
### Authentication
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ while let Some(conn) = host.accept().await? {
|
|||
|
||||
`accept()` returns the shared connection shape in [MTP Connections](CONNECTIONS.md)
|
||||
after version negotiation and authentication, when enabled. The host-specific `codec` is scoped to the negotiated version, and `client_public_key` is set for authenticated clients.
|
||||
The connection's `remote_addr` is the peer `SocketAddr` observed by QUIC. It is
|
||||
network metadata, not an authenticated client identity.
|
||||
|
||||
## Version Negotiation
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue