HTTP/0.9 The One Liner
第一个版本的HTTP规范是1991年提出的HTTP/0.9。只支持GET方法。
举个例子:
Request
GET /index.html
Response
(response body)
(connection closed)
文字性再描述一遍
- Client(User Agent)发出一个Request
- Server返回一个html文档作为response后关掉链接
简单到令人发指的行为,所以
- 没有headers
- 只允许GET
- Response必须是HTML
HTTP/1.0 – 发布于1996
1.0新增了不少方法,比如POST和HEAD等。Response的范围也放宽了不少,比如图像、视频、纯文本等。
Request和Response有了header,404等status code首次被加入进来。其他的,诸如字符集、认证、缓存等等常见的内容也是在1.0被添加进来的。
Request HTTP/1.0
GET / HTTP/1.0
Host: kamranahmed.info
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10105)
Accept: */*
Response HTTP/1.0
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
(response body)
(connection closed)
值得注意的是,header是用ASCII编码的。但是,response的body已经可以是任意格式。
1.0最大的缺点是不支持TCP重用,每一个HTTP request都需要新建立一个TCP连接,这简直无法忍受。
在此期间,部分先驱者试图自定义一个headerConnection: keep-alive
,可以没有被广泛的支持。
HTTP/1.1 发布于1999
1.1新增改动
- 新的Request Method,PUT/PATCH/HEAD/OPTIONS/DELETE。
-
Request的Host header被指定为必须的。
-
Connection: keep-alive被写进规范,如果想要关掉这个连接,需要添加Connection: close到request header中。
-
Pipelining,支持用同一条TCP连接串行发送多个request,并等待response。在此情况下,response必须在header中添加Content-Length。
有个问题,如果response没有固定的长度怎么办。为了解决这个问题,参考下面的Chunked Encoding。
- Chunked Transfer,当server不知道整个response有多长的时候,可以用Chunked Transfer,也就是分片传输。每一小片发送的时候指定长度就可以了。当传输完成的时候,server发送一个空的chunk来标识结束。当然,为了和普通的response区分,发送chunk的时候要在response的header中添加Transfer-Encoding: chunked。
-
1.0只支持基础认证,1.1支持digest和proxy认证。
-
语言协商。
-
cookies。
-
等等。
如果想知道所有1.0和1.1之间的区别,可以去查看RFC或者看看[Key differences between HTTP/1.0 and HTTP/1.1](http://www.ra.ethz.ch/cdstore/www8/data/2136/pdf/pd1.pdf)
SPDY 发布于2009 Google这个棒槌。。。
Google在2009年发布了SPDY。一个致力于提升Web网速和安全性的协议。
并且:
SPDY是Google的商标,不是首字母缩写……
其核心思想:
网络性能的提升可以由带宽提升来改进,但这么做是有瓶颈。之所以有瓶颈是因为网络传输附带着额外的、隐形的开销。如果能忽略这些额外的开销,网络性能的提升和带宽的提升就是线性关系。
对于那些不了解情况的人,额外的开销就是延迟。比如说,数据从源头发送到目的地需要花费多长时间。带宽就是每秒钟能传输多少数据量。
提供的功能:
- 多路传输
- 数据压缩
- 传输优先级
- 安全
- 等等
SPDY的设计理念是作为一个HTTP之下的传输层协议。在request发送出去之前修改其内容。
到2015年的时候,google觉得多搞一层协议太麻烦了,所以就把SPDY的内容合并到HTTP协议,也就是HTTP/2。
HTTP/2 – 2015
HTTP/2设计用于降低传输内容时的额外开销。
几个关键不同点如下:
- 二进制代替文本
- 多路传输
- HPACK压缩header
- Server Push,一个request可以有多个response
- Request优先级
- 安全
- 二进制协议
HTTP/2致力于用二进制内容代替HTTP/1.x中的文本内容。二进制的内容比文本内容更容易被计算机解析,但是难以阅读。
HTTP/2最大的贡献就是帧和流。(Frames and Streams)
Frames and Strems
HTTP消息现在是由一个或多个frame组成。一个是由元数据(meta data)组成的header frame;一个由负载(payload)组成的数据frame;还有一些替他种类的frame,例如HEADERS、DATA、RST_STREAM、SETTINGS、PRIORITY等。参考链接HTTP/2规范
每一个HTTP/2的request和response都有一个唯一的stream ID,并且被分割到各种类型的帧中。frame只是一小片数据的意思。一组frame的集合被称为Stream。每个帧由stream id来标示其属于哪个stream,并且同一个stream中的frame拥有相同的header。除了stream id是唯一的之外,还有一点需要注意,由client初始化的request用奇数作为stream id,而server发出的response用偶数作为stream id。
除了HEADER和DATA frame,另一种比较值得注意的是RST_STREAM frame。这是一种特殊的用途frame,其用来中止stream。在HTTP/1.1中,如果想让server停止发送response,只能是断开当前的TCP链接。但这样做会导致额外的隐形开销,因为后续的request需要重新建立一条新的TCP链接。
-
多路传输
HTTP/2是一个二进制协议并且使用frame和stream来传递request和response。一旦TCP链接建立成功,所有的stream都在这一条相同的链接上异步的收发。server回复response的时候也是无序的,client需要自己去根据stream id来重新组装报文。这正好解决了HTTP/1.x中的head-of-line阻塞问题。Client可以同时处理多个request而不用等待耗时长的那个。
-
HPACK Header压缩
这是RFC文档中被分离出来的一小部分。其解决的问题是,我们经常会在header中使用相同的内容