- Author(s): James Newton-King
- Approver: ejona86
- Status: Implemented
- Implemented in: grpc-dotnet
- Last updated: 2021-08-25
- Discussion at: https://groups.google.com/g/grpc-io/c/b1dWReBGyX4
HTTP/3 is the third and upcoming major version of the Hypertext Transfer Protocol used to exchange information on the World Wide Web, alongside HTTP/1.1 and HTTP/2.
This proposal is for how the gRPC protocol should run on top of the HTTP/3 protocol.
gRPC uses HTTP semantics but requires HTTP/2 for some features. HTTP/3 offers the same capabilities as HTTP/2, enabling all gRPC scenarios, along with new benefits offered by HTTP/3:
- Faster connection negotiation in fewer round-trips.
- Improved experience when there is connection packet loss.
- Client supports transitioning between networks.
PROTOCOL-HTTP2.md covers gRPC's HTTP semantics, along with some content that is specific to HTTP/2. Either this document should be generalized to include HTTP/2 and HTTP/3 information, or a new gRPC over HTTP/3 protocol document should be created.
n/a
The shape of gRPC HTTP requests and responses are unchanged in HTTP/3. The content in PROTOCOL-HTTP2.md that covers requests and responses can be referred to directly, without any duplication.
Notably, unlike gRPC-Web, the content-type of application/grpc
is unchanged. Apps
are still communicating with gRPC, but over HTTP/3 instead of HTTP/2.
The gRPC over HTTP/2 specification discusses HTTP2 transport mapping. The content discussed is mostly applicable to HTTP/3.
HTTP/3 stream IDs function largely the same as HTTP/2 stream IDs.
The relationship between DATA
frames and length prefixed messages are unchanged in HTTP/3.
HTTP/3 has different error codes
from HTTP/2. HTTP/3 errors are sent via QUIC frames instead of an RST_STREAM
HTTP frame.
HTTP/3 errors are used in three situations:
- Abruptly terminating streams
- Aborting reading of streams
- Immediately closing HTTP/3 connections
HTTP3 Code | HTTP2 Code | GRPC Code |
---|---|---|
H3_NO_ERROR(0x0100) | NO_ERROR(0) | INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively lameduck in some scenarios. |
H3_GENERAL_PROTOCOL_ERROR(0x0101) | PROTOCOL_ERROR(1) | INTERNAL |
H3_INTERNAL_ERROR(0x0102) | INTERNAL_ERROR(2) | INTERNAL |
H3_STREAM_CREATION_ERROR(0x0103) | n/a | INTERNAL |
H3_CLOSED_CRITICAL_STREAM(0x0104) | n/a | INTERNAL |
H3_FRAME_UNEXPECTED(0x0105) | FRAME_SIZE_ERROR | INTERNAL |
H3_FRAME_ERROR(0x0106) | FRAME_SIZE_ERROR | INTERNAL |
H3_EXCESSIVE_LOAD(0x0107) | ENHANCE_YOUR_CALM | RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. |
H3_ID_ERROR(0x0108) | n/a | INTERNAL |
H3_SETTINGS_ERROR(0x0109) | SETTINGS_TIMEOUT(4) | INTERNAL |
H3_MISSING_SETTINGS(0x010a) | SETTINGS_TIMEOUT(4) | INTERNAL |
H3_REQUEST_REJECTED(0x010b) | REFUSED_STREAM | UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. |
H3_REQUEST_CANCELLED(0x010c) | CANCEL(8) | Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. |
H3_REQUEST_INCOMPLETE(0x010d) | n/a | INTERNAL |
H3_MESSAGE_ERROR(0x010e) | n/a | INTERNAL |
H3_CONNECT_ERROR(0x010f) | CONNECT_ERROR | INTERNAL |
H3_VERSION_FALLBACK(0x0110) | n/a | INTERNAL |
n/a | FLOW_CONTROL_ERROR(3) | INTERNAL |
n/a | STREAM_CLOSED | No mapping as there is no open stream to propagate to. Implementations should log. |
n/a | COMPRESSION_ERROR | INTERNAL |
n/a | INADEQUATE_SECURITY | PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. |
GOAWAY
and PING
frames exist in HTTP/3 and serve the same purpose as in HTTP/2.
One notable difference is the GOAWAY
frame in HTTP/2 reports the last
successfully processed stream ID. In HTTP/3 the GOAWAY
frame ID value must be greater
than the last successfully processed stream ID.
When an RPC has exceeded its deadline, the server will reset the stream. In HTTP/2, a stream
is reset using the RST_STREAM
frame. The RST_STREAM
frame doesn't exist in HTTP/3.
Instead, this action is performed using a QUIC frame, called RESET_STREAM
.
Frame | Error code | Layer | |
---|---|---|---|
Deadline exceeded HTTP/2 | RST_STREAM | CANCEL(8) | HTTP |
Deadline exceeded HTTP/3 | RESET_STREAM | H3_REQUEST_CANCELLED(0x010c) | QUIC |
RESET_STREAM abruptly
terminates sending on a stream. An important difference between HTTP/2 and
HTTP/3 is frames are received out-of-order. Because of this, a RESET_STREAM
sent after a
completed response could still result in the response being aborted.
HTTP/3 also has the QUIC STOP_SENDING
frame. This frame is sent by the server when a
stream's response side completes before the request side. Using STOP_SENDING
alone isn't
appropriate for a deadline exceeded, because both stream directions should be aborted.
However, STOP_SENDING
should be sent along with RESET_STREAM
if the deadline is exceeded
while the request side is in-progress.
A client and server both need to support HTTP/3 for it to be used. There are two common scenarios for establishing an HTTP/3 connection:
- gRPC client uses TLS and is configured in advance to only use HTTP/3. The client starts a QUIC+HTTP/3 connection to server. If the server doesn't support HTTP/3 then the connection fails.
- gRPC client uses TLS and is configured to use HTTP/2 or greater. In this case an initial
HTTP/2 call is made, server returns response with an
alt-svc
header that tells the client that HTTP/3 is available. HTTP/2 connection is replaced with QUIC+HTTP/3 and future calls use HTTP/3. If the server doesn't support HTTP/3 then the client continues to use HTTP/2.
HTTP/3 requires TLS and will never be used by an insecure channel.
API for configuring channel HTTP negotation behavior is up to implementations.
HTTP/3 is an upcoming Internet Protocol. There needs to be a standardized agreement for how gRPC over HTTP/3 works to maintain interoperability in the gRPC eco-system.
A trial implementation in grpc-dotnet is underway. .NET 6 is adding preview support for HTTP/3 to the .NET server and client. grpc-dotnet leverages that underlying HTTP/3 support.
n/a