HTTP/2协议
RFC文档及其他
https://httpwg.org/specs/rfc7540.html
https://pkg.go.dev/golang.org/x/net/http2#pkg-overview
https://www.rfc-editor.org/rfc/rfc7540.html#section-1
帧格式
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
Type (8bit) 1byte 帧类型
+---------------+------+--------------+
| Frame Type | Code | Section |
+---------------+------+--------------+
| DATA | 0x0 | Section 6.1 |
| HEADERS | 0x1 | Section 6.2 |
| PRIORITY | 0x2 | Section 6.3 |
| RST_STREAM | 0x3 | Section 6.4 |
| SETTINGS | 0x4 | Section 6.5 |
| PUSH_PROMISE | 0x5 | Section 6.6 |
| PING | 0x6 | Section 6.7 |
| GOAWAY | 0x7 | Section 6.8 |
| WINDOW_UPDATE | 0x8 | Section 6.9 |
| CONTINUATION | 0x9 | Section 6.10 |
+---------------+------+--------------+
Payload SETTINGS
+------------------------+------+---------------+---------------+
| Name | Code | Initial Value | Specification |
+------------------------+------+---------------+---------------+
| HEADER_TABLE_SIZE | 0x1 | 4096 | Section 6.5.2 |
| ENABLE_PUSH | 0x2 | 1 | Section 6.5.2 |
| MAX_CONCURRENT_STREAMS | 0x3 | (infinite) | Section 6.5.2 |
| INITIAL_WINDOW_SIZE | 0x4 | 65535 | Section 6.5.2 |
| MAX_FRAME_SIZE | 0x5 | 16384 | Section 6.5.2 |
| MAX_HEADER_LIST_SIZE | 0x6 | (infinite) | Section 6.5.2 |
+------------------------+------+---------------+---------------+
grpc建立连接流程
1. 建立tcp连接
2. 服务端发送SETTINGS
3. h2客户端发送 PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
4. 客户端发送SETTINGS
5. 客户端发送SETTINGS (Flags ack置1)
6. 客户端发送 请求HEADER、DATA
7. 服务端发送SETTINGS (Flags ack置1)
8. 服务端发送WINDOW_UPDATE
9. 服务端发送PING
10. 服务端发送HEADER
11. 服务端发送DATA
错误码
+---------------------+------+----------------------+---------------+
| Name | Code | Description | Specification |
+---------------------+------+----------------------+---------------+
| NO_ERROR | 0x0 | Graceful shutdown | Section 7 |
| PROTOCOL_ERROR | 0x1 | Protocol error | Section 7 |
| | | detected | |
| INTERNAL_ERROR | 0x2 | Implementation fault | Section 7 |
| FLOW_CONTROL_ERROR | 0x3 | Flow-control limits | Section 7 |
| | | exceeded | |
| SETTINGS_TIMEOUT | 0x4 | Settings not | Section 7 |
| | | acknowledged | |
| STREAM_CLOSED | 0x5 | Frame received for | Section 7 |
| | | closed stream | |
| FRAME_SIZE_ERROR | 0x6 | Frame size incorrect | Section 7 |
| REFUSED_STREAM | 0x7 | Stream not processed | Section 7 |
| CANCEL | 0x8 | Stream cancelled | Section 7 |
| COMPRESSION_ERROR | 0x9 | Compression state | Section 7 |
| | | not updated | |
| CONNECT_ERROR | 0xa | TCP connection error | Section 7 |
| | | for CONNECT method | |
| ENHANCE_YOUR_CALM | 0xb | Processing capacity | Section 7 |
| | | exceeded | |
| INADEQUATE_SECURITY | 0xc | Negotiated TLS | Section 7 |
| | | parameters not | |
| | | acceptable | |
| HTTP_1_1_REQUIRED | 0xd | Use HTTP/1.1 for the | Section 7 |
| | | request | |
+---------------------+------+----------------------+---------------+
如果事先已经知道服务器支持http2,那么在tcp三次握手完成后立即发送这个magic信息
That is, the connection preface starts with the string PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n).
This sequence MUST be followed by a SETTINGS frame (Section 6.5), which MAY be empty.
The client sends the client connection preface immediately upon receipt of a 101 (Switching Protocols) response (indicating a successful upgrade) or
as the first application data octets of a TLS connection.
If starting an HTTP/2 connection with prior knowledge of server support for the protocol,
the client connection preface is sent upon connection establishment.
GRPC协议
// GRPC 协议, 第1个字节表示是否压缩
// 第2-5个字节表示pb长度
// 第6个字节到末尾都是pb数据
浏览器的应用
GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: token68
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c