Web协议详解与抓包实战之HTTP/2【三】

Web协议详解与抓包实战之HTTP/2【三】

前言

《Web协议详解与抓包实战》课程学习,陶辉老师主讲

学习内容:

  1. HTTP–TLS/SSL–TCP/IP自上而下根据应用学习web协议HTTP/2详细知识
  2. 结合抓包工具实践验证:chrome下的network面板、Tcpdump、Wireshark

HTTP/2的概念和特性

HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),简称为h2(基于TLS/1.2或以上版本的加密连接)或h2c(非加密连接)[1],是HTTP协议的的第二个主要版本,使用于万维网

HTTP/2标准于2015年5月以RFC 7540正式发表。

HTTP/2 协议本身未要求必须使用加密,但是多数客户端 (例如 Firefox, Chrome, Safari, Opera, IE, Edge) 的开发者声明,他们只会实现通过TLS加密的HTTP/2协议,这使得经TLS加密的HTTP/2(即h2)成为了事实上的强制标准,而h2c事实上被主流浏览器废弃。

主要特性

  • 传输数据量的大幅减少
    • 二进制方式传输
    • 标头压缩:HPACK算法
  • 多路复用及相关功能
    • 消息优先级
  • 服务器消息推送
    • 并行推送

http2.0并没有改变http1.x的语义,只是把原来http1.x的header和body部分用frame重新封装了一层而已

image-20201216151044692

使用WireShark解密TLS-SSL报文

  • wireshark获取TLS握手阶段生成的密钥

image-20201125162753581

  • wireshark从TLS中解密出来的HTTP/2的报文

image-20201125162946231

h2c:在TCP上从HTTP1.1升级到HTTP/2

h2c与HTTP1.1协商握手升级到WebSocket非常相似

image-20201125170911963

第一步:协商返回101 Switching Protocols

image-20201125171314318

第二步:客户端发动Magic帧

image-20201125171119206

image-20201125171657939

统一的连接过程:h2与h2c统一

image-20201125171600941

h2:在TLS上从HTTP1.1升级到HTTP/2

  • ALPN扩展协商协议

image-20201125172619078

升级过程

  • Clinet Hello包
    • 在alpn扩展中罗列出所支持的协议

image-20201125172449821

  • Server Hello包
    • 服务端选择h2协议,告诉客户端

image-20201125172538157

  • 然后发送Magic帧

帧、消息、流的关系

HTTP/2核心概念

image-20201125173452038

Stream、Message、Frame之间的关系

  • Stream与Frame之间通过stream ID对应起来

image-20201125174214062

  • Message的组成:HEADERS Frame与 DATA Frame组成

image-20201125174349950

多路复用

  • 传输中无序,接收时组装

  • 同个stream必须按顺序传输,不同stream之间的顺序可随意

    image-20201125174745541

帧格式

Sream ID的作用

9字节标准帧头部

image-20201127104858255

  • 【作用一】:实现多路复用的关键

    • 接收端的实现可据此并发组装消息
    • 同一Stream内的frame必须是有序的
    • SETTINGS_MAX_CONCURRENT_STREAMS控制着并发的Stream数
  • 【作用二】:推送依赖性请求的关键

    • 由客户端建立的流必须是奇数
    • 由服务端建立的流必须是偶数

    image-20201127134336509

  • 【作用三】:流状态管理的约束性规定

    image-20201127135224324

  • 【作用四】:应用层流控仅影响数据帧

    • StreamID为0的流仅用于传输控制帧
  • image-20201127135501538

帧类型及设置帧的子类型(Setting设置帧)

9字节标准帧头部为参考,介绍帧长度、帧类型

image-20201127104858255

  • 帧长度:Length

image-20201127140435234

  • 帧类型:Type及Flags,对不同Type,Flags内容也相呼应不同

image-20201127140647850

  • Setting设置帧的格式(type=0x4):

    • 设置帧并不是协商,是发送方接收方通知其特性及能力

    • 一个设置帧可以同时设置多个对象

      image-20201127141912043

      • Identifier:设置对象
      • Value:设置值
    • 设置类型:

      image-20201127142150761

image-20201127142631122

HPACK算法

HPACK如何减少HTTP头部的大小

HPACK压缩算法:在传输过程中,简化消息内容,降低消息大小

  • 消息发送端和消息接受端共同维护一份静态表和一份动态表(这两个合起来充当字典的角色)

  • 每次请求时,发送方根据字典的内容以及一些特定指定,编码压缩消息头部

  • 接收方根据字典进行解码,并且根据指令来判断是否需要更新动态表

  • 三种压缩方式

    • 静态字典
    • 动态字典
    • 压缩算法:Huffman编码

静态字典:https://httpwg.org/specs/rfc7541.html#static.table.definition

  • 只包含已知的header字段
    • name:value都可以确定
    • 只有name

静态字典和动态字典又称为索引表

HPACK压缩示意

  • 先使用静态表,经过多次请求规范动态字典,最后再结合Huffman编码压缩

image-20201204162745674

索引表用法示意图

image-20201204162606677

HPACK中如何使用Huffman编码

原理:

  • 出现概率较大的符号采用较短的编码,概率较小的符号采用较长的编码

静态Huffman编码:https://httpwg.org/specs/rfc7541.html#huffman.code

image-20201204164609526

动态Huffman编码

Huffman树构造过程

image-20201204164725478

HPACK中整型数字的编码(即索引值编码)

  • 小于31的整型数字编码

image-20201204165501524

  • 整型大数的编码

image-20201204165716005

  • 整型大数的解码

image-20201204165757980

HPACK中头部名称与值的编码(HEADER帧)

  • HEADER帧的格式

image-20201215162457545

当HEADER帧过大时,后续会跟一个CONTINUATION持续帧(Type=0x9)

  • 跟在HEADER帧或者PUSH_PROMISE帧之后,来补充完整的HTTP头部

    image-20201215162746996

为了更好的理解Header Block Fragment

image-20201215164119228

  • 字面编码

    image-20201215164236155

接下来看实践方式:

  • 名称和值都在索引表中(包括静态表与动态表)

    • 编码方式:首位传1,其余7位传索引号

      image-20201215164539913

    • 例如:method: GET在静态索引表中的序号为2,应表示为1000 0010,HEX为82

    • wireshark看例子

      image-20201215170923512

  • 名称在索引表中,值需要编码传递,同时新增至动态表中

    • 编码方式:前两位01

      image-20201215171336984

    • wireshark例子

      image-20201215173900032

  • 名称、值都需要编码传递,同时新增至动态表中

    • 前两位传01

      image-20201215174025681

  • 名称在索引表中,值需要编码传递,且不更新至动态表中

    • 前四位传0000

      image-20201215174506744

  • 名称、值都需要编码传递,且不更新至动态表中

    • 前四位传0000

      image-20201215174614658

  • 名称在索引表中,值需要编码传递,且永远不更新至动态表中

    • 前四位传0001

      image-20201215174729479

  • 名称、值都需要编码传递,且永远不更新至动态表中

    • 前四位传0001

      image-20201215174711439

image-20201215174838263

服务器端的主动消息推送(PUSH_PROMISE帧)

  • 提前将资源推送至浏览器缓存
  • 特性:
    • 推送基于已经发送的请求
  • 实现方式:
    • 推送资源必须对应一个请求
    • 请求由服务器端PUSH_PROMISE帧发送
    • 响应在偶数ID的STREAM中发送

HTTP/1.1中,获取HTML后,需要CSS资源时:

image-20201216101249776

HTTP2中的PUSH_PROMISE方式

image-20201216101545636

  • PUSH帧的格式

    • type=0x5,并且只能由服务器推送

      image-20201216101831028

  • wireshark实例

    • stream 1 中通知客户端图片资源即将来临

    image-20201216102557617

    • stream 2 中发送图片资源

    image-20201216103104934

  • PUSH推送模式的禁用:

    image-20201216103210301

Stream流的状态变迁

  • Stream特性

    image-20201216111543568

  • Message特性

    image-20201216111703608

  • Stream流的状态

    • 帧符号及流状态解释

      image-20201216112555558

    • 流程图

      image-20201216112708493

RST_STREAM帧及常见的错误码

  • RST_STREAM帧(type=0x3)

    image-20201216113405009

  • 常见错误码:不仅仅用于RST_STREAM帧中,GOAWAY帧等也会用到

    image-20201216113536379

    image-20201216113640776

    image-20201216113701466

Stream优先级与资源分配原则(PRIORITY帧)

对不同的请求进行优先级的设置调整

  • PRIORITY优先级设置帧

    • image-20201216114858950

    • exclusive标志位

      image-20201216115331082

不同于TCP的流量控制

  • HTTP/1.1中由TCP连接上没有多路复用

    image-20201216145904009

  • HTTP/2中,多路复用意味着多个Stream必须共享TCP层的流量控制

    • 产生问题:多个Stream争夺TCP的流控制,互相干扰可能造成Stream阻塞

      image-20201216150148349

    • 代理服务器内存有限,上下游网速不一致时,通过流控管理内存

    • 所以,需要HTTP/2进行应用层的流控

如何进行应用层的流控?

  • 由应用层决定发送速度

    image-20201216150337392

  • WINDOW_UPDATE帧

    image-20201216150624145

  • wireshark实例

    image-20201216150821064

  • 流控制窗口

    image-20201216151004237

gRPC框架

HTTP/2存在的问题

  • TCP及TCP+TLS建链握手过多问题

    image-20201216152601654

  • 多路复用与TCP的队头阻塞问题

    • 本质上是TCP规定的资源必须有序到达

      image-20201216153041321

HTTP3 QUIC协议

  • QUIC协议的位置:

    image-20201216153219240

  • HTTP/2与QUIC协议比较

    image-20201216153712609

  • HTTP3的连接迁移

    • 允许客户端更换IP地址、端口后,仍然可以复用前连接
  • 解决对头阻塞问题

    image-20201216160058829

  • HTTP3:1RTT完全握手

    image-20201216160131834

七层负载均衡

image-20201216155617265

  • HTTP转换协议

    image-20201216155733352

    • WAF防火墙

      image-20201216155804301

  • 反向代理与缓存功能

    image-20201216155920707

    image-20201216155935721

参考

详解http-2头部压缩算法

HTTP/2的流状态

猜你喜欢

转载自blog.csdn.net/weixin_39664643/article/details/110238244