HTTP协议学习笔记01 - HTTP协议发展史


HTTP(Hypertext Transfer Protocol)

即超文本传输协议,是互联网上应用最广泛的一种网络协议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

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

设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1。

2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。 HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。

超文本传输协议已经演化出了很多版本,它们中的大部分都是向下兼容的。在 RFC 2145 中描述了HTTP版本号的用法。客户端在请求的开始告诉服务器它采用的协议版本号,而后者则在响应中采用相同或者更早的协议版本。

HTTP/0.9

HTTP 0.9已经过时,作为HTTP协议的第一个版本,其本身的能力非常弱。只有GET语义,而且请求只有一行,例如:

telnet igvita.com 80
Connected to 173.230.151.99

GET /archive

从上文的例子可以看到,HTTP0.9协议的请求中,没有HTTP Header信息。并且无法使用内容协商,所以那个时代的HTTP客户端只能接收一种类型:纯文本(因为不知道具体是什么类型,所以都作为文本进行返回了)。并且,如果得不到所请求的资源,也不会有404、500等错误信息出现。

HTTP0.9协议具有典型的无状态性,每个事务独立进行处理。事务结束时就释放这个连接。(因为没有Header,所以更不会有keep-alive)

总结:

  1. HTTP0.9协议的客户端请求/服务端响应都是ASCII字符串;
  2. 客户端请求由一个回车符(CRLF)结尾;
  3. 服务器响应的是一种超文本标记语言(HTML);
  4. 连接在文档传输完毕后断开;

HTTP/1.0

随着WEB程序的快速发展,单纯的GET请求已经不能满足WEB程序的基本需求,所以HTTP1.0诞生了。

相比于HTTP0.9,HTTP1.0协议最大的改动是引入了POST方法,这使得客户端通过HTML表单向服务器发送数据成为可能。这也是WEB应用程序的一个基础。另一个巨大的改变是引入了HTTP头,使得服务端可以返回更加丰富的信息。并且HTTP协议所传输的内容也开始不仅限于纯文本,还可以是图片、动画等格式信息(在Header的Content-Type字段描述了body的信息类型)。例如:

telnet ietf.org 80
GET /rfc/rfc1945.txt HTTP/1.0
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Accept: */*

总结:

  1. 服务端响应增加了响应状态行;
  2. 请求和响应都增加了多行首部;
  3. 响应内容不再局限于超文本;
  4. 连接在响应传输完毕后默认会断开连接;

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

HTTP/1.1

HTTP的改进并不像HTTP1.0相比于HTTP0.9那么的具有革命性,但是也做了很多的增强,首先,增加了Host头,比如:

telnet google.com 80
GET /index.html HTTP/1.1
Host: website.org

GET后面仅仅需要相对路径就可以了。这看起来似乎只是个语法糖。但是实际上,这使得一台物理机器上同时绑定多个域名变成了可能(通过Host头来进行server分发)。如果没有该机制,那么多个域名指向同一个IP时会产生混淆(参考nginx如果不支持SNI扩展时,一个IP上如果有多份HTTPS证书,那么客户端请求该服务器时,可能会出现握手错误)

此外,还提供了Range头,该头字段允许客户端通过HTTP下载时只下载内容的一部分,这使得多线程下载也成为可能。

还有值得一提的是HTTP1.1默认情况下连接是一直保持的(但是如果链路中有代理不支持keep-alive的话,那么也无法使用该功能)

到2014年,HTTP1.1协议支持的内容有:

  1. RFC7230 - HTTP/1.1: Message Syntax and Routing
  2. RFC7231 - HTTP/1.1: Semantics and Content(methods, status codes and headers)
  3. RFC7232 - HTTP/1.1: Conditional Requests ( If-modified-Since)RFC7233 - HTTP/1.1: Range Requests
  4. RFC7234 - HTTP/1.1: Cacheing
  5. RFC7235 - HTTP/1.1: Authentication

总结:

  1. 1999年的HTTP1.1协议主要做出以下几个改动:
  2. 持久连接(Connection: keep-alive)
  3. 传输编码(Transfer-Encoding: chunked),目前应该只有分块(chunked)这一种类型了,其它类型应该都废弃掉了。
  4. 字节范围请求(Accept-Ranges)
  5. 增强的缓存机制(协商缓存和强缓存)
  6. 带宽优化及网络连接的使用(管道)

在HTTP/1.1中持久连接被默认开启,并能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求(虽然这个pipe不是很好用),以便降低线路负载,提高传输速度。

SPDY

spdy协议是Google开发的基于TCP协议的应用层协议,spdy协议旨在通过压缩、多路复用和优先级来缩短网页的加载时间和提高安全性。现在已经废弃。但是新的HTTP/2.0是基于spdy协议来设计的。

spdy协议是在性能上对HTTP协议做了大量优化,其核心思想是尽量减少连接个数。而对于HTTP的语义并没有做太大的修改,但是删除了一些不常用的头字段并重写了HTTP中管理连接和数据转移格式的部分,所以基本上是兼容HTTP的。

Google在spdy的白皮书里表示要向协议栈下面渗透并替换掉TCP协议,但是这样的话实施起来相当困难,因此google准备先对HTTP进行改进,先在SSL之上增加一个会话层来实现spdy协议,而HTTP的GET和POST消息格式保持不变。

HTTP协议的不足

单路连接,请求低效

HTTP协议最大的弊端是每个TCP连接只能对应一个HTTP请求(即使有管道pipelining,也是一次发送多个请求,但是按照顺序执行并返回)即每个HTTP连接只请求一个资源,浏览器只能通过建立多个连接来解决并发问题。此外HTTP中对请求是严格的FIFO进行的,如果中间某个请求处理时间过长,那么会阻塞掉后面的请求。

HTTP只允许由客户端主动发起请求

服务端只能等待客户端发送一个请求,对于可以预加载的场景来说,这是一个限制。

HTTP头冗余

HTTP头在同一个会话里反复发送的一些头信息其实是冗余的,比如User-Agent, Host等。这会造成带宽等资源的浪费。

SPDY的优点:

多路复用,请求优化

spdy规定在一个spdy连接内可以有无限个并行请求,即允许多个并发HTTP请求公用一个TCP会话。这样spdy通过复用在单个TCP连接上的多次请求,而非为每个请求单独开放连接,这样只需要建立一个TCP连接就可以传送网页上所有资源,有效减少了连接数,这对于客户端、服务端来说都是一个好消息。此外,spdy的多路复用可以设置优先级,而不像传统的http那样严格按照FIFO策略来进行处理,它会选择性地线传输CSS这样更重要的资源,然后再传输网站图标一类的相对不那么重要的资源,可以有效提高用户体验。

spdy压缩了HTTP头

因为是复用当前的TCP连接,所以有一些头就不需要每次都传输了,比如(User-Agent, Host等),这样可以节省多余数据传输所带来的等待时间和带宽。

强制使用ssl/tls协议

Web的未来发展必定是安全的网络连接,所以使用ssl/tls对传输进行加密之后,可以有效降低MITM(man-in-the-middle)攻击。(量子传输也可以做到,而且似乎比ssl更加优雅)

支持服务器推送技术

服务器可以主动向客户端发起通信,向客户端推送数据(得益于多路复用),这种预加载可以使用户一致保持一个快速的网络。总结:spdy是对HTTP协议的一个重大的改进,ietf也充分吸收了spdy协议的改进建议并应用到了http2上。

HTTP/2

当前版本,于2015年5月作为互联网标准正式发布。

HTTP2新增功能概述

  1. HTTP/2采用二进制格式传输数据,而非HTTP/1的文本格式。
  2. HTTP/2对消息头采用HPACK进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1每次请求都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决这个问题。
  3. 多路复用,直白的说就是所有的请求都是通过一个TCP连接并发完成。HTTP/1虽然能利用一个连接完成多次请求,但是这个请求之间是有先后顺序的,如果某个请求阻塞了,那么后面的请求就都必须等待。而HTTP/2则做到了真正的并发请求。同时,流还支持优先级和流量控制。
  4. Server Push:服务端能够更快的把资源推送给客户端。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML再发送这些请求。当客户端需要的时候,文件已经在客户端了。

HTTP/2是HTTP/1在底层传输机制上的完全重构,HTTP/2基本兼容HTTP/1语义。但是也有一些不同,例如: Content-Type依然是Content-Type,但是它不再是文本传输了。