互联网协议 — HTTP/3 超文本传输协议第 3 版

目录

文章目录

  • 目录
  • HTTP/3
  • HTTP/3 与 HTTP/2 的比较
  • HTTP/3 的特性
    • 零 RTT 建立连接
    • QUIC 流
      • HTTP/3 帧(frame)
      • HTTP 请求
      • HTTP 响应
      • QPACK 头部
    • 使用 Alt-svc 自举
    • 服务器推送

HTTP/3

2018 年,基于 QUIC 协议的 HTTP(HTTP over QUIC)也就是 HTTP/3,正式被确定为下一代网络规范。基于 QUIC 的 HTTP/3 的范例和概念没有改变。它含有头部(header)和正文(body),请求和回复,还有动词(verb)、Cookie 和缓存。HTTP/3 的主要改变是将这些报文以比特传送到另一端的方式。

为了使 HTTP 可以通过 QUIC 传输,协议的某些方面要进行修改,修改的结果便是 HTTP/3。这些必要修改是因 QUIC 与 TCP 在某些性质上有所不同所致的,修改包括:

  • 在 QUIC 中,数据流由传输层本身提供,而在 HTTP/2 中,流由 HTTP 层完成。
  • 由于数据流互相独立,HTTP/2 中使用的头部压缩算法如果不做改动,会造成队头阻塞。
  • QUIC 流与 HTTP/2 略有不同。

HTTP/3 与 HTTP/2 的比较

相似之处:

  • 两者都提供数据流。
  • 两者都提供服务器推送。
  • 两者都有头部压缩,QPACK 与 HPACK 的设计非常类似。
  • 两者都通过单一连接上的数据流提供复用。
  • 两者都提供数据流的优先度设置。

不同之处:

  • HTTP/3 面向 QUIC 设计,QUIC 是一个自己处理数据流的传输层协议。
  • HTTP/2 面向 TCP 设计,因此数据流在 HTTP 层处理。
  • 得益于 QUIC 的 0-RTT 握手,HTTP/3 可以提供更好的早期数据支持,而 TCP 快速打开和 TLS 通常只能传输更少的数据,且经常存在问题。
  • 得益于 QUIC,HTTP/3 的握手速度比 TCP+TLS 快得多。
  • HTTP/3 不存在明文的不安全版本。尽管在互联网上很少见,HTTP/2 还是可以不配合 HTTPS 来实现和使用。
  • 通过 ALPN 拓展,HTTP/2 可以直接在 TLS 握手时进行协商。HTTP/3 基于 QUIC,所以需要凭借响应中的 Alt-Svc: 头部来向客户端宣告。

HTTP/3 的特性

零 RTT 建立连接

互联网协议 — HTTP/3 超文本传输协议第 3 版_第1张图片

HTTP/2 的连接需要 3 RTT,如果考虑会话复用,即把第一次握手算出来的对称密钥缓存起来,那么也需要 2 RTT,更进一步的,如果 TLS 升级到 1.3,那么 HTTP/2 连接需要 2 RTT,考虑会话复用则需要 1 RTT。有人会说 HTTP/2 不一定需要 HTTPS,握手过程还可以简化。这没毛病,HTTP/2 的标准的确不需要基于 HTTPS,但实际上所有浏览器的实现都要求 HTTP/2 必须基于 HTTPS,所以 HTTP/2 的加密连接必不可少。而 HTTP/3 首次连接只需要 1 RTT,后面的连接更是只需 0 RTT,意味着客户端发给服务端的第一个包就带有请求数据,这一点 HTTP/2 难以望其项背。

  • Step1:首次连接时,客户端发送 Inchoate Client Hello 给服务端,用于请求连接;
  • Step2:服务端生成 g、p、a,根据 g、p 和 a 算出 A,然后将 g、p、A 放到 Server Config 中再发送 Rejection 消息给客户端;
  • Step3:客户端接收到 g、p、A 后,自己再生成 b,根据 g、p、b 算出 B,根据 A、p、b 算出初始密钥 K。B 和 K 算好后,客户端会用 K 加密 HTTP 数据,连同 B 一起发送给服务端;
  • Step4:服务端接收到 B 后,根据 a、p、B 生成与客户端同样的密钥,再用这密钥解密收到的 HTTP 数据。为了进一步的安全(前向安全性),服务端会更新自己的随机数 a 和公钥,再生成新的密钥 S,然后把公钥通过 Server Hello 发送给客户端。连同 Server Hello 消息,还有 HTTP 返回数据;
  • Step5:客户端收到 Server Hello 后,生成与服务端一致的新密钥 S,后面的传输都使用 S 加密。

这样,QUIC 从请求连接到正式接发 HTTP 数据一共花了 1 RTT,这 1 个 RTT 主要是为了获取 Server Config,后面的连接如果客户端缓存了 Server Config,那么就可以直接发送 HTTP 数据,实现 0 RTT 建立连接。

QUIC 流

HTTP/3 针对 QUIC 设计,所以它可以利用 QUIC 流的所有好处,通过 HTTP/3 传输的 HTTP 请求使用一系列的数据流完成。而 HTTP/2 不得不在 TCP 之上构建它的数据流和复用概念。

HTTP/3 帧(frame)

HTTP/3 中的数据帧种类不多且固定(截至 2018 年 12 月 18 日有九种)。最关键的帧可能是:

  • HEADERS:发送压缩的 HTTP 头部。
  • DATA:发送二进制数据内容。
  • GOAWAY:请关闭此连接.

HTTP/3 中有一种帧是优先度(PRIORITY)。与 HTTP/2 中的类似,它用于设定一个流的优先度和依赖关系。该帧可以设定一个流依赖于另一个流,也可以设定特定流的 “权重”。

服务器应该只在一个流所依赖的所有流都被关闭,或者都无法取得进展时为该流分配资源。一个流的权重是介于 1 到 256 之间的值,有着相同父系流的流应该按照权重的比例分配资源。

HTTP 请求

客户端通过其发起的双向 QUIC 流来发送 HTTP 请求。一个请求包括一个 HEADERS 帧,之后可能有一两种其他的帧,例如:一系列的 DATA 帧,以及可能有一个作为末尾的 HEADERS 帧。发送一个请求后,客户端会关闭该数据流以进行发出。

HTTP 响应

服务器在双向流上发回其 HTTP 响应。其中含有一个 HEADERS 帧,一系列 DATA 帧,末尾可能有一个 HEADERS 帧。

QPACK 头部

HEADERS 含有用 QPACK 算法压缩的 HTTP 头部。QPACK 与 HTTP/2 中的 HPACK(RFC 7541)类似,并针对乱序流做了相应修改。QPACK 本身在两个端点间使用两个额外的单向 QUIC 流,用于在两个方向上传递动态表信息。

使用 Alt-svc 自举

替代服务(alternative service)头部 Alt-svc: 和它相对应的 ALT-SVC HTTP/2 帧并不是特别为 QUIC 和 HTTP/3 设计的。它是为了让服务器可以告诉客户端:“看,我在这个主机的这个端口用这个协议提供相同的服务” 而设计的。详见 RFC 7838。

如果初始连接使用的是 HTTP/2(甚至 HTTP/1),服务器可以响应并告诉客户端它可以再试试 HTTP/3。连接可以指向相同主机或者不同但提供相同服务的主机。Alt-svc: 回复中有一个到期计时器,让客户端可以在指定的时间内使用建议的替代协议将后续的连接和请求直接发送给替代主机。

服务器推送

服务器推送实际上就是对一个未曾发出的客户端请求做出响应!

HTTP/3 的服务器推送与 HTTP/2(RFC 7540)类似,但机制上有所不同。

服务器推送仅在客户端同意的前提下才允许发出。在 HTTP/3 中,客户端甚至能通过通告给服务器的最大推送流 ID 来设置所接受推送的次数限制。超出限制将导致连接错误。

如果服务器端认为客户端可能需要某个并未要求但应该有的额外资源,服务器可以通过请求流发送一个 PUSH_PROMISE 帧,使该推送请求看上去像是一个响应,然后通过新的流发送实际响应。

虽然客户端之前已经表示过推送可接受,但如果客户端认为适合,每个推送流仍可以随时取消,然后发送一个 CANCEL_PUSH 帧到服务器。

你可能感兴趣的:(计算机网络)