Summary
Update the HTTP Client API to support the HTTP/3 protocol. This will allow applications and libraries to interact with HTTP/3 servers and get the benefits of HTTP/3 with minimal code changes.
Problem
The HTTP Client API is protocol agnostic and currently supports versions HTTP/1.1 and HTTP/2 of the HTTP protocol. It is designed to support future HTTP protocol versions with minimal API changes. HTTP/3 was standardized in 2022 by the Internet Engineering Task Force (IETF). HTTP/3 is an evolution of HTTP/2 based on QUIC (pronounced "quick"), a new transport protocol over the User Datagram Protocol (UDP). Unfortunately, the HTTP Client API does not support this latest version of the HTTP protocol. Providing HTTP/3 support, within the HttpClient, provides application with greater connectivity scope, and protocol options, when accessing the Web’s services and resources.
This CSR proposes to update the HTTP Client API to support the HTTP/3 protocol. This will allow applications and libraries to interact with HTTP/3 servers and get the benefits of HTTP/3 with minimal code changes. To achieve this goal several small API updates are needed.
The HttpClient.Version
enum currently only allows to choose between HTTP/1.1 and HTTP/2. In order to support HTTP/3, a new HTTP_3
constant is needed.
Unlike previous versions of the protocol, HTTP/3 doesn’t define a standard port for servers to be listening on. Though it is expected that most HTTP/3 servers deployed will listen on UDP port 443, this is neither guaranteed nor specified by the RFCs. Because HTTP/3 goes over UDP, and previous versions go over TCP, there is no way to define an upgrade mechanism or negotiate the HTTP version during the TLS handshake. Instead, HTTP servers may use HTTP Alternative Services (RFC 7838) to advertise the availability of resources over HTTP/3. An http client, which is ALT-SVC aware can utilise this information to access services and resources over HTTP/3. Additionally, an HTTP client may attempt to connect directly to an HTTP server, as per the authority (host:port) extracted from a URI, over HTTP/3. As such, an API with a flexible connection policy is desirable.
Compared to HTTP/2, HTTP/3 allows server pushes to be shared between several request/responses on the same connection. The PushPromiseHandler interface needs to be extended to support this. Also it should be possible to figure out whether two different requests were performed through the same, or through different connections, as it may have an impact on whether push promise responses can be shared between them.
Solution
The following API changes are proposed:
- extend the
HttpClient.Version
enum with a new constant value:HTTP_3
. - update the
HttpClient
class level API documentation to advertise and document HTTP/3 support, enhance theHttpClient.Builder.build
method API documentation - add a new sealed
HttpOption<T>
interface, to model options that can be set through theHttpRequest.Builder
. - add a new method
HttpRequest.Builder.setOption(HttpOption<T> option, T value)
allowing to configure a request with options. - add a new method
Optional<T> HttpRequest.getOption(HttpOption<T> option)
, to get the value of an option previously set on the request through theHttpRequest.Builder
. - define an
HttpOption.H3_DISCOVERY
constant, (of typeHttpOption<Http3DiscoveryMode>
) to model an option that allows to configure how to select/establish an HTTP/3 connection for the request, if the selected protocol version isHTTP_3
. - define an
HttpOption.Http3DiscoveryMode
enum with three values,ALT_SVC
,ANY
, andHTTP_3_URI_ONLY
that can be set as value for theH3_DISCOVERY
option, in order to change the default HttpClient behavior for a given request if needed. - update API documentation (and/or
@implNote
) of the variousBuilder::version
/HttpClient::version
/HttpRequest::version
methods to link back to the paragraph in theHttpClient
class-level@implNote
that talk about protocol version selection. - modify
HttpResponse.PushPromiseHandler
with two new default methods that will be called in the event that an HTTP/3 push promise is received. A class implementingHttpResponse.PushPromiseHandler
could override these methods to take advantage of the improved push promise mechanism brought by HTTP/3. The default implementation of these method will call existing methods so that existing push promise handlers still work, though they may not be able to take full advantage of the push promise sharing defined by HTTP/3. To support this a sealedPushPromiseHandler.PushId
interface, implemented by aPushId.Http3PushId
record is also defined. - add two new subclasses of IOException:
UnsupportedProtocolVersionException
, andStreamLimitException
- add and document in module-info a few jdk-specific system properties to help configure some coarse grain aspects of the HTTP/3 and underlying QUIC protocols implementation.
Specification
See attached SpecDiff and ApiDiff
Changes to module-info.java are only visible in the ApiDiff
- blocks
-
JDK-8291976 JEP 517: HTTP/3 for the HTTP Client API
-
- Candidate
-
- csr of
-
JDK-8349910 Implement JEP 517: HTTP/3 for the HTTP Client API
-
- Open
-