Skip to content
大纲

HTTP

HTTP 的特点

  • 灵活
  • 请求-响应
  • 传输可靠
  • 无状态

HTTP 的发展

HTTP 最初的版本为 0.9,仅定义了建立 TCP 连接后,客户端向服务端请求的资源,进行支持 GET 方法;
HTTP 1.0 版本初步定义了传输规则:增加了 POST、HEAD 方法,增加了 Header 头,定义了状态码且支持任意格式数据
HTTP 1.1 版本除了完善传输规则并增加了 持久连接、管道机制、缓存控制、断点续传、虚拟网络 等特性
目前 1.1 版本也是主要使用的版本,由于 HTTP 的数据为明文传输,存在安全隐患,因而发展出了 HTTPS 协议,通过证书确保通信双方可信,传输时对数据加密避免被第三方接持
HTTP 2 优化了通信效率,对数据头部进行压缩,实现了多路复用减少请求连接

HTTP 1.x

报文格式

  • 请求报文:请求行(方法 地址 协议) - 通用信息头 - 请求头 - 实体头(空行) - 报文主体
  • 响应报文:状态行(协议 状态) - 通用信息头 - 响应头 - 实体头(空行) - 报文主体

请求方法包括(其中 GET、HEAD、OPTIONS、TRACE、DELETE、PUT 是幂等请求)(幂等性指一或多次请求某资源应具有同样的副作用)

  • GET: 请求获取指定资源
  • POST: 请求提交数据进行处理
  • PUT: 请求提交数据进行替换 (整体替换)
  • PATCH: 请求提交数据进行替换 (部分替换) (与 PUT 类似,但由于是部分替换,因而不被认为是幂等的)
  • DELETE: 请求删除指定资源
  • OPTIONS: 用于获取服务端支持的请求方法
  • HEAD: 请求获取资源的响应消息头
  • TRACE: 请求服务器回送收到的请求信息,主要用于测试或诊断
  • CONNECT: 建立连接隧道,用于代理服务器

状态码由三位数字组成,其首位代表状态类别

  • 1xx:消息类状态,如:100-客户端应该继续发送请求,102-处理将被继续执行
  • 2xx:成功类状态,如:200-成功
  • 3xx:重定向状态,如:301-永久重定向,302-临时重定向,304-命中协商缓存,305-指定访问代理
  • 4xx:客户端错误,如:400-请求语法错误,401-用户未认证,403-请求被拒绝,404-资源不存在,405-请求方法错误
  • 5xx:服务端错误,如:500-服务器异常,502-网关错误,503-服务器维护或过载,504-网关超时,505-HTTP 版本不支持

传输特性

  • 持久连接:TCP 连接不关闭,可以被多个请求复用
    • 默认状态下所有连接都是持久连接
    • 可通过 Connection: Keep-AliveConnection: close 指定开启或关闭
  • 管道机制:在一个 TCP 连接中,可以同时发送多个请求,发送过程中不需先等待服务端响应
    • 依赖于持久连接
    • 由于未收到响应就可以继续发生请求,所以只支持幂等请求
    • 需要服务端也支持管道化,还可能导致对头阻塞问题,浏览器默认关闭管道化
  • 断点续传:通过设置请求头中的 Range 字段进行实现
  • 虚拟网络:同一服务器上支持多个共享同一 IP 的虚拟主机
  • 缓存控制:优化了缓存标识的判断规则

存在问题

  • 明文传输:无法确保传输的安全性
  • 性能浪费:持久链接会占用服务端带来更大的服务器压力
  • 队头阻塞:请求管道化带来的新问题,多个有序请求可能因对头受阻导致整列数据受阻。
    • 独立的消息数据在一个链路上传输
    • 队列上传输的数据又严格的顺序约束
    • 当一列的第一个数据包(队头)受阻而导致整列数据包受阻

队头阻塞的处理

  • HTTP 1.x 默认关闭管道化
  • HTTP 1.x 使用并发连接(Chrome 默认 6 个)和域名分片(根据二级域名划分业务提高最大并发)提高请求效率
  • HTTP 2 中引入 二进制分针和多路复用 处理

HTTPS

HTTPS = HTTP + SSL/TLS,即对传输信息进行了加密
附:SSL-安全套接层,TLS-传输层安全(1.2 以上安全),主流的版本配置为 TLS1.2 + SSL3.3

HTTP 为明文传递,存在以下问题

  • 窃听风险:第三方可以获取通信内容
  • 篡改风险:第三方可以修改通信内容
  • 冒充风险:第三方可以冒充参与通信

SSL/TLS 协议进行了以下处理

  • 信息加密,确保第三方无法窃听
  • 信息校验,确保识别被篡改信息
  • 配备证书,防止第三方身份冒充

加密方式

对称加密:加密解密使用同一个密钥

  • 优点:加密解密效率高
  • 缺点:密钥可以被窃取

非对称加密:客户端使用公钥加密,服务端使用私钥解密

  • 优点:私钥无法被窃取
  • 缺点:加密解密效率低

工作流程

公钥加密:客户端先向服务端索要公钥,然后用公钥加密信息,服务端收到密文后使用私钥解密

  • 公钥存放在证书中,只要证书可信,公钥则可信
  • 对称加密,减少加密运算消耗时间

协议过程(步骤 1 和 2 为握手阶段)

  1. 客户端向服务端索要并验证公钥
  2. 客户端与服务端协商生成对话密钥
  3. 客户端与服务端采用对话密钥加密通信

握手阶段(通信为明文传输)

  1. 客户端向服务端发出加密通信请求,ClientHello 请求
    • 协议版本
    • 客户端生成的随机数
    • 支持的加密方法
    • 支持的压缩方法
  2. 服务端接收请求后向客户端回应,ServerHello 响应
    • 确认使用的协议版本(若与客户端不一致,服务端关闭加密通信)
    • 服务端生成的随机数
    • 确认使用的加密方法
    • 服务器证书
  3. 客户端收到响应后验证证书并获取公钥,随后向服务器发送请求
    • 随机数(又称 pre-master key),用于服务器公钥加密,防止被窃听
    • 编码通知,决定加密方法和密钥
    • 客户端握手结束通知,其值为之前内容的 hash 值,供服务端校验
  4. 服务端接收到请求后,根据上述三个随机数生成会话密钥,之后发送
    • 编码通知
    • 服务端握手结束通知,值为内容 hash,共客户端校验

流程梳理

  1. 客户端 -- client hello --> 服务端
  2. 服务端 -- 证书(公钥) --> 客户端
  3. 客户端(获取证书公钥) -- 公钥加密信息 --> 服务端
  4. 服务端(私钥解密信息) -- 生成会话密钥 --> 客户端
  5. 后续服务端与客户端使用会话密钥进行加密解密通信(对称加密)

HTTP 2

HTTP 2 进一步优化了通信性能,并解决了 1.1 中队头阻塞等问题

  • 二进制分帧:引入头信息帧和数据帧
  • 请求优先级:可以设置数据帧优先级,优化处理顺序
  • 多路复用:用于解决队头阻塞问题
  • 头部压缩:用于优化 Header 信息占比过重的请求 (HPACK 算法)
  • 服务端推送:允许服务端主动向客户端推送

二进制分帧

帧:报文被拆分为二进制帧,帧作为最小通信单位,承载特定类型的数据(Header 帧、Data 帧)
消息:HTTP 消息(请求、响应)由一个或多个帧组成
流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。

对于相同 Stream ID 帧是有序传输的
对于不同 Stream ID 帧是无序传输的
接收到二进制帧后将对相同 Stream ID 的帧进行组装
帧中包含着优先级、流量控制等信息,便于优化处理效率

头部压缩

采用HPACK算法进行压缩,主要包括

  • 常用头信息规则映射
  • 哈弗曼编码压缩数据

多路复用

可以使用单一 TCP 连接发送多个请求,数据流以消息形式发送,消息由帧组成,帧首部添加了流标识,可以无序发送,由接收方组装,从而解决 1.1 中队头阻塞的问题。

服务端推送

服务端可以在接收客户端请求后,主动推送其他资源,客户端后续发送请求时若存在相关资源则可以直接通过缓存读取