HTTP协议入门
HTTP协议是基于TCP/IP
协议之上的应用层协议,默认使用80端口(HTTPS默认使用443端口)。HTTP协议是属于Client-Server
模型,是无状态。
为什么说HTTP协议是无状态的呢,我的理解是,在协议层面HTTP协议是无状态的,请求没有记录上下文,请求之间不存在事物关系,每个HTTP请求都是完全独立的。请求的状态是靠Cookie
和Session
保持的。这样,即使在HTTP/1.1(同一个连接上允许传输多个HTTP请求)之上的协议,第一个请求出错了,也不影响第二个第三个请求的处理。
但是,从HTTP/2协议开始,对HTTP的请求头做了压缩和索引处理(客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了)。因此,HTTP/2协议是有状态。
HTTP协议的发展史
HTTP/0.9-短链接
HTTP最早的版本,发布于1991年,只有一个GET
命令,协议规定,服务器只能回应HTML格式的字符串,不能回应别的格式。服务器发送完response,就关闭TCP连接。每次HTTP请求都要经过 DNS解析->TCP三次握手->HTTP传输->TCP四次挥手
HTTP/1.0-长链接概念出现
1996年5月发布,支持不仅仅是HTML格式的传输(图像、视频、二进制文件等等),引入了POST,HEAD等命令。增加了Header这样的元数据信息,response还增加了status code,多字符集支持等等。
HTTP/1.0,每个TCP连接只能发送一个HTTP请求,发送完HTTP请求就关闭,不能复用。而TCP需要三次握手,建立TCP连接的开销还是很大的,所以出现了Connection: keep-alive
参数。但是此时不是标准参数,不同的实现可能不一样,所以并不能说解决了问题。
HTTP/1.1-长连接成为默认的连接方式
1997年又推出了HTTP/1.1,HTTP/1.1主要是为了解决HTTP/1.0中存在的一些缺点。最大的一点,长链接成为默认连接方式,即使请求的Header没有携带Connection: Keep-Alive
,也默认是长链接的方式。同时,提出了HOLB(Head of Line Blocking,列头阻塞)
的问题(长连接中请求是串行的,如果某个请求出现网络阻塞等问题,会导致同一连接上的后续请求被阻塞)。
Tomcat中,keepAliveTimeout的默认值是connectionTimeout
的值,connectionTimeout
的默认值是60000(60s)。同时维护这么多的长链接,这其实也是很大的开销。
除此之外,还引入了管道的概念(pipelining
):客户端可以在一次请求发送完成后,不等待服务端相应便直接发起第二个请求,服务端的响应还是按照请求的顺序串序返回(为了匹配多个请求和多个响应)。这样,HOLB(Head of Line Blocking)
的问题依然存在。所以pipelining
并没有被所有浏览器支持,且大部分会将其默认关闭。
SPDY与HTTP/2-多路复用
2009年,为解决HTTP/1.1效率不高的问题,谷歌提出了SPDY(SPeeDY
)协议,SPDY可以认为是HTTP/2协议的前身和探路者。目前SPDY项目已经被谷歌关闭,正式让位于HTTP/2。
multiplexing(多路复用,在SPDY中就提出了,并被HTTP/2继承),multiplexing技术能够让个多个请求和响应的传输完全混杂在一起进行,通过streamId
来互相区别。这样就解决了HOLB(Head of Line Blocking)
问题。
除此之外,还有二进制帧层:在客户端-服务端之间的传输方式改为更有效率的二进制形式(之前文本/二进制都可以)。报文中的二进制帧被细分为头部帧
和数据帧
,并对头部帧
提供了专门的压缩方式。同时,,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
HTTP/2还支持了消息推送(Server Push)的能力,允许服务端未经请求,向客户端发送资源。不过现阶段实际推广和使用,效果好像很一般。
HTTP与HTTPS
HTTP是明文传输的,在TCP协议之上就是HTTP协议。HTTPS就是在TCP协议之上,加了层安全协议(SSL或TSL)。传输层安全性协议(Transport Layer Security,缩写:TLS)及其前身安全套接层(Secure Sockets Layer,缩写:SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。HTTPS通常也被称为HTTP over TLS
、HTTP over SSL
、HTTP Secure
。HTTPS利用HTTP通信,在其上利用TLS/SSL
来加密数据包。
1994年网景公司(Netscape)推出了HTTPS协议,以SSL加密。IETF(互联网工程任务组)后将SSL标准化,在1999年公布了第一版TLS标准文件(TLS1.0,基于1996年发布的SSL3.0,2014年10月,Google发布在SSL 3.0中发现设计缺陷,建议禁用此一协议)。
关于HTTPS加密,如果使用对称加密,双方拥有相同的密钥,容易泄漏密钥(有很多的client,也确实容易被泄漏)。使用非对称加密,服务端持有私钥,client端持有公钥。但是这又出现了一个新的问题:如何避免中间人攻击? 因此,出现了第三方可信任的CA机构(证书授权中心Certificate Authority),Server将自己的公钥提交给CA机构,CA机构为其颁发一个CA签名过的证书,证书会包括证书颁发机构,有效时间,公钥,证书所有者,签名等信息。在进行HTTPS请求时,Server会将这个数字证书返回给Client,Client收到Server返回的数字证书后,会验证有效时间,颁发机构等等信息。然后从操作系统中取出对应CA机构的公钥,对Server发过来的证书进行解密,比较二者的Hash值。
HTTP/3-QUIC(Quick UDP Internet Connections)
在HTTP/3中,将弃用TCP协议,改用基于UDP的QUIC协议。QUIC位于OSI七层模型的传输层。(HTTP协议是应用层协议)。
HTTPS请求需要TLS(Transport Layer Security,传输层安全性协议),而QUIC使协商密钥和支持的协议成为初始握手过程的一部分。QUIC使用UDP协议作为其基础,并且在QUIC级别而不是UDP级别重传丢失的数据。