RFC 9114
HTTP/3 —— 把 9110 的语义映射到 QUIC。帧还在,流交给运输层;字段压缩是 QPACK(RFC 9204)。
h3,请求走客户端发起的双向流(0/4/8…),字段压缩在 RFC 9204 不在 9114。同一套语义,运输换成 QUIC
HTTP semantics ([HTTP]) are used for a broad range of services on the Internet. These semantics have most commonly been used with HTTP/1.1 and HTTP/2. HTTP/1.1 has been used over a variety of transport and session layers, while HTTP/2 has been used primarily with TLS over TCP. HTTP/3 supports the same semantics over a new transport protocol: QUIC.
[……下接 HTTP/2 在 TCP 上的队头阻塞]
HTTP/2 ([HTTP/2]) introduced a binary framing and multiplexing layer to improve latency without modifying the transport layer. However, because the parallel nature of HTTP/2's multiplexing is not visible to TCP's loss recovery mechanisms, a lost or reordered packet causes all active transactions to experience a stall regardless of whether that transaction was directly impacted by the lost packet.
[……下接委托给 QUIC]
This document defines HTTP/3: a mapping of HTTP semantics over the QUIC transport protocol, drawing heavily on the design of HTTP/2. HTTP/3 relies on QUIC to provide confidentiality and integrity protection of data; peer authentication; and reliable, in-order, per- stream delivery. While delegating stream lifetime and flow-control issues to QUIC, a binary framing similar to the HTTP/2 framing is used on each stream. Some HTTP/2 features are subsumed by QUIC, while other features are implemented atop QUIC.
[……下接概览:帧仍在,多路复用交给 QUIC]
HTTP/3 provides a transport for HTTP semantics using the QUIC transport protocol and an internal framing layer similar to HTTP/2. Once a client knows that an HTTP/3 server exists at a certain endpoint, it opens a QUIC connection. QUIC provides protocol negotiation, stream-based multiplexing, and flow control. Discovery of an HTTP/3 endpoint is described in Section 3.1. Within each stream, the basic unit of HTTP/3 communication is a frame (Section 7.2). Each frame type serves a different purpose. For example, HEADERS and DATA frames form the basis of HTTP requests and responses (Section 4.1). Frames that apply to the entire connection are conveyed on a dedicated control stream. Multiplexing of requests is performed using the QUIC stream abstraction, which is described in Section 2 of [QUIC-TRANSPORT]. Each request-response pair consumes a single QUIC stream. Streams are independent of each other, so one stream that is blocked or suffers packet loss does not prevent progress on other streams.
注解
9110 的方法、状态码、字段语义不变。9113 把它们编成 TCP 上的帧和流;9114 改成 QUIC 上的映射。差别首先是运输:TCP+TLS 换成 QUIC(里面已经有 TLS 1.3)。
HTTP/2 的多路复用 TCP 看不见,丢一个段会卡住同连接所有事务。QUIC 按流做可靠与流控,一条流丢包不挡别的流——这是 9114 相对 9113 最硬的差异。
HTTP/3 仍有帧(HEADERS / DATA / SETTINGS…),但帧跑在 QUIC 流里面。连接级控制走专用 control stream。一条请求/响应对消耗一条 QUIC 流。
h3 是两个八位组 0x68 0x33
Unless some other mechanism is used to select HTTP/3, the token "h3" is used in the Application-Layer Protocol Negotiation (ALPN; see [RFC7301]) extension during the TLS handshake.
[……下接连接建立]
QUIC version 1 uses TLS version 1.3 or greater as its handshake protocol. HTTP/3 clients MUST support a mechanism to indicate the target host to the server during the TLS handshake. If the server is identified by a domain name ([DNS-TERMS]), clients MUST send the Server Name Indication (SNI; [RFC6066]) TLS extension unless an alternative mechanism to indicate the target host is used. QUIC connections are established as described in [QUIC-TRANSPORT]. During connection establishment, HTTP/3 support is indicated by selecting the ALPN token "h3" in the TLS handshake. Support for other application-layer protocols MAY be offered in the same handshake. While connection-level options pertaining to the core QUIC protocol are set in the initial crypto handshake, settings specific to HTTP/3 are conveyed in the SETTINGS frame. After the QUIC connection is established, a SETTINGS frame MUST be sent by each endpoint as the initial frame of their respective HTTP control stream.
[……下接 ALPN 登记]
The "h3" string identifies HTTP/3:
Protocol: HTTP/3
Identification Sequence: 0x68 0x33 ("h3")注解
除非另有机制,选 HTTP/3 就在 TLS 握手里用 ALPN 标识 h3(0x68 0x33)。QUIC v1 的握手是 TLS 1.3 或更高。域名访问必须送 SNI(除非用了别的指示主机的办法)。
QUIC 自己的参数在加密握手里谈;HTTP/3 自己的设置在 SETTINGS 帧里,而且必须是各自 control stream 上的第一帧。
UDP 被挡时客户端 SHOULD 退回基于 TCP 的 HTTP。可以用 Alt-Svc 宣告“同主机另一个 UDP 端口有 h3”。http URI 不能直接用 HTTP/3 当权威访问,因为权威定义绑的是 TCP。
请求流是客户端发起的双向流:0、4、8…
A client sends an HTTP request on a request stream, which is a client-initiated bidirectional QUIC stream; see Section 6.1. A client MUST send only a single request on a given stream.
[……下接 §6 流映射]
A QUIC stream provides reliable in-order delivery of bytes, but makes no guarantees about order of delivery with regard to bytes on other streams. In version 1 of QUIC, the stream data containing HTTP frames is carried by QUIC STREAM frames, but this framing is invisible to the HTTP framing layer. The transport layer buffers and orders received stream data, exposing a reliable byte stream to the application. Although QUIC permits out-of-order delivery within a stream, HTTP/3 does not make use of this feature. QUIC streams can be either unidirectional, carrying data only from initiator to receiver, or bidirectional, carrying data in both directions. Streams can be initiated by either the client or the server. For more detail on QUIC streams, see Section 2 of [QUIC-TRANSPORT]. When HTTP fields and data are sent over QUIC, the QUIC layer handles most of the stream management. HTTP does not need to do any separate multiplexing when using QUIC: data sent over a QUIC stream always maps to a particular HTTP transaction or to the entire HTTP/3 connection context.
[……下接双向请求流]
All client-initiated bidirectional streams are used for HTTP requests and responses. A bidirectional stream ensures that the response can be readily correlated with the request. These streams are referred to as request streams. This means that the client's first request occurs on QUIC stream 0, with subsequent requests on streams 4, 8, and so on. In order to permit these streams to open, an HTTP/3 server SHOULD configure non- zero minimum values for the number of permitted streams and the initial stream flow-control window. So as to not unnecessarily limit parallelism, at least 100 request streams SHOULD be permitted at a time.
[……下接单向流头与类型]
Unidirectional streams, in either direction, are used for a range of
purposes. The purpose is indicated by a stream type, which is sent
as a variable-length integer at the start of the stream. The format
and structure of data that follows this integer is determined by the
stream type.
Unidirectional Stream Header {
Stream Type (i),
}
Figure 1: Unidirectional Stream Header
Two stream types are defined in this document: control streams
(Section 6.2.1) and push streams (Section 6.2.2). [QPACK] defines
two additional stream types. Other stream types can be defined by
extensions to HTTP/3; see Section 9 for more details. Some stream
types are reserved (Section 6.2.3).[……下接 control stream]
A control stream is indicated by a stream type of 0x00. Data on this stream consists of HTTP/3 frames, as defined in Section 7.2. Each side MUST initiate a single control stream at the beginning of the connection and send its SETTINGS frame as the first frame on this stream. If the first frame of the control stream is any other frame type, this MUST be treated as a connection error of type H3_MISSING_SETTINGS. Only one control stream per peer is permitted; receipt of a second stream claiming to be a control stream MUST be treated as a connection error of type H3_STREAM_CREATION_ERROR. The sender MUST NOT close the control stream, and the receiver MUST NOT request that the sender close the control stream. If either control stream is closed at any point, this MUST be treated as a connection error of type H3_CLOSED_CRITICAL_STREAM. Connection errors are described in Section 8.
注解
客户端发起的双向流 = 请求流。第一条请求在 QUIC stream 0,随后 4、8、12…(客户端双向流的 ID 步长是 4)。服务器不得用服务器发起的双向流,除非谈过扩展。
QUIC 流之间不排序。HTTP/3 不用 QUIC 提供的“流内乱序交付”。多路复用不必再做一遍:一条 QUIC 流对应一次 HTTP 事务,或对应整个连接上下文。
单向流开头是变长整数 Stream Type。本文件定义 control = 0x00、push;QPACK 另外定义编码器/解码器流。每端必须在开头建一条 control stream,第一帧必须是 SETTINGS;缺了就是 H3_MISSING_SETTINGS。control stream 不能关,关上就是 H3_CLOSED_CRITICAL_STREAM。
两端的传输参数必须允许对端至少建 3 条单向流(control + QPACK 一对),并建议给每条至少 1024 字节流控额度。请求流建议至少同时允许 100 条。
字段压缩不在 9114 里规定算法
As in HTTP/2, request and response fields are compressed for transmission. Because HPACK ([HPACK]) relies on in-order transmission of compressed field sections (a guarantee not provided by QUIC), HTTP/3 replaces HPACK with QPACK ([QPACK]). QPACK uses separate unidirectional streams to modify and track field table state, while encoded field sections refer to the state of the table without modifying it.
[……下接 §4.2.1]
[QPACK] describes a variation of HPACK that gives an encoder some control over how much head-of-line blocking can be caused by compression. This allows an encoder to balance compression efficiency with latency. HTTP/3 uses QPACK to compress header and trailer sections, including the control data present in the header section.
[……下接附录 A.2.2 为什么换掉 HPACK]
HPACK was designed with the assumption of in-order delivery. A sequence of encoded field sections must arrive (and be decoded) at an endpoint in the same order in which they were encoded. This ensures that the dynamic state at the two endpoints remains in sync. Because this total ordering is not provided by QUIC, HTTP/3 uses a modified version of HPACK, called QPACK. QPACK uses a single unidirectional stream to make all modifications to the dynamic table, ensuring a total order of updates. All frames that contain encoded fields merely reference the table state at a given time without modifying it. [QPACK] provides additional details.
[……下接规范性引用]
[QPACK] Krasic, C., Bishop, M., and A. Frindell, Ed., "QPACK:
Field Compression for HTTP/3", RFC 9204,
DOI 10.17487/RFC9204, June 2022,
<https://www.rfc-editor.org/info/rfc9204>.注解
HPACK 假定压缩指令按发送顺序到达。QUIC 不保证跨流次序,所以 HTTP/3 换成 QPACK。算法、动态表、编码器/解码器流都在 RFC 9204。说“9114 定义了 QPACK”是错的。
QPACK 用一条单向流专门改动态表,保证更新全序;HEADERS 里的编码字段只引用某个时刻的表,不改表。这和 HPACK 把改表指令与字段块绑在一起不同。
9114 只规定:字段块怎么进 HEADERS / PUSH_PROMISE,以及必须给 QPACK 留两条单向流。
抓包对照
先当 QUIC 抓,再看 TLS 里的 ALPN h3。应用层要会话密钥才能解 1-RTT。
- 过滤器两层:运输是
quic,应用是解密后的http3。ClientHello 里出现h3只证明客户端提议。 - 没有 HTTP/2 那种 24 字节
PRI * HTTP/2.0前言。HTTP/3 的“开场”是各自 control stream 上的 SETTINGS。 - 一个 UDP 数据报里可以叠 Initial + Handshake + 1-RTT。短头 1-RTT 仍要密钥。
- QPACK 编码器/解码器流是单向流,不是请求流。不要在 stream 0 上找动态表更新。
考点与易错点
- HTTP/3 = 9110 语义 + QUIC 运输。ALPN 是
h3(0x68 0x33),不是h2,也没有已部署的明文 h3c。 - 相对 9113:多路复用和流控交给 QUIC,不再有 TCP 层队头阻塞;HPACK 换成 QPACK(RFC 9204)。
- 请求流 = 客户端发起的双向流,ID 0、4、8…。服务器不得擅自开双向流。
- 每端一条 control stream(类型 0x00),第一帧必须是 SETTINGS,且不能关闭。
- QPACK 属于 RFC 9204。9114 只规定怎么装帧、怎么留流。
- 抓包用
udp port 443+quic,不要用tcp port 443或http2。