【协议分析】HTTP2报文头及数据帧格式解析实例分析

一、HEAD HPACK压缩协议格式说明,HPACK压缩的二进制格式采用以下2种格式:
1、用索引标识头域,如下所示,0位固定为1,其它7bit标识索引值,索引参考下面的静态表格,如82代表 -> :method: GET。
     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 1 |        Index (7+)         |
   +---+---------------------------+

    Figure 5: Indexed Header Field

 +-------+-----------------------------+---------------+
          | Index | Header Name                 | Header Value  |
          +-------+-----------------------------+---------------+
          | 1     | :authority                  |               |
          | 2     | :method                     | GET           |
          | 3     | :method                     | POST          |
          | 4     | :path                       | /             |
          | 5     | :path                       | /index.html   |
          | 6     | :scheme                     | http          |
          | 7     | :scheme                     | https         |
          | 8     | :status                     | 200           |
          | 9     | :status                     | 204           |
          | 10    | :status                     | 206           |
          | 11    | :status                     | 304           |
          | 12    | :status                     | 400           |
          | 13    | :status                     | 404           |
          | 14    | :status                     | 500           |
          | 15    | accept-charset              |               |
          | 16    | accept-encoding             | gzip, deflate |
          | 17    | accept-language             |               |
          | 18    | accept-ranges               |               |
          | 19    | accept                      |               |
          | 20    | access-control-allow-origin |               |
          | 21    | age                         |               |
          | 22    | allow                       |               |
          | 23    | authorization               |               |
          | 24    | cache-control               |               |
          | 25    | content-disposition         |               |
          | 26    | content-encoding            |               |
          | 27    | content-language            |               |
          | 28    | content-length              |               |
          | 29    | content-location            |               |
          | 30    | content-range               |               |
          | 31    | content-type                |               |
          | 32    | cookie                      |               |
          | 33    | date                        |               |
          | 34    | etag                        |               |
          | 35    | expect                      |               |
          | 36    | expires                     |               |
          | 37    | from                        |               |
          | 38    | host                        |               |
          | 39    | if-match                    |               |
          | 40    | if-modified-since           |               |
          | 41    | if-none-match               |               |
          | 42    | if-range                    |               |
          | 43    | if-unmodified-since         |               |
          | 44    | last-modified               |               |
          | 45    | link                        |               |
          | 46    | location                    |               |
          | 47    | max-forwards                |               |
          | 48    | proxy-authenticate          |               |
          | 49    | proxy-authorization         |               |
          | 50    | range                       |               |
          | 51    | referer                     |               |
          | 52    | refresh                     |               |
          | 53    | retry-after                 |               |
          | 54    | server                      |               |
          | 55    | set-cookie                  |               |
          | 56    | strict-transport-security   |               |
          | 57    | transfer-encoding           |               |
          | 58    | user-agent                  |               |
          | 59    | vary                        |               |
          | 60    | via                         |               |
          | 61    | www-authenticate            |               |
          +-------+-----------------------------+---------------+
2、字符头域表示法
  2.1字符头域索引法,包括插入索引法和新命名法
 
   直接插入索引法:
     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 1 |      Index (6+)       |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
   新命名法:
        0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 1 |           0           |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
   40                                      | == Literal indexed ==
   0a                                      |   Literal name (len = 10)
   6375 7374 6f6d 2d6b 6579                | custom-key
   0d                                      |   Literal value (len = 13)
   6375 7374 6f6d 2d68 6561 6465 72        | custom-header
                                           | -> custom-key: custom-head\
                                           |   er
        
   2.1字符头域无索引法,不插入新索引和新命名法
   不插入新索引:
    0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 0 |  Index (4+)   |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
  
   04                                      | == Literal not indexed ==
                                           |   Indexed name (idx = 4)
                                           |     :path
   0c                                      |   Literal value (len = 12)
   2f73 616d 706c 652f 7061 7468           | /sample/path
                                           | -> :path: /sample/path

  新命名法:  
   0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 0 |       0       |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
   2.2从不索引,不插入新索引和新命名法
  
        0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 1 |  Index (4+)   |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
  
  


     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 1 |       0       |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+
   10                                      | == Literal never indexed ==
   08                                      |   Literal name (len = 8)
   7061 7373 776f 7264                     | password
   06                                      |   Literal value (len = 6)
   7365 6372 6574                          | secret
                                           | -> password: secret
                                          
二、实例分析:HTTP2数据带Haffman Code
00000000  50 52 49 20 2a 20 48 54  54 50 2f 32 2e 30 0d 0a PRI * HT TP/2.0..
00000010  0d 0a 53 4d 0d 0a 0d 0a  00 0c 04 00 00 00 00 00 ..SM.... ........
00000020  00 03 00 00 00 64 00 04  00 00 ff ff 00 39 01 05 .....d.. .....9..
00000030  00 00 00 01 41 8a a0 e4  1d 13 9d 09 b8 c8 00 0f ....A... ........
00000040  82 04 94 62 43 91 8a 47  55 a3 a1 89 d3 4d 0c 1a ...bC..G U....M..
00000050  a9 0b e5 79 d3 4d 1f 86  53 03 2a 2f 2a 90 7a 8d ...y.M.. S.*/*.z.
00000060  aa 69 d2 9a c4 c0 17 6d  71 2d 7f 07 1f          .i.....m q-...          

1、头部:                               
00000000  50 52 49 20 2a 20 48 54  54 50 2f 32 2e 30 0d 0a PRI * HT TP/2.0..
00000010  0d 0a 53 4d 0d 0a 0d 0a   ..SM....
2、设置帧:
长度:00 0c
TYPE: 04
FLAG: 00
FlowID: 00 00 00 00
MAXFLOWNUM FLAG:00 03
MAXFLOWNUM : 00 00 00 64
MAX Win FLAG: 00 04
MAX Win Size: 00 00 ff ff
3、报头帧
长度:00 39
TYPE: 01
FLAG: 05
FlowID: 00 00 00 01
报头数据,值部分数据采用了Haffman编码:
41 8a a0 e4  1d 13 9d 09 b8 c8 00 0f ....A... ........
00000040  82 04 94 62 43 91 8a 47  55 a3 a1 89 d3 4d 0c 1a ...bC..G U....M..
00000050  a9 0b e5 79 d3 4d 1f 86  53 03 2a 2f 2a 90 7a 8d ...y.M.. S.*/*.z.
00000060  aa 69 d2 9a c4 c0 17 6d  71 2d 7f 07 1f          .i.....m q-... 

41::authority
8a: len = 10 data = a0 e4  1d 13 9d 09 b8 c8 00 0f  data dec = localhost:3000

82: :method = Get

04: :path
94: len = 20 data 62 43 91 8a 47  55 a3 a1 89 d3 4d 0c 1a a9 0b e5 79 d3 4d 1f data dec /doc/manual/html/index.html

86: :scheme = http

53: :accept
03 len = 3 data = 2a 2f 2a */*

90: :accept-encoding = gzip,deflate
7a: :user-agent
8d: len = 13 data = aa 69 d2 9a c4 c0 17 6d  71 2d 7f 07 1f data dec = nghttp
/*
     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | ? | ? | ? | 1   1   1   1   1 |
   +---+---+---+-------------------+
   | 1 |    Value-(2^N-1) LSB      |
   +---+---------------------------+
                  ...
   +---+---------------------------+
   | 0 |    Value-(2^N-1) MSB      |
   +---+---------------------------+
*/

参考:hpack草案及HTTP2草案

你可能感兴趣的:(Protocol,Identifying)