网络知识
RFC 精读 · Application · Proposed Standard

RFC 9114

HTTP/3 —— 把 9110 的语义映射到 QUIC。帧还在,流交给运输层;字段压缩是 QPACK(RFC 9204)。

编号 / 标题
RFC 9114 · HTTP/3
发布
June 2022 · M. Bishop, Ed.
状态
Proposed Standard(不是 STD 编号)
关系
无 Obsoletes · 无 Updates · 无 Updated by(对照 rfc-editor JSON,2026-08)
原文
rfc-editor HTML · 纯文本 · datatracker
配套
语义 9110 · HTTP/2 9113 · QUIC 9000 · QPACK 9204
读这一篇的目标:能说出 HTTP/3 是 9110 语义在 QUIC 上的映射,ALPN 标识是 h3,请求走客户端发起的双向流(0/4/8…),字段压缩在 RFC 9204 不在 9114。
§1 / §1.1 / §1.2 / §2

同一套语义,运输换成 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 流。

§3.1 / §3.2 / §11.1

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 标识 h30x68 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。

§4.1 / §6 Stream Mapping

请求流是客户端发起的双向流: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 条。

§2 / §4.2.1 / [QPACK] = RFC 9204

字段压缩不在 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。

udp.port == 443 quic tls.handshake.extensions_alpn_str == "h3" ALPN: 客户端 offer 在 ClientHello(QUIC Initial 解开后可见) 服务器选择在 TLS 1.3 EncryptedExtensions(需密钥) 解密之后: http3 quic.stream.stream_id == 0 第一条请求流 http3.frame_type HEADERS / DATA / SETTINGS qpack tcpdump: udp port 443 Wireshark: quic && tls.handshake.extensions_alpn_str == "h3" 配置 SSLKEYLOGFILE 后再看 http3 不要用 tcp port 443 抓 HTTP/3。

考点与易错点

  1. HTTP/3 = 9110 语义 + QUIC 运输。ALPN 是 h3(0x68 0x33),不是 h2,也没有已部署的明文 h3c。
  2. 相对 9113:多路复用和流控交给 QUIC,不再有 TCP 层队头阻塞;HPACK 换成 QPACK(RFC 9204)。
  3. 请求流 = 客户端发起的双向流,ID 0、4、8…。服务器不得擅自开双向流。
  4. 每端一条 control stream(类型 0x00),第一帧必须是 SETTINGS,且不能关闭。
  5. QPACK 属于 RFC 9204。9114 只规定怎么装帧、怎么留流。
  6. 抓包用 udp port 443 + quic,不要用 tcp port 443http2