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