[译] HTTP 的进化 - 0.9、1.0、1.1、Keep-Alive、Upgrade 和 HTTPS

HTTP 的进化 - 理解真实的 HTTP 是如何工作的

原文: https://medium.com/platform-engineer/evolution-of-http-69cfe6531ba0


自从在 1989-1991 年间被 CERN(译注:即“欧洲核子研究组织”的原称 - Conseil Européen pour la Recherche Nucléaire)的 Tim Berners-Lee 发明出来以后,HTTP(超文本传输协议) 就一直是万维网的基础传输协议。在 C/S 计算模型中,HTTP 起到了一个“请求/响应”协议的作用。HTTP 标准由 IETF(因特网工程任务组) 和 W3C(万维网联盟)负责开发,并以一系列注释请求(RFCs - Requests for Comments)的形式被发布。HTTP 有 4 个版本:HTTP/0.9、HTTP/1.0、HTTP/1.1 以及 HTTP/2.0。当前通常使用 HTTP/1.1 版本,未来会是 HTTP/2.0。

HTTP/0.9 — 单行协议

  • HTTP 的首个版本 — 一个简单的 客户端/服务器、请求/响应、对 telenet 友好的协议
  • 请求: 单行 (method + 所请求文档的 path)
  • 支持的方法: 仅 GET
  • 响应类型: 仅 超文本
  • 响应后马上结束的连接
  • 没有 HTTP headers (无法传输其他内容类型的文件), 没有 status/error 代码, 没有 URLs, 没有版本控制
$> telnet ashenlive.com 80

(连接1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(请求)
GET /my-page.html

(超文本响应)
<HTML>
A very simple HTML page
</HTML>

(连接1关闭 - 断掉 TCP)

流行的 web 服务器(Apache, Nginx)始终支持 HTTP/0.9。可以打开一个 Telnet 会话访问 google.com 试试。

HTTP/1.0 — 构建可扩展性

  • 对浏览器友好的协议
  • 提供了对请求和响应都包含丰富元数据的 header 域 (HTTP 版本号、status code 和 content type)
  • 响应:不再只限于超文本 (Content-Type 头部提供了传输 HTML 之外文件的能力 — 如脚本、样式或媒体文件)
  • 支持的方法: GET , HEAD , POST
  • 响应后马上结束的连接
(连接1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(请求)
GET /my-page.html HTTP/1.0 
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

(响应)
HTTP/1.0 200 OK 
Content-Type: text/html 
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

<HTML> 
A page with an image
  <IMG SRC="/myimage.gif">
</HTML>

(连接1关闭 - 断掉 TCP)

------------------------------------------

(连接2建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(请求)
GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

(响应)
HTTP/1.0 200 OK 
Content-Type: text/gif 
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

[image content]

(连接2关闭 - 断掉 TCP)

HTTP/0.9 和 HTTP/1.0 的主要问题 — 为每个请求建立一个新连接

HTTP/0.9 和 HTTP/1.0 都需要为每次请求建立一个新的连接(并在收到对应的响应后立即关闭该连接)。每次新连接建立时,都要经历一遍 TCP 三次握手。考虑到更好的性能,应该着重减少这些 C/S 之间的往返通信。HTTP/1.1 用持久化连接解决了这个问题。

典型的 TCP 三次握手(观察一下 TCP 状态机是如何改变其状态的吧)

HTTP/1.1 — 标准化的协议

  • 这是当前普遍使用的 HTTP 版本
  • 进行了重大的性能优化和特性增强,分块传输、压缩/解压、内容缓存磋商、虚拟主机(有单个 IP 地址的主机具有多个域名)、更快的响应,以及通过增加缓存节省了更多的带宽
  • 支持的方法: GET , HEAD , POST , PUT , DELETE , TRACE , OPTIONS
  • 长久的连接
(连接1建立 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(请求1)
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

(响应1)
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

[content]

(请求2)
GET /static/img/header-background.png HTTP/1.1
Host: developer.cdn.mozilla.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

(响应2)
HTTP/1.1 200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

[image content of 3077 bytes]

(连接1关闭 - 断掉 TCP)

TCP 三次握手会在任何连接被建立之前发生一次。最终,当发送了所有数据之后,服务器发送一个消息,表示不会再有更多数据向客户端发送了;则客户端才会关闭连接(断开 TCP)。HTTP/1.0 存在的问题是,对于每个 请求/响应 轮回,也要建立并关闭一个连接。而改用 HTTP/1.1 后的优点则在于,可以复用同一个连接,来完成多次 请求/响应 轮回

Keep-Alive 和 Upgrade 头部

Keep-Alive 头部

  • Connection: Keep-Alive 头部在 HTTP/1.1 之前就存在,但在 HTTP/1.1 中该头部被废弃了,因为持久化连接变成了默认的行为(译注:除非用Connection: Close显式关闭)。Keep-Alive 头部可以被用于在主机之间定义持久连接通信策略(比如使一个连接在某个事件发生之前都保持激活)。这奠定了持久化、连接复用、管道化及其他很多现代 web 通信协议中被加强能力的基础。
  • 可以对客户端、服务器,或任何中间人分别设置独立的 Keep-Alive 头部。同时,主机可以增加 timeout 参数以设置一个超时,或用 max 参数限制每个连接的最大请求数。
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache

[body] 

`Keep-Alive` 头部的用法。所有连接都是独立协商的
  • 受益于 Keep-Alive 头部,HTTP 管道化实现了多个连接,以及其他更多改进。

HTTP 管道化和多个并行连接

Upgrade 头部

  • 借助 HTTP/1.1 带来的 Upgrade 头部,便可用一个常用的协议起步,比如 HTTP/1.1,然后让该连接切换到增强的协议类型,如 HTTP/2.0 或 WebSockets。
  • 在一个升级过的连接中,不再有 max 参数了。升级后的协议为 timeout 参数提供了新的策略(如果没有特别定义,使用基础协议默认的 timeout 值)。

由 HTTP/1.1 升级到 WebSocket[RFC6455]

HTTPS

  • 加密超文本传输协议(HTTPS)是 HTTP 的安全版本,使用 SSL/TLS 完成安全加密通信。
  • 最初由网景公司在 90 年代中期开发,SSL(安全套接字层)是一种增强 HTTP 的密码学协议,定义了客户端和服务器之间如何安全的互相通信。TLS(安全传输层协议)是 SSL 的继承者。
  • 因为在客户端和服务器间提供了双向加密,HTTPS 连接可以在数据传输中防止中间人攻击和常见的安全威胁。

访问 msdn.microsoft.com 站点时的 SSL 握手过程 — TCP 连接 -> SSL/TLS 客户端 Hello -> SSL/TLS 服务器 Hello -> SSL/TLS 认证 -> SSL/TLS 客户端交换秘钥 -> SSL/TLS 新会话 Ticket -> HTTPS 加密数据传输

SSL/TLS 握手 — HTTPS 中的主要问题

  • 尽管 HTTPS 设计上是安全的,但 SSL/TLS 握手过程在 HTTPS 连接之前消耗了显著的时间;通常会耗费 1 至 2 秒,极大影响了网站启动性能。

HTTP/2.0 和未来

所有以上提及的特性,当今都已经被主要的服务器和浏览器所使用了。但像 HTTP/2.0、Server Side Events (SSE) 以及 WebSocket 这样的现代增强功能,则改变了传统 HTTP 的工作方式。

参考:

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
  2. https://tools.ietf.org/id/draft-thomson-hybi-http-timeout-01.html
  3. https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism
  4. https://hpbn.co/brief-history-of-http/
----------------------------------------

长按二维码或搜索 fewelife 关注我们哦

关注下面的标签,发现更多相似文章
评论
说说你的看法