读《图解HTTP》总结

读《图解HTTP》总结,让读者对HTTP协议形成一个整体的概念,推荐初学阅读,或者在准备啃《HTTP权威指南》之前,先形成一定的体系。由浅入深

HTTP的诞生

1989年3月,互联网还只属于少数人,在这一互联网的黎明期,HTTP就诞生了。
CERN(欧洲核子研究组织)的蒂姆·博纳斯—李(Tim Berners-Lee)博士提出了一种能让远隔两地的研究者们共享知识的设想
最初设想的基本理念即:

借助多文档之间相互关联形成的超文本(HyperText),连成可相互参阅的WWW(World Wide Web,万维网)。

现在已提出了3项WWW的构建技术,分别是:

把SGML(Standard Generalized Markup Language,标准通用标记语言)作为页面的文本标记语言的HTML(HyperText Markup Language,超文本标记语言);

作为文档传递协议的HTTP;

指定文档所在地址的URL(Uniform Resource Locator,统一资源定位符)。
WWW这一名称,也是Web浏览器当前用来浏览超文本的客户端应用程序时的名称,现在则用来表示这一些列的集合,也可简称为Web。

网络基础TCP/IP

为了了解HTTP,我们需要先了解下TCP/IP协议族
通常的网络是在TCP/IP协议族的基础上运作的,而HTTP 属于他内部的子集
协议中存在各式各样的内容,从电缆的规格到IP地址的选定方法,寻找异地用户的方法,双方建立通信的顺序,以及web页面需要处理的步骤等等

TCP/IP的分层管理

应用层

应用层决定了向用户提供应用服务时通信的活动。
TCP/IP协议族内预存了各类通用的应用服务,比如FTP(文件传输协议),DNS(域名系统)就是其中的两类,HTTP协议也处于该层

传输层

传输层对上传应用层,提供处于网络连接中的两台计算机之间的数据传输
在传输层有两个性质不同的协议:TCP(传输控制协议),UDP(用户数据报协议)

网络层

网络层用来处理网络上流动的数据包,数据包是网络传输的最小数据单位,该层规定了通过怎样的路径(所谓的传输线路)到达对方计算机,并把数据包传送给对方
与对方计算机之间通过多台计算机或网络设备进行传输时,网络层的作用就是在众多的选项内选择一条传输路线

链路层 (数据链路层,网络接口层)

用来处理链接网络的硬件设备部分,包括控制操作系统,硬件的设备驱动,NIC(网络适配器,网卡)及光纤等物理可见部分,硬件上的范畴均在链路层的作用范围之内

TCP/IP通信传输流

为了方便传输,在传输层(TCP协议)把应用层收到的数据报进行分割并在各个报文上打上标记序号及端口号后转发给网络层。
在网络层(IP协议),增加作为通信目的地的MAC地址后转发给链路层,

通信传输流

确保可靠性的TCP协议

TCP属于传输层,提供可靠的字节流服务,将大块数据分割以报文段位单位的数据包进行管理,为了准确无误的传输。
TCP采用了三次握手, 握手过程使用了SYN和ACK
首先发送一个带SYN的数据包给对方,接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后发送端再回传一个ACK标志的数据包,代表握手结束。
shake hand

负责传输的IP协议

IP协议的作用是把各种数据包传输给对方,而要保证确实传送到对方那里,则需要满足各类条件,其中两个重要的条件就是IP地址和MAC地址。
IP地址指明了节点被分配的地址,MAC地址是指网卡所属的固定地址,IP地址可以和MAC地址进行配对,IP地址可变换但MAC地址基本上不会更改

使用ARP协议 凭借MAC地址进行通信
IP间的通信依赖MAC地址,在网络上,通信双方在同一局域网内的情况是很少的,通常是经过多台计算机和网络设备中转才链接到对方,而在进行中转时,会利用下一站中转设备的MAC地址来搜索下一个中转目标,这时,会采用ARP协议,ARP协议是一种用以解析地址的协议,根据通信方的IP地址就能反查出对应的MAC地址
IP

负责域名解析的DNS服务

DNS服务是和HTTP协议一样位于应用层的协议。它提供域名到IP之间的解析服务
DNS

HTTP协议与个协议的关系

图

简单的HTTP协议

HTTP是无状态的,即无状态(stateless)协议,HTTP协议自身不对请求和响应之间的通信状态进行保存。

持久链接

为了解决HTTP初始版本中,每一次通信就要断开,建立一次TCP链接的问题,在1.1(和一部分1.0)提出了持久连接,也称为 HTTP keep-alive,只要任意一端没有明确提出断开连接,则保持TCP连接状态

管线化(pipelining)

持久链接使得多数请求以管线化方式发送成为可能,以前发送请求后需要等待接收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求

使用Cookie的状态管理

HTTP是无状态的,但是服务器通常要保存客户端的状态,保留无状态的特征的同时又要解决类似的矛盾问题,于是引入了Cookie技术,通过在请求和响应报文中写入Cookie信息来控制客户端的状态
解决1.0TCP每次都会重新连接的问题,在1.1提出了持久连接,也称为 HTTP keep-alive,只要任意一端没有明确提出断开连接,
则保持TCP连接状态
cookie

HTTP报文组成

用于HTTP协议交互的信息被称为HTTP报文,请求端的HTTP报文叫做请求报文,响应端的叫做响应报文。
HTTP本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
报文组成

请求报文及响应报文的结构

请求和响应报文
示例
示例

请求行

包含用于请求的方法,请求URI和HTTP版本

状态行

包含表明响应结果的状态码,原因短语和HTTP版本

首部字段

包含表示请求和响应的各种条件和属性的各类首部。

一般有4中首部:通用首部,请求首部,响应首部和实体首部。

编码提升传输速率

HTTP在传输数据时可以按数据源码传输,也可以在传输过程中通过编码提升传输效率,但编码的操作是要计算机来完成,因此会消耗更多的CPU资源。

压缩传输的内容编码

常用的内容编码有以下几种

  • gzip(GNU zip)
  • compress (UNIX系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)
    示例

分割发送的分块传输编码

在HTTP通信过程中,请求的编码视图资源尚未全部传输完成之前,浏览器无法显示请求页面,在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。
示例
分块传输编码会将实体主体分成多个部分,每一块会用十六进制来标记快的大小,而实体的最后一块会使用“0(CR+LF)”来标记

返回结果的HTTP状态码

1
2
3
4
5
1XX:Informational      (信息性状态码)        接收的请求正在处理
2XX:Success (成功状态码) 请求正常处理完毕
3XX:Redirection (重定向状态码) 需要进行附加操作以完成请求
4XX:Client Error (客户端错误状态码) 服务器无法处理的请求
5XX: Server Error (服务端错误状态码) 服务器处理请求出错

2XX 成功

请求在服务端被正常处理了

200 OK

客户端发送的请求在服务端被正常处理。
示例

204 No Content

服务器收到的请求已成功处理,但在返回的响应报文中不含实体的主体部分,返回204浏览器显示的页面不发生更新。

一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用
示例

206 Partial Content

客户端进行了返回请求,而服务端成功的执行了这部分的GET请求,响应报文中由“Content-Range”指定范围的实体内容
示例

3XX 重定向

3XX响应表明浏览器需要执行某些特殊的处理以正确的处理请求

301 Moved Permanently

永久性重定向,该状态码表示请求的资源已被分配了新的URI,这是应该按照“Loaction”首部字体提示的URI重新保存。
示例

302 Found

临时性重定向,该状态码表示请求的资源已经被分配了新的URI,希望用户(本次)能够使用新的URI访问
示例

303 See other

该状态码表示由于请求对应的资源存在另一个URI,应使用GET方法定向获取请求的资源。303和302有着相同的功能,但303表示客户端应采用get方法获取资源。
示例

304 Not Modified

客户端发送附带条件的请求时,服务端允许请求访问资源,但未找到满足条件的情况。
示例
附带条件通常指:

  • If-Match
  • If-Modified-Since
  • If-None-Match
  • If-Range
  • If-Unmodified-Since

中的任一首部

4XX 客户端错误

4XX 的响应结果表明客户端是发生错的原因所在

400 Bad Request

该状态码表示请求报文中存在语法错误。
示例

401 Unauthorized

该状态码表示发送的请求需要有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息,另外如果已经进行了1次请求,则表示用户认证失败
示例

403 Unauthorized

该状态码表明对请求资源的访问被服务器拒绝了。

示例

404 Not Found

该状态码表明服务器上无法找到请求的资源,除此之外,也可以在服务器端拒绝请求且不想说明理由时使用

5XX 服务器错误

5XX的响应结果表明服务器本身发生错误

500 Internal Server Error

该状态码表明服务器端在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的故障。
示例

503 Service Unavailable

该状态码表明服务器端暂时处于超负载或进行停机维护,现在无法处理请求,如果事先得知解除以上状况需要的时间,最好写入“Retry-After”首部字段在返回给客户端
示例

通信数据转发程序:代理,网关,隧道

代理

一种有转发功能的应用程序,他扮演了位于服务器和客户端“中间人”的角色,绝收客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端
代理不会改变请求URI,在转发时附加Via首部字段标识经过的主机信息。

网关

转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,他就像自己拥有资源的服务器一样对请求进行处理。
和代理的工作机制类似,使通信线路上的服务器提供非HTTP协议服务,提高通信的安全性。

隧道

隧道是在相隔甚远的客户端和服务器两者之间进行中转,并报出双方通信连接的应用程序
可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信,隧道的目的是确保客户端能与服务器进行安全的通信

HTTP首部

HTTP请求报文

在请求中,HTTP报文由方法,URI,HTTP首部字段等部分构成
示例

HTTP响应报文

在响应中,HTTP报文由HTTP版本,状态码,HTTP首部字段3部分构成。
示例

HTTP首部字段

使用首部字段是为了给浏览器和服务器提供报文主体大小,所使用的语言,认证信息等内容。

通用首部字段

请求报文和响应报文两方都会使用的首部。

请求首部字段

从客户端向服务器端发送请求报文时使用的首部,补充了请求的附加内容,客户端信息,响应内容相关优先级等信息

响应首部字段

从服务器端向客户端返回响应报文时使用的首部,补充了响应的附加内容,也会要求客户端附加额外的内容信息。

实体首部字段

针对请求报文和响应报文的实体部分使用的首部,补充了资源内容的更新时间与实体有关的信息

HTTP/1.1首部字段一览

请求首部

示例

响应首部

示例

实体首部

示例

各个字段的详细使用方法请参阅原书

HTTPS

HTTP的不足如下

  • 使用明文通信,内容可能被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装
  • 无法验证报文的完整性。所以有可能已遭篡改

加密处理防止被窃听

通信加密

一种方式是将通信加密。HTTP协议中没有加密机制,但可以通过和SSL(Secure Socket Layer,安全套接层)或者TLS(Transport Layer Security,安全层传输协议)的组合使用,加密HTTP的通信内容,与SSL组合使用的HTTP 被称为HTTPS

内容加密

还有一种将参与通信的内容本身加密的方式,由于HTTP协议没有加密机制,那么就对HTTP协议传输的内容本身加密,即把HTTP报文所含的内容进行加密处理

通过证书确定通信对方

虽然HTTP协议无法确定通信方,但是如果使用SSL则可以,SSL使用了一种被称为证书的手段,可用于确定方

如何防止被篡改

单单使用MD5和PGP 是无法确保结果百分之百正确,因为如果PGP和MD5本身被改写,用户是没法办法意识到的,所有必须配合HTTPS,SSL提供认证加密处理及摘要功能,紧靠HTTP 确保完整性是非常困难的

SSL

SSL采用一种叫做公开密钥加密的处理方式

共享密钥加密

加密和解密使用一个密钥的方式被称为共享密钥加密,也叫对称加密。以共享密钥方式加密时必须将密钥也发送给对方(或者双方预先约定好密钥格式内容)。如果密钥丢失,意味着加密也就失去了意义。
图片

使用两把密钥的公开密钥加密

公开密钥加密方式很好地解决了共享密钥加密的困难。
公开密钥加密使用一对非对称加密的密钥,一把叫做私有密钥,另一把叫做公开密钥。
使用公开密钥加密方式,发送密文的一方使用对方公开的密钥进行加密处理,对方收到加密信息后,在使用私有密钥进行解密。
图片

HTTPS 采用混合加密机制

在加交换密钥阶段使用公开加密方式,之后的建立通信交换报文阶段则使用共享加密方式
图片

HTTPS的安全通信机制

HTTPS的通信步骤
图片
步骤1:
客户端通过发送Client Hello 报文开始SSL通信,报文中包含客户端支持的SSL的指定版本,加密组件(Suite)列表(所使用的的加密算法及密钥长度等)
步骤2:
服务端可进行SSL通信时,会以Server Hello 报文作为应道,和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接受到的客户端加密组件内容筛选出来的。
步骤3:
之后服务端发送Certificate报文,报文中包含公开密钥证书。
步骤4:
最后服务器发送Server Hello Done 报文通知客户端,最初阶段的SSL握手协商部分结束。
步骤5:
SSL第一次握手结束之后,客户端已Client Key Exchange报文作为回应,报文中包含通信加密中使用的一种被称为 Pre-master-secret的随机密码串,该报文已用步骤3中的公开密钥进行加密。
步骤6:
接着客户端继续发送 Change Cipher Spec 报文,该报文会提示服务器,在此报文之后的通信会采用Pre-master secret 密钥加密。
步骤7:
客户端发送Finished报文,该报文包含连接至今全部报文的整体校验值,这次握手能否成功,要以服务器是否能够正确解密该报文作为判定标准。
步骤8:
服务器同样发送Change Cipher Spec 报文。
步骤9:
服务器同样发送Finished报文。
步骤10:
服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成,当然,通信会受到SSL的保护,从此处开始进行应用层协议的通信,即发送HTTP请求。
步骤11:
应用层协议通信,发送HTTP响应。
步骤12:
由客户端断开链接,断开链接时,发送close_notify报文,上图做了一些省略,这步之后在发送TCP FIN报文来关闭TCP的通信。
下面是对整个流程的图解,从仅使用服务端的公开加密证书建立HTTPS通信的整个过程
图片

HTTP 的功能追加协议

HTTP的瓶颈

  • 一个连接只可以发送一个请求
  • 请求只能从给客户端发起,客户端不可以接受除响应以外的指令
  • 未经压缩就发送,首部信息越多延迟越大
  • 发送冗长的首部,每次互相发送相同的首部造成的浪费较多
  • 非强制压缩发送,可任意选择数据压缩格式

Ajax 的解决方法

名为XMLHttpRequest的API,通过JavaScript的调用实现HTTP通信,从已加载完的web发起请求,只更新局部页面

Comet的解决方法

通过延迟应答,默契实现服务端像客户端推送的功能。
Comet在收到请求后,不会立即返回响应,会先至于挂起状态,等内容与更新时,在返回。但是为了保留响应,一次连接的持续时间也变长了。

SPDY

SPDY规定通信中使用SSL,SPDY会议会话层的形式加入,控制对数据的流动,但还是采用HTTP建立通信连接。
图片
使用SPDY后,HTTP额外获得以下功能:

多路由复用

通过单一的TCP连接,可以无限制处理多个HTTP请求,所有请求的处理都在一条TCP上完成,因此提高了TCP的处理效率。

赋予请求优先级

SPDY不进可以无限制的并发处理,还可以逐个分配优先级,主要是为了在发送多个请求时,解决因带宽低导致响应变慢的问题。

压缩HTTP首部

压缩HTTP请求和响应的首部。减少数据包数量和发送的字节数。

推送功能

支持服务端主动向客户端推送数据的功能。

服务器提示功能

服务器可以主动提示客户端请求所需的资源。由于客户端发现资源之前就可知获知资源的存在,因此在资源已缓存等情况下,可以避免发送不必要的请求。

WebSocket

Web浏览器与Web服务器之间全双工通信标准。
单工:
数据只在一个方向上传输,不能实现双方通信,例如:电视、广播。
半双工:
允许数据在两个方向上传输,但是同一时间数据只能在一个方向上传输,其实际上是切换的单工,例如:对讲机。
全双工:
允许数据在两个方向上同时传输,例如:手机通话。

WebSocket主要特点

  • 推送服务
  • 减少通信量,只要建立连接,就希望一直保持。
    为了实现WebSocket 通信,在HTTP 建立之后,需要完成一次“握手过程”的步骤
  • 握手-请求:通过Upgrade首部告知服务器通信协议发送改变,以达到握手的目的
  • 握手-响应:对之前的请求返回101 Switching Protocols的响应

    HTTP/2.0

    HTTP/2 可以说是google早些年推出的SPDY方案的升级版,HTTP2.0 跟 SPDY 不同的地方主要是以下两点:
  • HTTP2.0 支持明文 HTTP 传输,SPDY 强制使用 HTTPS
  • HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE

HTTP/2.0 的特点

多路复用(Multiplexing)

即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。

首部压缩

HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小

服务端推送

同SPDY一样,HTTP2.0也具有server push功能。

二进制协议(分帧)

HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮,HTTP2.0是运行在TCP连接上的应用层协议,接受服务器或发送请求时,会自动将头部信息/request body分成HEAD帧和DATA帧。