文章

网络协议打怪升级-应用层:HTTP、HTTPS

网络协议打怪升级-应用层:HTTP、HTTPS

1.HTTP

HTTP(HyperText Transfer Protocol,超文本传输协议)是一个用在客户端和服务端之间传输数据的应用层协议,也是网络用户接触最多的协议。由于此协议很常见,本文不再赘述其结构核心概念等知识,只会重点梳理协议的核心特性和协议发展。

1.1.HTTP 1.x

  • HTTP 1.x的核心特性
    • 请求-响应式模型:客户端发送请求,服务端返回响应
    • 无状态:每个HTTP请求是独立的,服务器不会记住之前的请求,所以出现了Cookie、Session或者URL参数
    • 文本协议:请求和响应以纯文本形式传输,(在2.x开始,使用二进制传输)
    • 状态码:HTTP响应使用状态码来标识响应结果。
      1
      2
      3
      4
      5
      
      1XX:信息性(ex:101 Switching Protocols-http升级websocket协议)
      2XX:成功
      3XX:重定向
      4XX:客户端错误
      5XX:服务端错误
      
    • 头部:提供请求元信息,包括Content_Type(内容类型),Host(目标域名),User-Agent(客户端标识),Referer(客户端域名)
    • 超文本支持:最初设计传输HTML,后续支持图片,JSON,视频等任意数据
  • HTTP 1.x流程
    • HTTP 1.x基于TCP协议,在TCP完成三次握手建立连接后,HTTP连接建立在TCP连接之上
    • HTTP 依赖DNS协议和IP协议,通过DNS协议解析URL到IP,TCP协议依赖IP协议进行包传递

  • HTTP 1.x不同版本之间差异
    • HTTP 0.9
      • 最早版本,用于简单网页传输
      • 只支持GET,用于获取资源
      • 单次连接:每次请求都要建立一个TCP连接
      • 只传HTML,且无状态码,无法区分成功或错误
    • HTTP 1.0
      • 增加POST,HEAD(仅获取头部)
      • 增加请求头,允许携带元信息
      • 引入状态码
      • 支持非HTML传递,由于请求头中Content_Type指定类型
    • HTTP 1.1及之后
      • HTTP 1.1奠定了当前HTTP1.x协议的基本特性
      • 持久化(keep-alive)允许多个HTTP请求复用一个TCP连接
      • 强制头部,要求请求必须包含一些特定字段(如Host)
      • 管道化(pipline)允许收到前一个请求的响应前发送后续请求,减少等待时间

在1997年HTTP1.1之后,HTTP1.x稳定运行了十多年。 但是随着现代更复杂的网页出现,人们对高延迟网络(如移动网络)的优化需求。2015年,HTTP2正式被推出。

1.2.HTTP 2

1
HTTP/2旨在提升性能、降低延迟并适应现代化Web需求,而不改变HTTP的语义(如方法、状态码、URI),保持与HTTP1.x的兼容性
1.2.1HTTP 2解决了什么问题?

在说明HTTP 2解决了哪些问题之前,我们先看看HTTP1.x有哪些问题


  • 1-队头阻塞
    • 每个TCP连接一次只能处理一个请求-响应对,即使启用Pipeline,响应仍需按序返回,若某一个请求或响应延迟(比如满加载图片),后续请求会被阻塞
    • 浏览器为了解决这个问题,允许开启多个TCP连接(默认6个),但却增加了服务器的负担
  • HTTP 2的解决办法:多路复用(multiplexing)
    • 允许在单个TCP连接上并行传输多个请求和响应
    • 每个请求是一个独立的”流”,互相不干扰,消除了队头阻塞

  • 2-头部冗余和高额开销
    • 每个请求重复发送大量头部(如User-Agent,Accept),且未压缩,浪费带宽
  • HTTP 2的解决办法:头部压缩(HPACK)
    • 使用专门的压缩算法,使用动态表记录已发送的头部,后续只传输差异或索引

  • 3-连接效率低
    • 尽管有keep-alive,仍需要多个连接,每个连接需三次握手和慢启动,延迟增加
  • HTTP 2的解决办法:单一连接
    • 由于多路复用的存在,所有请求可以公用同一个TCP连接,减少握手和资源开销

  • 4-服务器推送支持度不高
    • 使用请求-响应式模型,客户端必须对所有资源进行请求,增加往返时间
  • HTTP 2的解决办法:服务器推送(server push)
    • 服务器可以主动推送相关资源到客户端,减少请求次数,减少客户等待时间

1.2.2HTTP 2的核心技术特点
  • 二进制协议:使用二进制传输代替HTTP1.x的纯文本传输,解析更快、更高效
  • 多路复用:多个HTTP请求/响应可以使用同一个TCP连接,每个请求是一个独立的”流”,彼此之间互不干扰
  • 头部压缩:使用特殊算法压缩头部,维护一张动态表记录已发送的头部,减少带宽使用
  • 服务端主动推送:打破了之前的请求-响应式模型,允许一次请求多个响应
  • 向后兼容:保留HTTP1.x的语义,无感向后兼容

2.HTTPS

随着互联网世界的不断扩展,传输安全性也称为互联网设计者们必须要考虑的课题。 对于客户端-服务端这种交互形式来说,需要考虑的安全问题主要有以下几点:

  • 传输包内容被劫持
  • 传输包内容被修改
  • 服务端的可信任性

HTTPS的出现,正是为了解决上面三个问题。

2.1.HTTPS的握手流程

我们都知道,HTTPS使用SSL、TLS协议来保证请求的安全性。 那么SSLTLS是什么呢?

SSL和TLS是两个在传输层之上,在应用层之下的协议。
旨在解决HTTP请求中的安全问题,TLS/SSL在TCP连接建立后(三次握手),
通过握手过程协商加密参数,然后加密TCP数据流。
当前HTTPS几乎完全使用TLS,尤其是TLS1.2,TLS1.3,SSL已经基本被淘汰。
原因是TLS相较于SSL,有更强大的加密算法和更安全的加密套件,
在性能上的表现也是TLS优于SSL,TLS成为了HTTP加密行业的新标准

TLS是如何使请求变得安全呢?答案就在HTTPS的握手过程中

TLS握手过程如下:

  • 客户端hello,携带请求信息
    • TLS版本
    • 客户端随机数,用于生成密钥
    • 支持的加密套件列表
    • 扩展字段(如支持的椭圆曲线、ALPN协议)
  • 服务端hello,携带响应信息
    • 选定的TLS版本
    • 服务端随机数,用于生成密钥
    • 选定的加密套件
    • 扩展响应
  • 服务端发送证书信息,供客户端验证服务端安全
    • 服务器的公钥证书(CA颁发)
    • 可选:证书链
  • 服务端发送Done
    • 空消息,表示服务器完成发送
    • 提示客户端开始响应
  • 客户端收到证书信息,通过证书公钥加密并验证证书可信任性

  • 客户端验证通过,生成预主密钥与通信密钥,并发送预主密钥
    • 生成预主密钥
    • (预主密钥+客户端随机数+服务端随机数)三个密钥生成通信密钥
    • 此时客户端持有通信密钥
    • 发送预主密钥到服务器
  • 服务端收到预主密钥
    • (预主密钥+客户端随机数+服务端随机数)三个密钥生成通信密钥
    • 此时服务端持有通信密钥
  • 服务端和客户端分别发送一条短消息
    • 切换到加密模式
    • 表示后续通信将使用协商好的通信密钥进行加密
  • Server Finish && Client Finish
    • 使用通信密钥加密的校验消息,包含握手中所有消息的哈希
    • 验证握手完整性
    • 确认双方密钥一致

至此,后续在此连接上发送的数据包都通过通信密钥进行堆成加密,解决了:

1-数据包被劫持:数据被加密,劫持了也没有密钥进行解密 2-服务端可信任性:通过校验CA颁发的证书,保证服务端是CA认可的、可信任的服务器

如何避免数据包被篡改?

TLS使用消息认证码MAC(Message Authentication Code)来确保数据完整性

MAC:
1-数据在进行发送之前,基于通信密钥,计算发送数据包中所有内容的MAC(基于HMAC,如HMAC-SHA256),并放到请求中。
2-数据接收到之后,先解密,然后基于通信密钥对解密后的内容计算MAC。
3-比较两个MAC是否一致,若不一致,说明数据被篡改。

3.补充:SSE与WebSocket

SSE与WebSocket都是基于HTTP的通信机制,用于实现服务器与客户端之间的实时数据传输。他们在HTTP基础上扩展了功能,解决了HTTP 1.x的请求-响应模型在实时性上的缺陷

3.1.SSE

SSE(Server Send Event)是一种基于HTTP的技术,允许服务端向客户端推送实时更新。它使用标准的HTTP协议,通过Content-Type=text/event-stream实现单向数据流。

实现原理

  • 连接建立
    • 客户端发送HTTP请求,头部包含Accept:text/event-stream
    • 服务端响应Content-Type:text/event-stream,保持连接不关闭
  • 服务端推送消息
    • 服务端发送的消息遵循简单文本格式,每条消息以换行符’\n’分隔
      • event: [时间类型]:指定事件名
      • data: [数据]:实际数据
      • id:[标识]:事件id
      • 空行:’\n\n’:标识一条消息结束
  • 客户端按照空行为分割一个个接收服务端返回的数据并处理
  • 重连机制:如果连接断开,EventSource会根据retry:(服务器指定重试间隔)字段自动重连

特性

  • 长连接:HTTP连接保持开放,服务器分块推送
  • 简单:基于HTTP,无需额外协议
  • 单向性:仅服务器推送,客户端无法通过同一连接发送数据

常见用法

  • 实时消息推送(新闻、股票)
  • 状态更新(服务器状态更新)
  • 聊天模型流式返回

3.2.WebSocket

WebSocket与SSE不同,它是一种基于TCP的独立的协议,通过HTTP握手建立,提供全双工通信(客户端和服务端可同时发送消息)

它在建立连接时,依赖HTTP发起握手(Upgrade请求),完成后切换为WebSocket的独立协议

实现原理

  • 握手过程
    • 首先,客户端与服务端建立TCP连接
    • 客户端发送HTTP请求,包含头部升级
      GET /chat HTTP/1.1
      Host: example.com
      Upgrade: websocket
      ...
      
    • 服务端响应101 Switching Protocols,确认升级
      HTTP/1.1 101 Switching Protocols
      Upgrade: websocket
      Connection: Upgrade
      ...
      
  • 消息传输:WebSocket连接建立后,通过二进制帧通信
    • FIN:是否最后一帧
    • Opcode:帧类型(0x1文本,0x2二进制,0x8关闭)
    • Payload:实际数据
  • 双向通信:
    • 客户端和服务端可随时发送消息,无需等待对方响应

特性

  • 协议升级:从HTTP升级为WebSocket
  • 全双工:双向实时通信
  • 高效:二进制帧减少开销

常见用法

  • 实时双向交互:在线聊天
  • 游戏:实时同步玩家操作和状态
  • 物联网:设备与服务器的双向通信

4.总结

  • HTTP1.x/HTTP2
    • 是应用层的协议,用来实现客户端与服务器的交互
    • 有多个请求方法和响应CODE,用来标识不同类型的请求和不同类型的响应
    • 请求头中包含元数据,标识请求类型、携带参数类型、请求源、目标服务器地址等
    • HTTP 1.x 纯文本传输,仅支持请求-响应式模型,可以通过keep-alive实现多个请求复用同一TCP连接,但是会有队头阻塞等问题
    • HTTP 2二进制帧传输;支持服务端主动推送;采用多路复用,每个请求被分为特定的流,可以不按照顺序进行传输;支持头部压缩,减少请求包大小,降低带宽压力
  • HTTPS
    • 使用TLS/SSL协议,实现传输内容安全(加密),服务器可信任(证书校验),传输内容防篡改(MAC)
    • 在TCP连接建立后,通过TLS/SSL的握手流程,实现对称密钥商议和证书的验证
    • HTTPS需要客户端和服务端都同时支持,单边支持无法使用HTTPS
  • SSL VS WebSocket | 特性 | SSE | WebSocket | | — | — | — | | 通信方向 | 单向 | 双向(全双工) | | 协议基础 | HTTP | HTTP握手后建立独立协议 | | 数据格式 | 文本(event-stream) | 二进制帧(支持文本/二进制) | | 连接方式 | 长连接 | 持久连接 | | 复杂度 | 简单 | 较复杂 | | 重连 | 内置支持 | 需手动实现 |
本文由作者按照 CC BY 4.0 进行授权