最近在研究HTTP 2相关的协议,且大多数CDN都是默认HTTP 2,所以记录一下HTTP 2的详细通信流程。

1、HTTP 2概述

Cloudflare统计,HTTP 2网站已经占到所有网站的50%,HTTP 3则占到了20.5%。所以HTTP 2在如今的网络环境中越来越重要。HTTP 2的RFC文档在此

HTTP 2通信常被分为两类,即h2ch2

h2c:是基于HTTP 1.1 Upgrade试探升级HTTP 2,或在C/S框架中客户端已知服务端支持HTTP 2,直接发送HTTP 2数据包,不论哪一种,其通信过程是都是明文的,这是极其不安全的,主流浏览器都不支持,也很少有人使用,所以这里我们不做讨论。

h2:是被大多数人推广使用的,即在TLS的ClientHello包中的ALPN(Application Layer Protocol Negotiation)扩展中就声明支持h2,若服务端支持h2,则会选中该扩展,发回客户端。随后TLS连接建立完之后,就可以直接用HTTP 2通信了。

2、帧结构

image.png

HTTP 2的帧(Frame)结构由固定9字节帧头(Frame Header)和可变长度帧负载(Frame Payload)组成,定义于RFC 7540。

字段长度说明
Length24bitPayload长度
Type8bit帧类型
Flags8bit与帧类型相关的标志位
R1bit保留位,必须为0
Stream Identifier31bit流ID,0表示连接级帧

Length:默认大小区间为为0~16,384(2^14),一旦超过默认最大值2^14(16384),发送方将不再允许发送,除非接收到接收方定义的SETTINGS_MAX_FRAME_SIZE(一般此值区间为2^14 ~ 2^24)值的通知
Type:帧类型,共10种,如下表所示
Flags:与帧类型相关的标志位,如END_STREAM表示流的一端关闭、END_HEADERS表示Header块结束、ACK表示确认SETTINGS或PING帧
R:保留位,必须为0
Stream Identifier:帧所属的流ID,0表示连接帧,如SETTINGS、PING、GOAWAY,奇数表示由客户端创建的流,偶数表示由服务端建立的流

Type帧类型简介
0x0DATA承载请求或响应的实体数据,受流量控制机制约束
0x1HEADERS传输请求或响应的首部块,使用HPACK压缩
0x2PRIORITY指定流的优先级和依赖关系
0x3RST_STREAM异常终止一个已存在的流
0x4SETTINGS交换连接级参数配置,仅使用流ID 0
0x5PUSH_PROMISE服务器推送时,声明即将发送的请求
0x6PING连接保活、RTT测量,携带8字节不透明数据
0x7GOAWAY通知对端即将关闭连接并指明最后可处理流
0x8WINDOW_UPDATE流量控制,更新连接或流的发送窗口
0x9CONTINUATION继续传输未在HEADERS/PUSH_PROMISE中完成的首部块

HTTP 2本质上没有改变HTTP语义,只是将HTTP的Header和Body部分重新用帧结构封装了一下。

HEADERS采用了HPCAK压缩算法,且仅有其使用。

3、通信流程

HTTP 2整体上还是遵循客户端请求-服务端响应的通信结构,只不过会多一些控制帧。

首先,客户端先发送Magic序列,这是一个固定的24字节序列,表明其要用HTTP 2协议通信,然后紧接着必须发送SETTING帧,之后还可能衔接WINDOW_UPDATE帧,随后则是HEADERS和DATA,且HEADERS必须先于DATA。

服务端在TLS握手结束后,立即同步发送SETTING帧。

标签: HTTP

添加新评论