Class HTTP3Client

All Implemented Interfaces:
AutoCloseable, Container, Destroyable, Dumpable, Dumpable.DumpableContainer, LifeCycle

public class HTTP3Client extends ContainerLifeCycle implements AutoCloseable

HTTP3Client provides an asynchronous, non-blocking implementation to send HTTP/3 frames to a server.

Typical usage:

// Client-side QUIC configuration to configure QUIC properties.
ClientQuicConfiguration quicConfig = new ClientQuicConfiguration(sslClient, null);

// Create the HTTP3Client instance.
HTTP3Client http3Client = new HTTP3Client(quicConfig);

// To configure HTTP/3 properties.
HTTP3Configuration h3Config = http3Client.getHTTP3Configuration();

http3Client.start();

// HTTP3Client request/response usage.

// Connect to host.
String host = "webtide.com";
int port = 443;
Session.Client session = http3Client
    .connect(new InetSocketAddress(host, port), new Session.Client.Listener() {})
    .get(5, TimeUnit.SECONDS);

// Prepare the HTTP request headers.
HttpFields.Mutable requestFields = HttpFields.build();
requestFields.put("User-Agent", http3Client.getClass().getName() + "/" + Jetty.VERSION);

// Prepare the HTTP request object.
MetaData.Request request = new MetaData.Request("PUT", HttpURI.from("https://" + host + ":" + port + "/"), HttpVersion.HTTP_3, requestFields);

// Create the HTTP/3 HEADERS frame representing the HTTP request.
HeadersFrame headersFrame = new HeadersFrame(request, false);

// Send the HEADERS frame to create a request stream.
Stream stream = session.newRequest(headersFrame, new Stream.Listener()
{
    @Override
    public void onResponse(Stream stream, HeadersFrame frame)
    {
        // Inspect the response status and headers.
        MetaData.Response response = (MetaData.Response)frame.getMetaData();

        // Demand for response content.
        stream.demand();
    }

    @Override
    public void onDataAvailable(Stream stream)
    {
        Stream.Data data = stream.readData();
        if (data != null)
        {
            // Process the response content chunk.
        }
        // Demand for more response content.
        stream.demand();
    }
}).get(5, TimeUnit.SECONDS);

// Use the Stream object to send request content, if any, using a DATA frame.
ByteBuffer requestChunk1 = UTF_8.encode("hello");
stream.data(new DataFrame(requestChunk1, false))
    // Subsequent sends must wait for previous sends to complete.
    .thenCompose(s ->
    {
        ByteBuffer requestChunk2 = UTF_8.encode("world");
        s.data(new DataFrame(requestChunk2, true));
    });

IMPLEMENTATION NOTES.

Each call to connect(SocketAddress, Session.Client.Listener) creates a new DatagramChannelEndPoint with the correspondent ClientQuicConnection.

Each ClientQuicConnection manages one ClientQuicSession with the corresponding ClientHTTP3Session.

Each ClientHTTP3Session manages the mandatory encoder, decoder and control streams, plus zero or more request/response streams.

GENERIC, TCP-LIKE, SETUP FOR HTTP/1.1 AND HTTP/2
HTTP3Client - dgramEP - ClientQuiConnection - ClientQuicSession - ClientProtocolSession - TCPLikeStream

SPECIFIC SETUP FOR HTTP/3
                                                                                     /- [Control|Decoder|Encoder]Stream
HTTP3Client - dgramEP - ClientQuiConnection - ClientQuicSession - ClientHTTP3Session -* HTTP3Streams

HTTP/3+QUIC support is experimental and not suited for production use. APIs may change incompatibly between releases.