3. 启动 HTTP/2
生成 HTTP 请求的实现需要发现服务器是否支持 HTTP/2.
HTTP/2 使用 [HTTP] Section 4.2 中定义的 "http" 和 "https" URI 方案, 默认端口号与 HTTP/1.1 [HTTP/1.1] 相同. 这些 URI 不包含任何关于上游服务器 (客户端希望与之建立连接的直接对等方) 支持哪些 HTTP 版本的指示.
确定 HTTP/2 支持的方式对于 "http" 和 "https" URI 不同. "https" URI 的发现见 Section 3.2. 对 "http" URI 的 HTTP/2 支持只能通过带外方式发现, 并且需要如 Section 3.3 所述的先验知识.
3.1. HTTP/2 版本标识
本文档定义的协议有两个标识符. 基于任一标识符创建连接都意味着使用本文档描述的传输、分帧和消息语义.
-
字符串 "h2" 标识 HTTP/2 使用传输层安全性 (Transport Layer Security, TLS) 的协议; 参见 Section 9.2. 该标识符用于 TLS 应用层协议协商 (Application-Layer Protocol Negotiation, ALPN) 扩展 [TLS-ALPN] 字段, 以及任何标识 TLS 上 HTTP/2 的位置.
"h2" 字符串被序列化为 ALPN 协议标识符时, 是两个八位组序列: 0x68, 0x32.
-
"h2c" 字符串以前用作 HTTP Upgrade 机制的 Upgrade 头字段 (Section 7.8 of [HTTP]) 中的令牌. 这种用法从未广泛部署, 并由本文档废弃. 曾与升级到 "h2c" 一起使用的 HTTP2-Settings 头字段也同样如此.
3.2. 为 "https" URI 启动 HTTP/2
向 "https" URI 发起请求的客户端使用带 ALPN 扩展 [TLS-ALPN] 的 TLS [TLS13].
TLS 上的 HTTP/2 使用 "h2" 协议标识符. 客户端 MUST NOT 发送 "h2c" 协议标识符, 服务器也 MUST NOT 选择它; "h2c" 协议标识符描述的是不使用 TLS 的协议.
TLS 协商完成后, 客户端和服务器 MUST 都发送连接前言 (connection preface, Section 3.4).
3.3. 使用先验知识启动 HTTP/2
客户端可以通过其他方式获知特定服务器支持 HTTP/2. 例如, 客户端可以被配置为知道某个服务器支持 HTTP/2.
知道服务器支持 HTTP/2 的客户端可以建立 TCP 连接, 并发送连接前言 (Section 3.4), 后跟 HTTP/2 帧. 服务器可以通过连接前言的存在识别这些连接. 这只影响明文 TCP 上 HTTP/2 连接的建立; TLS 上的 HTTP/2 连接 MUST 使用 TLS 中的协议协商 [TLS-ALPN].
同样, 服务器 MUST 发送连接前言 (Section 3.4).
在没有额外信息的情况下, 先前支持 HTTP/2 并不能强烈表明给定服务器将继续支持未来连接上的 HTTP/2. 例如, 服务器配置可能发生变化, 集群服务器中的实例配置可能不同, 网络条件也可能变化.
3.4. HTTP/2 连接前言
在 HTTP/2 中, 每个端点都需要发送连接前言, 作为对正在使用的协议的最终确认, 并建立 HTTP/2 连接的初始设置. 客户端和服务器分别发送不同的连接前言.
客户端连接前言以 24 个八位组序列开始, 其十六进制表示为:
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
也就是说, 连接前言以字符串 "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 开始. 该序列 MUST 后跟一个 SETTINGS 帧 (Section 6.5), 该帧 MAY 为空. 客户端将客户端连接前言作为连接上的首批应用数据八位组发送.
Note: 选择客户端连接前言的目的, 是使大多数 HTTP/1.1 或 HTTP/1.0 服务器和中介不会尝试处理后续帧. 请注意, 这并未解决 [TALKING] 中提出的问题.
服务器连接前言由一个可能为空的 SETTINGS 帧 (Section 6.5) 组成, 该帧 MUST 是服务器在 HTTP/2 连接中发送的第一个帧.
作为连接前言一部分从对等方收到的 SETTINGS 帧 MUST 在发送连接前言之后被确认 (参见 Section 6.5.3).
为避免不必要的延迟, 允许客户端在发送客户端连接前言后立即向服务器发送其他帧, 而无需等待接收服务器连接前言. 但需要注意, 服务器连接前言中的 SETTINGS 帧可能包含必然改变客户端预期通信方式的设置. 收到 SETTINGS 帧后, 客户端应遵守已建立的任何设置. 在某些配置中, 服务器可能在客户端发送其他帧之前传输 SETTINGS, 从而提供避免该问题的机会.
客户端和服务器 MUST 将无效连接前言视为 PROTOCOL_ERROR 类型的连接错误 (Section 5.4.1). 在这种情况下 MAY 省略 GOAWAY 帧 (Section 6.8), 因为无效前言表明对等方未使用 HTTP/2.