HTTP/1.0支持GET和POST请求方式本质上支持长连接,但默认是短连接,添加keep-alive关键字将短连接变为长连接HTTP请求和响应格式也变了。每次通信除了要传输的数据外,还包含头信息来描述一些信息。还加入了状态码(statuscode)、多字符集支持、多部分传输(multi-parttype)、权限(authorization)、缓存(cache)、内容编码(contentencoding)等HTTP/1.1HTTP1。1最大的变化是引入了长连接,即TCP连接默认不关闭,可以被多个请求复用。如果客户端或服务端发现对方长时间没有活动,就会关闭连接,但标准做法是客户端在上次请求时请求服务端关闭连接。对于同一个域名,目前浏览器支持建立6-8个长链接(chrom、6、firefox、8)。主要缺点是连接速度慢,服务器只能按顺序响应。如果某个请求耗时较长,就会出现请求队列阻塞。HTTP/2.0的特点BinaryframingheadercompressionflowcontrolmultiplexingrequestpriorityserverpushBinaryframing没有改变HTTP1.x的语义、方法和状态码。在URL和头域方面,HTTP2.0通过在应用层(HTTP)和传输层(TCP)之间增加了一个二进制分帧层,突破了HTTP1.1的性能限制,提高了传输性能,实现了低延迟高吞吐量Frame:HTTP2.0通信的最小单位,所有帧共享一个8字节的头部,其中包含帧的长度、类型、标志和一个保留位,至少有一个标识流的标识符当前帧属于哪个帧,帧携带特定类型的数据,例如HTTP标头、有效负载等。消息:大于帧的通信单元,是指逻辑HTTP消息,如请求和响应。流由一个或多个帧组成:比消息大的通信单元。它是TCP连接中的一个虚拟通道,可以承载双向消息。每个流都有一个唯一的整数标识符头压缩HTTP1.1不支持HTTP头压缩,为此出现了SPDY和HTTP2.0。SPDY使用的是DEFLATE算法,而HTTP2.0使用的是专门为头部压缩设计的HPACK算法。流量控制HTTP2.0为数据流和连接流提供了一种简单的机制:流量是基于HTTP链接的每一跳,而不是端到端的控制流量控制是基于窗口更新帧,即接收者广播本身对于某个数据流要接收多少字节,对于整个链路要接收多少字节。流控是有方向的,即接收方可以根据自己的情况为每个流甚至整个链路设置任意的窗口大小。接收方可以禁用流控制,包括针对单个流和整个链路。帧类型决定了流控是否适用于该帧。目前只有DATA帧进行流控,其他类型的帧不占用流控窗口空间。这样可以确保重要的控制帧不会被流量控制阻塞。服务端推送服务端根据客户端的请求提前返回多个响应,向客户端推送额外的资源。不足的是http2是基于tcp协议的。tcp协议在设计之初并不是基于当前高质量、高带宽的网络基础设施而设计的。充分考虑了数据的可靠性,谨慎行事。在传输速率性能方面,它已经跟不上当前的网络基础设施。未来是否会开发出更优化的网络层协议还有待观察,包括基于udp协议的QUIC协议。我个人认为还是由os内核来实现下层协议比较好。QUIC协议是在应用层实现的,而不是操作系统的内核层,这一直是一个弱点。大多数http2实现和应用程序(包括浏览器和Web服务器)实际上必须基于TLS(SSL)安全套接字层。对于一个承载互联网内容的基础协议来说,这样的安全考虑是合理且必要的。有优点也有缺点。TLS的握手和数据加密过程难免会给通信和通信双方带来一些负担。这些负担和额外成本对于某些内部应用程序有时是不必要的,例如后端微服务之间,并且可以简化。由于现实世界是基于http1建立起来的,一些通信链路上的基础设施,比如http代理,暂时还不能支持http2,所以这会阻碍http2的落地,而且这个障碍可能是一个长期的过程.由于http2是二进制的,传输是多路复用的,所以在不同帧的设计中都考虑了压缩、优先级控制、流量控制、服务器推送,这使得http2协议更加复杂。因此,协议的实现和应用程序的调试,相比单纯的明文http1,显然会增加一些难度。简单直观,对于人类来说,有着天然的亲和力。常见状态码1xx:Instructions-表示请求已收到,继续处理2xx:Success-表示请求已成功收到3xx:Redirect-表示必须进行进一步的操作才能完成请求4xx:Clienterror-表示arequest存在语法错误或请求无法执行5xx:servererror-表示服务器未能执行合法请求HTTP/3.0背景由于HTTP2.0依赖于TCP,如果TCP有任何问题,就会出现HTTP2的一些问题。最重要的是队头拦截。应用层的问题解决了,但是TCP协议层的队头阻塞还没有解决。当TCP丢失一个数据包时,它会重传它。如果前面没有收到一个数据包,它只能将后面的数据包放入缓冲区。应用层取不到数据。也就是说,HTTP2的多路复用并行性对于TCP的丢失恢复机制不起作用,因此丢失或重新排序的数据会导致交互挂起。为了解决这个问题,Google发明了QUIC协议特性,在传输层直接干掉TCP,取而代之的是UDP,实现了一套新的拥塞控制。该算法彻底解决了TCP中的队头阻塞问题,实现了类似TCP的流量控制和传输可靠性等功能。虽然UDP不提供可靠传输,但是QUIC在UDP之上加了一层保证数据可靠传输。它提供了数据包重传、拥塞控制等TCP中存在的一些特性来实现快速握手功能。由于QUIC是基于UDP的,QUIC可以使用0-RTT或者1-RTT来建立连接,也就是说QUIC可以最快的速度发送和接收数据。集成TLS加密功能。目前QUIC使用TLS1.3HTTPS数字证书来验证服务器的身份。如果没有验证,可能会被中间人劫持。如果请求被中间人拦截,中间人会将自己的公钥给客户端,客户端收到公钥后将信息发送给中间人。中间人解密数据后,再请求实际的服务器,得到服务器公钥,然后将信息发送给服务器。服务器和CA组织有一对密钥(公钥和私钥),那么如何生成数字证书呢?CA组织通过摘要算法生成服务器公钥的摘要(hashabstract)。CA组织通过CA私钥和特定的签名算法对摘要进行加密,生成签名,将签名、服务器公钥等信息打包成数字证书,返回给服务器服务器配置好证书后,客户端连接到服务器,首先将证书发送给客户端进行验证,得到服务器的公钥。证书验证使用CA公钥和声明的签名算法对CA中的签名进行解密,得到服务器公钥的摘要内容,然后使用摘要算法生成证书中服务器公钥的摘要,然后将这个摘要和上一步得到的摘要进行对比,如果一致证明证书是合法的,那么里面的公钥也是正确的,否则就是非法的。证书认证分为单向认证和双向认证。单向认证:服务器发送证书,客户端验证证书。双向认证:服务端和客户端互相提供证书,互相验证对方的证书。但是,大多数https服务器都是单向身份验证。如果服务端需要验证客户端的身份,通常会使用用户名、密码、手机验证码等凭据进行验证。只有要求更高的系统,比如大额网银转账,才会提供双向认证场景,保证客户身份的认证加密过程真正用在TLS中。两种算法的混合加密。对称加密算法的密钥通过非对称加密算法进行交换。交换完成后,使用对称加密对传输的数据进行加解密。这确保了会话的机密性。过程如下。浏览器向服务器发送一个随机数client-random和支持的加密方法列表。服务器向浏览器发送另一个随机数server-random、加密方法和公钥。浏览器再生成一个随机数pre-random,用公钥加密后发送给服务器,再用私钥解密得到这个pre-random。浏览器和服务器将这三个随机数与加密方式混合生成最终的密钥。即使被拦截,中间人在没有私钥的情况下也会拿不到预随机,无法生成最终密钥。对称加密算法使用相同的密钥进行加密和解密。如AES、DES。加解密过程:浏览器向服务器发送一个随机数client-random和支持的加密方式列表。服务器返回另一个随机数server-random和双方支持的加密方式给浏览器。将随机数混合生成一个密钥,该密钥是通信双方加密和解密的密钥。优点内容加密,中间无法查看原始内容身份认证保证用户正确访问。数据完整性,防止内容被第三方冒充或篡改并不是绝对安全的,但当前架构下最安全的解决方案是文案,这大大增加了中间人攻击的成本。需要的钱不够,越是强大的证书,需要绑定的证书就越贵。固定IP,不能在同一个IP上绑定多个域名。双方进行HTTPS加解密会消耗更多的服务器资源。HTTPS握手比较耗时,会减慢某些用户的访问速度(优化不是缺点)TLS1.2握手浏览器服务器发送一个随机数客户端-随机,TLS版本和支持的加密方法列表。服务器向浏览器生成一个椭圆曲线参数server-params、随机数server-random、加密方式、证书等。浏览器生成一个椭圆曲线参数。client-params、握手数据摘要等信息发送给服务器,服务器将摘要返回给浏览器进行确认。该版本不再生成椭圆曲线参数client-params和server-params,而是在server端和浏览器端都获取server-params。和client-params之后,用ECDHE算法直接计算pre-random,两边有3个随机数,然后将3个随机加密混合,生成最终的key。TLS1.3握手在TLS1.3版本中RSA算法被废弃,因为RSA算法可能会泄露私钥导致所有历史消息被破解,而ECDHE算法每次握手都会生成一个临时密钥,所以即使私钥被破解,也只能破解一条消息,不会影响之前的历史信息。目前主流的是使用ECDHE算法进行密钥交换。浏览器生成client-params、client-random、TLS版本和加密方式列表发送给服务器。服务器返回服务器参数、服务器随机数、加密方法、证书和摘要。等待浏览器确认响应,将握手数据摘要等信息返回给服务器。简而言之,它简化了握手过程。只有三个步骤。将原来的两个RTT打包成一个发送,减少了发送次数。这种握手方式也叫1-RTThandshake继续握手优化可以使用sessionmultiplexing
