Skip to main content

3. 启动HTTP/2 (Starting HTTP/2)

HTTP/2连接是运行在TCP连接([TCP])之上的应用层协议。客户端是TCP连接发起者。

HTTP/2使用与HTTP/1.1相同的"http"和"https" URI方案。HTTP/2共享相同的默认端口号:用于"http" URI的80端口和用于"https" URI的443端口。因此,实现需要处理对包含这些URI方案的目标资源的请求,该请求的发现通过第3.1节中定义的方法或通过其他方式配置。

3.1 HTTP/2版本标识 (HTTP/2 Version Identification)

本文档中定义的协议有两个标识符。

字符串"h2"标识HTTP/2使用传输层安全性(TLS) [TLS12]的协议。这个标识符在TLS应用层协议协商(ALPN)扩展[TLS-ALPN]字段中使用,以及在标识HTTP/2 over TLS的任何地方使用。

"h2"字符串被序列化为ALPN协议标识符,作为两个八位字节序列:0x68、0x32。

字符串"h2c"标识运行在明文TCP上的HTTP/2。这个标识符在HTTP/1.1 Upgrade头部字段中使用,以及在标识HTTP/2 over TCP的任何地方使用。

"h2c"字符串是从ALPN标识符空间保留的,但描述了不使用TLS的协议。

协商"h2"或"h2c"意味着使用本文档中描述的传输、安全、帧和消息语义。

3.2 启动TLS上的HTTP/2 (Starting HTTP/2 for "https" URIs)

请求"https" URI的客户端使用带有应用层协议协商(ALPN)扩展[TLS-ALPN]的TLS [TLS12]。

HTTP/2 over TLS使用"h2"协议标识符。一旦TLS协商完成,客户端和服务器都必须发送连接前言(第3.5节)。

3.3 启动明文TCP上的HTTP/2 (Starting HTTP/2 for "http" URIs)

请求"http" URI而不先了解对HTTP/2的支持的客户端使用HTTP Upgrade机制([RFC7230]的第6.7节)。客户端通过使用带有"h2c"令牌的Upgrade头部字段的HTTP/1.1请求来实现。这样的HTTP/1.1请求必须包含一个HTTP2-Settings头部字段。

例如:

GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

包含有效负载主体的请求必须在完全发送请求之前完成。这意味着可以在升级之前完全发送一个大请求,而较小的请求可能无法在升级到HTTP/2之前完全发送。

如果客户端从先前的连接中知道服务器不支持Upgrade机制,则不应进行HTTP/1.1 Upgrade请求。相反,HTTP/2 over TCP可以通过先验知识启动(参见第3.4节)。

接受升级到HTTP/2的服务器必须用101(Switching Protocols)响应代码响应。在101响应之后,服务器可以开始发送HTTP/2帧。这些帧必须包括对发起升级的请求的响应。

例如:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c

[ HTTP/2连接 ]

服务器在Upgrade请求中收到的第一个HTTP/2帧必须是包含SETTINGS帧的SETTINGS帧(第6.5节)。在接收到101响应后,客户端必须发送连接前言(第3.5节),其中包括SETTINGS帧。

在升级之前发送的HTTP/1.1请求被分配流标识符1(参见第5.1.1节),具有默认优先级值(第5.3.5节)。流1从客户端向服务器隐式"半关闭"(参见第5.1节),因为请求作为HTTP/1.1请求完成。在开始HTTP/2连接后,流1用于响应。

3.4 通过先验知识启动HTTP/2 (Starting HTTP/2 with Prior Knowledge)

如果客户端知道服务器支持HTTP/2,则可以立即发送HTTP/2帧,而无需升级机制。此知识可以通过配置获得,例如,通过带外信息或先前的连接。

这种方式特别适用于在不使用TLS的情况下使用HTTP/2,但也可以与TLS一起使用,尽管使用TLS时ALPN是首选方法。

如果没有其他信息,支持HTTP/2的客户端可以通过发送带有Upgrade头部字段的HTTP/1.1请求来发现HTTP/2支持,即使它知道服务器可能支持HTTP/2。

服务器必须接受直接HTTP/2通信的连接前言(第3.5节),而无需此升级过程。使用先验知识发现服务器不支持HTTP/2的客户端必须放弃连接。

3.5 HTTP/2连接前言 (HTTP/2 Connection Preface)

在HTTP/2中,每个端点都需要发送连接前言作为使用的协议的最终确认,并建立HTTP/2连接的初始设置。客户端和服务器各自发送不同的连接前言。

客户端连接前言以24个八位字节的序列开始,十六进制表示为:

0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a

也就是说,连接前言以字符串"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"开始。这个序列必须紧跟一个SETTINGS帧(第6.5节),该帧可能为空。客户端在接收到服务器连接前言中的第一个设置帧后立即发送客户端连接前言。

客户端连接前言被选择为使其外观类似于HTTP/1.1请求。这样做的目的是防止HTTP/1.1服务器尝试处理HTTP/2连接。更多信息请参见[RFC7540]的附录A。

服务器连接前言由可能为空的SETTINGS帧(第6.5节)组成,该帧必须是服务器在HTTP/2连接中发送的第一个帧。

从客户端接收到连接前言的SETTINGS帧后,服务器可以开始发送帧。服务器必须等到接收到完整的连接前言后才能发送其它帧(除了SETTINGS帧)。

为了避免不必要的延迟,允许客户端在发送客户端连接前言后立即向服务器发送额外的帧,而无需等待接收服务器连接前言。但是,重要的是要注意,服务器连接前言SETTINGS帧可能包括必须在发送额外帧前必须遵守的参数。在接收到SETTINGS帧后,客户端应该遵守已建立的任何参数。在某些配置中,服务器可能在客户端发送额外帧之前传输SETTINGS,从而提供避免此问题的机会。


上一章: 2. HTTP/2协议概览 (HTTP/2 Protocol Overview)
下一章: 4. HTTP帧 (HTTP Frames)