HTTP的前世今生

17 March 2018

http 网络 WWW 科普 HTTP协议发展历程

http

生活的每一天都会打开,关闭很多的网页链接,却未曾真正有彻底去了解过链接背后的不为人知的传奇故事。

今日就让我来为你讲述HTTP协议的前世今生传奇吧。

先来认识HTTP是什么?

HTTP全名:超文本传输协议(英文:HyperText Transfer Protocol)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。 –摘自《维基百科

例如:链接 http://yi-love.github.io/ ,链接最前面的http就是HTTP协议。

那是谁发明了HTTP?

lee

【图1】Tim Berners-Lee

蒂姆·伯纳斯-李(英语:Tim Berners-Lee),英国计算机科学家。他是万维网(WWW)的发明者。1990年12月25日,他成功利用互联网实现了HTTP客户端与服务器的第一次通讯。

免责声明:文章内容,大部分来源于网络资料,本人只是将HTTP协议的整个发展历程按时间顺序进行排版讲述,一切以真实资料为主。如有错误或者侵犯您的权益,请随时联系修正。

HTTP的前世传奇

HTTP协议确定之前,伯纳斯-李已经提出了超文本构想,并最终实现了最早期的超文本系统。

1980年——超文本构想的诞生

1980年6月至12月间,伯纳斯-李在日内瓦的CERN(欧洲核子研究中心)担任独立承包人。在那段时间里,他提出了一个构想:创建一个以超文本系统为基础的项目,目的是为了方便研究人员分享及更新讯息。

同时他也开发出了最早的原型系统,并命名为ENQUIRE。这个系统允许一个存储信息片断,并以任何方式链接相关的部分。要找到信息,通过从一张纸到另一张纸的链接进行,就像在旧电脑游戏“冒险”中一样。他用它来记录个人和模块的个人记录。 它类似于Apple原来为Macintosh制作的应用程序Hypercard。不同的是,查询尽管缺乏花哨的图形,却运行在多用户系统上,并允许许多人访问相同的数据。

ENQUIRE

【图2】ENQUIRE系统查询页面

就这样,最早的超文本系统原型诞生了(那时候还没有HTTP协议)。也正是因为ENQUIRE系统的经验,为万维网的诞生埋下了一颗坚实的种子。

1989年——万维网的诞生

1980年,离开CERN的伯纳斯-李在辗转4年之后又重新回到了CERN。1989年,伯纳斯-李为了解决CERN的信息访问的问题,他使用与ENQUIRE系统相似的概念来创建万维网

当时CERN信息访问的存在着很多的问题,也包括了:

  1. 人员流动,信息不断丢失?
  2. 这个模块在哪里使用?
  3. 谁写了这段代码?他在哪里工作?
  4. 关于这个概念的文件有哪些?
  5. 该项目包括哪些实验室?
  6. 哪些系统依赖于此设备?
  7. 什么文件涉及这一个?

伯纳斯-李意识到存在的问题后,他写了 一份提案 试图说服CERN管理层,全球超文本系统是符合CERN的现状并且还是有益的。1989年的时候,CERN是全欧洲最大的互联网节点。这份提案里面详细的说出了CERN信息访问问题的产生,并且详细的描述了解决方案的演变。并说出了最终的解决方案就是使用超文本系统。

http

【图3】分布式超文本系统的客户端/服务器模型

这也第一次提出使用链接资源而非分层系统,而非关键字定位资源。这里的链接资源也就是后面鼎鼎有名的全球网络资源唯一认证的系统,统一资源标识符(URI)。

那为什么伯纳斯-李不用分层系统和关键字定位资源呢。其实他也是有考虑过的,在他写的那份 [提案]((https://www.w3.org/History/1989/proposal.html) 里面详细的描述了分层系统和关键字定位资源的存在的问题。主要的问题有:

  1. 分层系统的问题:树形结构的问题,使用链接的话没有限制。
  2. 关键字的问题:两个人从未选择过相同的关键字。这些关键字仅适用于已经熟悉应用程序的人员。

正是出于这些原因,伯纳斯-李第一次建立了一个小型的链接信息系统,但他并没有意识到已经为这个想法创造了一个术语:“超文本”。

最终,在1990年伯纳斯-李重新开发配置系统后被他的经理麦克·森德尔(Mike Sendall)所接受。

http

【图4】超文本网关允许通过超文本浏览器以超文本形式查看数据

伯纳斯-李重新开发配置系统大概的系统就是如图4展示的样子。用户通过超文本浏览器通过超文本网关查看数据。

也就是因为这个系统,不仅为HTTP/0.9协议奠定了基础,也诞生了后面大家熟悉的万维网

万维网(英语:World Wide Web),亦作“WWW”、“Web”,是一个由许多互相链接的超文本组成的系统,通过互联网访问。 –摘自《维基百科

“我只要把超文本系统和传输控制协议、域名系统结合在一起,然后就有了万维网…” –来自蒂姆·伯纳斯-李

HTTP协议诞生

其实说了这么多并没有说明HTTP协议的必要性,为什么需要创造一个新的协议(HTTP协议),难道使用其它协议不行吗?

是的,其它协议不行。

当时现有的协议涵盖许多不同的任务:

  1. 邮件协议允许将单个作者的短暂信息传输给少量收件人。
  2. 文件传输协议允许根据发送者或接收者的请求传输数据,但在响应端不允许处理数据。
  3. 新闻协议允许向广泛的受众广播瞬态数据。
  4. 搜索和检索协议允许进行索引搜索,并允许文档访问。

考虑到很少存在可以根据需要进行扩展的协议,仅有的Z39.50算是一个可行的吧。

HTTP协议必须提供:

  1. 文件传输功能的一个子集
  2. 能够请求索引搜索
  3. 自动格式协商
  4. 将客户端引用到另一台服务器的能力

由于很难在原来现有的协议上进行扩展,所以HTTP协议诞生了。

HTTP协议的今生故事

HTTP协议诞生后,HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC。

HTTP/0.9

1991年,定义了原始超级文本传输协议(HTTP),最初由发布原型中的万维网初始化软件实施(其实应该是上文伯纳斯-李重新开发配置系统)。这是完整的HTTP协议的一个子集,被称为HTTP 0.9。

没有客户配置文件信息与查询一起传输。未来的HTTP协议将与此协议反向兼容。

这个受限制的协议非常简单,当您不需要向后兼容的完整协议的功能时,可能会始终使用此协议。

该协议在TCP-IP链路上使用普通的internet风格的telnet协议风格。

Connection(连接)

客户端使用域名或IP号码以及地址中给出的端口号与主机建立TCP-IP连接。如果未指定端口号,则始终假设HTTP为80。然后,服务器接受连接。

Request(请求)

客户端发送一个文档请求,其中包含一行由CR LF(回车,换行符)对终止的ASCII字符。行为良好的服务器不需要回车符。

这个请求由单词“GET”,一个空格,文档地址组成,当它们是用于建立连接的坐标时,省略“http :,主机和端口部分”(如果正在使用网关,则满文件地址可以给出指定不同的命名方案)。

文件地址将包含一个单词(即没有空格)。如果在请求行中找到任何其他单词,它们必须被忽略,否则按照完整的HTTP规范处理。

GET /index.html

Response(响应)

对简单的GET请求的响应是超文本标记语言(HTML)中的消息。这是一个ASCII字符的字节流。

该消息由服务器关闭连接而终止。

错误响应以HTML语法中的可读文本提供。除了文本内容之外,没有办法将错误响应与满意的响应区分开来。

<html>
  <body>Hello World</body>
</html>

Disconnection(断开)

整个文档传输完成后,服务器会断开TCP-IP连接。在此之前,客户可以通过断开连接来中止传输,在这种情况下,服务器不应记录任何错误情况。请求是幂等的。断开连接后,服务器不需要存储关于请求的任何信息。

总结

只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息,返回HTML信息。

HTTP/1.0

最早在1992年,伯纳斯-李就已经写了一份HTTP/1.0的草案,后来慢慢被互联网草案,信息RFC以及现在的标准跟踪文档取代。

1992年当时作为惠普实验室担任研究员的Dave Raggett与伯纳斯-李会面后,Raggett参与了万维网的发展。

Raggett

【图5】Dave Raggett

1995年,Raggett领导了HTTP工作组(HTTP WG),并希望通过扩展操作扩展协议,扩展协商,更丰富的元信息,并与安全协议捆绑在一起,通过添加额外的方法和标题字段,该协议变得更加高效。

无可否认Phillip Hallam-Baker在安全方面做出了巨大的贡献,他是第一位提出了 S-HTTP 的科学家。

请不要将安全超文本传输协议(S-HTTP)与 HTTPS 混淆。

1996年5月,正式推出并受认可的HTTP V1.0协议RFC 1945,内容比HTTP/0.9大大增加。

首先,任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠定了基础。

其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。

再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

这是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。

GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP/1.0 200 OK 
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>

HTTP/1.1

HTTP/1.0协议准备发布后不久。在1996年初,主要浏览器开发人员迅速采用了基于当时正在开发的RFC 2068(称为HTTP-NG)的标准HTTP/1.1。 1996年3月,各大主要浏览器公司都支持最新标准的HTTP/1.1版本,最终用户采用新浏览器的速度非常快。

在1996年3月,一家网络托管公司报告说,在互联网上使用的浏览器中有超过40%是符合HTTP 1.1的。同一个网络托管公司报告说,截至1996年6月,访问其服务器的所有浏览器中有65%是HTTP /1.1兼容。

1997年1月,HTTP/1.1版本发布,只比1.0版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。

HTTP/1.1相较于HTTP/1.0协议的区别主要体现在:

  1. 缓存处理
  2. 带宽优化及网络连接的使用
  3. 错误通知的管理
  4. 消息在网络中的发送
  5. 互联网地址的维护
  6. 安全性及完整性

持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。

虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为”队头堵塞”(Head-of-line blocking)。

为了避免这个问题,只有两种方法:

  1. 减少请求数
  2. 是同时多开持久连接

这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

SPDY 协议

2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。包括了降低网页的加载时间。通过优先级和多路复用,SPDY使得只需要创建一个TCP连接即可传送网页内容及图片等资源。SPDY并不用于取代HTTP,它只是修改了HTTP的请求与应答在网络上传输的方式。

这个协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。

2015年9月,Google宣布了计划,移除对SPDY的支持,拥抱 HTTP/2。

HTTP/2

2015年5月 , HTTP/2作为互联网标准正式发布。

HTTP2与HTTP/1.1在请求方法、状态码乃至URI和绝大多数HTTP头部字段等方面保持高度兼容性。

通过以下举措,减少 网络延迟,提高浏览器的页面加载速度:

  1. 对HTTP头字段进行数据压缩(即HPACK算法)
  2. HTTP/2 服务端推送(Server Push)
  3. 请求管线化
  4. 修复HTTP/1.0版本以来未修复的“队头阻塞”问题
  5. 对数据传输采用多路复用,让多个请求合并在同一TCP连接内

HTTP/2的开发基于SPDY进行跃进式改进。在诸多修改中,最显著的改进在于,HTTP/2使用了一份经过定制的压缩算法,基于霍夫曼编码,以此替代了SPDY的动态流压缩算法,以避免对协议的Oracle攻击——这一类攻击以CRIME为代表。

此外,HTTP/2禁用了诸多加密包,以保证基于TLS的连接的前向安全。

展望未来

HTTP2,已经慢慢普及(Node.js,Nginx等已经支持HTTP2),网络瞬息万变,未来HTTP2如何,我们拭目以待。

参考文档

https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE

https://www.w3.org/Protocols/WhyHTTP.html

https://www.w3.org/Protocols/Classic.html

https://www.w3.org/History/1989/proposal.html

https://www.w3.org/Protocols/DesignIssues.html

https://www.w3.org/Protocols/HTTP/AsImplemented.html

https://www.w3.org/Protocols/HTTP/digest_specification.html

http://lists.w3.org/Archives/Public/ietf-http-wg-old/1994SepDec/

http://lists.w3.org/Archives/Public/ietf-http-wg-old/1995JanApr/

http://lists.w3.org/Archives/Public/ietf-http-wg-old/1995JanApr/0110.html

https://tools.ietf.org/html/draft-ietf-http-v10-spec-00

https://datatracker.ietf.org/doc/rfc1945/

https://datatracker.ietf.org/doc/rfc2068/

https://datatracker.ietf.org/doc/search/?name=http&activedrafts=on&rfcs=on

https://datatracker.ietf.org/doc/rfc7540/

https://zh.wikipedia.org/wiki/HTTP/2

http://www.ruanyifeng.com/blog/2016/08/http.html