Skip to content

Commit

Permalink
http3: document the new client API
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Oct 14, 2024
1 parent cab06dd commit 9bd2144
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 14 deletions.
16 changes: 8 additions & 8 deletions content/docs/http3/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ weight: 2
This package provides a `http.RoundTripper` implementation that can be used on the `http.Client`:

```go
roundTripper := &http3.RoundTripper{
tr := &http3.Transport{
TLSClientConfig: &tls.Config{}, // set a TLS client config, if desired
QUICConfig: &quic.Config{}, // QUIC connection options
}
defer roundTripper.Close()
defer tr.Close()
client := &http.Client{
Transport: roundTripper,
Transport: tr,
}
```

Expand All @@ -25,7 +25,7 @@ The `http.Client` can then be used to perform HTTP requests over HTTP/3.
To use a custom `quic.Transport`, the function used to dial new QUIC connections can be configured:
```go
tr := quic.Transport{}
roundTripper := &http3.RoundTripper{
h3tr := &http3.Transport{
TLSClientConfig: &tls.Config{}, // set a TLS client config, if desired
QUICConfig: &quic.Config{}, // QUIC connection options
Dial: func(ctx context.Context, addr string, tlsConf *tls.Config, quicConf *quic.Config) (quic.EarlyConnection, error) {
Expand All @@ -41,11 +41,11 @@ roundTripper := &http3.RoundTripper{
This gives the application more fine-grained control over the configuration of the `quic.Transport`.


## Using the same UDP Socket for Server and Roundtripper
## Running Client and Server on the Same Socket

Since QUIC demultiplexes packets based on their connection IDs, it is possible allows running a QUIC server and client on the same UDP socket. This also works when using HTTP/3: HTTP requests can be sent from the same socket that a server is listening on.

To achieve this using this package, first initialize a single `quic.Transport`, and pass a `quic.EarlyListner` obtained from that transport to `http3.Server.ServeListener`, and use the `DialEarly` function of the transport as the `Dial` function for the `http3.RoundTripper`.
To achieve this using this package, first initialize a single `quic.Transport`, and pass a `quic.EarlyListner` obtained from that transport to `http3.Server.ServeListener`, and use the `DialEarly` function of the transport as the `Dial` function for the `http3.Transport`.

## Using 0-RTT

Expand All @@ -59,14 +59,14 @@ It is the application's responsibility to make sure that it is actually safe to


```go
rt := &http3.RoundTripper{
tr := &http3.Transport{
TLSClientConfig: &tls.Config{
ClientSessionCache: tls.NewLRUClientSessionCache(100),
},
}
req, err := http.NewRequest(http3.MethodGet0RTT, "https://my-server/path", nil)
// ... handle error ...
rt.RoundTrip(req)
tr.RoundTrip(req)
```

The code snippet shows all the knobs that need to be turned to send a request in 0-RTT data:
Expand Down
11 changes: 5 additions & 6 deletions content/docs/http3/datagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,19 @@ http.HandleFunc("/datagrams", func(w http.ResponseWriter, r *http.Request) {

## On the Client Side

On the client side, the client needs to use an `http3.SingleDestinationRoundTripper`. It is not possible to use HTTP datagrams when using an `http3.RoundTripper`.
On the client side, the client needs to use an `http3.ClientConn` from the `http3.Transport`. It is not possible to use HTTP datagrams when using the `Transport`'s `RoundTrip` method.

The `http3.SingleDestinationRoundTripper` manages a single QUIC connection to a remote server.
The `http3.ClientConn` manages a single QUIC connection to a remote server.

The client is required to check that the server enabled HTTP datagrams support by checking the SETTINGS:

```go
// ... dial a quic.Connection to the target server
// make sure to set the "h3" ALPN
rt := &http3.SingleDestinationRoundTripper{
Connection: qconn,
tr := &http3.Transport{
EnableDatagrams: true,
}
conn := rt.Start()
conn := tr.NewClientConn(qconn)
// wait for the server's SETTINGS
select {
case <-conn.ReceivedSettings():
Expand Down Expand Up @@ -125,4 +124,4 @@ rsp, err := str.ReadResponse()
// ... handle error ...
```

The `SingleDestinationRoundTripper` splits the sending of the HTTP request and the receiving of the HTTP response into two separate API calls (compare that to the standard library's `RoundTrip` function). The reason is that sending an HTTP request and receiving the HTTP response from the server takes (at least) one network roundtrip. RFC 9297 allows the sending of HTTP datagrams as soon as the request has been sent.
The `ClientCon` splits the sending of the HTTP request and the receiving of the HTTP response into two separate API calls (compare that to the standard library's `RoundTrip` function). The reason is that sending an HTTP request and receiving the HTTP response from the server takes (at least) one network roundtrip. RFC 9297 allows the sending of HTTP datagrams as soon as the request has been sent.

0 comments on commit 9bd2144

Please sign in to comment.