导图社区 HTTP模块思维导图
前人栽树,后人乘凉!自己结合大佬的图解书籍,总结包括HTTP的发展历史,HTTP1.0 1.1 2.0 3.0以及各种TLS算法握手深度解析,每个HTTP版本详解,优劣,以及如何优化。关于HTTP的方方面面都有所涉及,现在我来栽树,希望能看到的朋友可以一起学习,无畏艰苦,共同进步。本思维导图也是本人第一次使用这款软件第一次制作,内容上理解有限;如有不对,欢迎指导。
编辑于2021-06-06 18:44:23详细的介绍了TCP的报文格式和特性,然后讲解了什么是TCP连接建立,连接断开,SYN洪水攻击,什么是RTT,RTO,什么是超时重传,什么是快速重传。滑动窗口怎么实现流量控制,什么是窗口死锁等。内容详细,通俗易懂。但是TCP东西还有很多,需要你们自己去检索。
前人栽树,后人乘凉!自己结合大佬的图解书籍,总结包括HTTP的发展历史,HTTP1.0 1.1 2.0 3.0以及各种TLS算法握手深度解析,每个HTTP版本详解,优劣,以及如何优化。关于HTTP的方方面面都有所涉及,现在我来栽树,希望能看到的朋友可以一起学习,无畏艰苦,共同进步。本思维导图也是本人第一次使用这款软件第一次制作,内容上理解有限;如有不对,欢迎指导。
社区模板帮助中心,点此进入>>
详细的介绍了TCP的报文格式和特性,然后讲解了什么是TCP连接建立,连接断开,SYN洪水攻击,什么是RTT,RTO,什么是超时重传,什么是快速重传。滑动窗口怎么实现流量控制,什么是窗口死锁等。内容详细,通俗易懂。但是TCP东西还有很多,需要你们自己去检索。
前人栽树,后人乘凉!自己结合大佬的图解书籍,总结包括HTTP的发展历史,HTTP1.0 1.1 2.0 3.0以及各种TLS算法握手深度解析,每个HTTP版本详解,优劣,以及如何优化。关于HTTP的方方面面都有所涉及,现在我来栽树,希望能看到的朋友可以一起学习,无畏艰苦,共同进步。本思维导图也是本人第一次使用这款软件第一次制作,内容上理解有限;如有不对,欢迎指导。
HTTP(HyperText Transfer Protocol)
HTTP 1.0
http 1.0每次请求都需要建立一次TCP连接,这也称为短连接;极大地造成了资源浪费
HTTP1.1
性能
长链接
早起的http1.0性能上每一次发起一个请求,都要串行的建立一次TCP连接。增加了无用的开销;因此1.1版本提出长链接的连接方式,也叫持久连接;只要一方没有明确的提出断开连接,则一直保持TCP连接状态。
管道网络传输(pipeline)
即在一个TCP连接里,客户端可以发送多个请求,只要第一个请求发送出去,不必等其回来则可以发送第二个请求;这样可以减少整体请求的响应时间。但是客户端必须按照发送请求的顺序来响应;这样如果前一个响应很慢,则后面的响应只能等,造成队头阻塞。
队头阻塞
要是因为某种原因造成了前一个响应被阻塞,后面的响应也无法被响应。导致客户端一直接收不到数据。
与HTTP1.0相比性能上的优缺点
优点
使用TCP长链接减少了性能开销和资源浪费
支持管道传输,可以同一时间向服务端发送多条请求
缺点
对于HTTP1.1的报文来说,无法对其头部进行压缩,高冗余的头部会造成很高的延迟,从而只能在报文的body中想办法进行压缩
没有对请求优先级的控制
服务器只能被动响应,无法主动推送资源
存在队头阻塞的问题
HTTP1.1 性能上该怎么优化?
尽量不发送HTTP请求
对于一些具有重复性的HTTP请求,比如每次请求得到的响应数据都一样,我们可以把这对请求-响应的数据都缓存在本地磁盘中,下次进行相同请求,就可以直接读取本地瓷盘中的缓存数据。从而减少HTTP请求。一般来说,客户端会把第一次请求和响应的数据保存下来,然后用URL来作为Key,响应数据作为Value,两者形成映射关系。
但是缓存的是第一次请求的响应数据,一般服务器在响应数据时会预估一个资源过期的时间,并放到响应头部中;当客户端读取缓存的响应数据时,发现缓存的资源已经过期了。这个时候客户端会重新发起网络请求,在请求的Etag字段中带上缓存的响应头部中的摘要,服务器接收到新的请求后,会将Etag中的摘要与自身相同URL中对应的数据做摘要,并与Etag中的摘要相比较,如果相同,表示资源未变动。在给客户端响应一个状态码为304的空包,告诉客户端资源未改变。如果不同,则响应最新的响应数据。客户端接收到资源并进行缓存更新。
尽量减少发送HTTP请求的次数
减少重定向的请求次数
服务器的资源可能因为迁移或者维护等原因,会从原来的URL1转移到URL2。这个时候客户端并不知情,还是继续用URL1来访问原来的服务器资源;但服务器不能粗暴的返回一个错误。而是用302状态码和头字段Location;来告诉客户端用新的URL2来访问资源。但是一般源服务器,上一级一般会存在代理服务器;这个时候会造成两次消息访问
但是重定向交给代理服务器来处理,并且在代理服务器了解了重定向规则后,就可以很好地减少重定向
合并请求
优点:可以把多个访问小资源的请求合并成一个大的请求,这样虽然请求的总资源不变,但是减少了重复发送的请求次数。因为HTTP1.1存在队头阻塞的问题,所谓浏览器一般会同时发送五六个TCP请求,每一个请求都是一次TCP连接,由于TCP存在慢启动和握手,就会非常耗时,而合并请求就会减少连接,减少总体请求时间
缺点:当请求的大资源中某个小资源发生问题,需要重新下载整个完整的资源,会非常造成网络消耗
延迟发送请求
在用户浏览网页时,可以先请求当前浏览页面的资源;未浏览的网页延迟资源请求。
尽量压缩响应报文中的Body数据
有损压缩
无损压缩
HTTP1.1优化总结
HTTPS
TLS握手过程
一般在TLS握手过程中需要非对称加密算法和对称加密算法共同加密。因为考虑到性能的问题;非对称加密加密对称加密的秘钥。因为非堆成加密慢但是安全性更高;对称加密只有一个秘钥加密速度快但不安全。并且一般的TLS只需要发送四个消息,也就是2个RTT完成握手。
RSA算法
RSA是非对称加密算法,用于一般的TSL密钥交换阶段的算法;下面是RSA握手解析
第一次握手
客户端向客户端发送Client Hello包
第二次握手
服务器发送Server Hello
这里涉及到双方支持的密码套件格式问题:密码套件格式为:交换秘钥算法+签名算法+WITH+对称加密算法+对称加密秘钥长度+分组模式+摘要算法
服务器为了验证自己的身份,发送Server Certificate.
这里涉及到客户端证书验证的问题
什么是数字证书,从何而来?
数字证书包含
持有者的公钥
持有者的相关信息
证书认证机构CA的信息
CA对证书文件的数字签名和其签名的算法
证书有效期
一些其他的信息
客户端验证服务器证书的过程:
首先CA将证书持有者的信息做一个摘要H1;然后用CA的私钥将摘要加密形成数字签名,然后形成持有者的数字证书。服务端在二次握手的时候将数字证书发给客户端,而CA的公钥是提前置于浏览器内部的;然后客户端用CA公钥将数字证书中的数字签名解密,然后用相同的摘要算法将证书中的内容做个摘要H2,H1与H2作比较。如果相同;则说明证书可信任;如果不相同;则证书不可信任
三层证书链
一般证书存在三层证书链;服务器的数字证书一般由中间证书颁发,中间证书由根证书颁发。当客户端拿到服务器的数字证书时;客户端无法通过本地根证书去验证服务器的合法性。只能在服务器证书找到颁发者的信息,然后从证书中获取到颁发者(中间证书)信息;然后从中间证书获取到根证书;然后根证书进行自证;发现无上层颁发者;然后从本地根证书清单查找此证书是否记录。如果有记录则可以信任。然后用根证书的公钥去验证中间证书是否可信任;再而用中间证书的公钥去验证服务器证书。
为什么要分证书层级?
这是为了保证根证书的绝对安全性;防止根证书安全发生问题
握手结束,服务器发送Server Hello Done
第三次握手
客户端会随机生成一个新的随机数pre-master;然后用服务端公钥加密;然后发送Change Cipher Key Exchange
客户端发送Change Cipher Spec,通知服务器接下来会使用生成了对称加密密钥进行对称加密传输
最后发送Encrypted Handshake Message;将之前所有握手数据做个摘要供服务器校验
第四次握手
服务器向客户端发送Change Cipher
服务器将之前所有握手消息做个摘要发送Encrypted Handshake Message;供客户端校验
RSA算法的缺陷
因为在RSA协商对称密钥的时候一次二次握手都有明文传输的随机数,三次握手用的服务器公钥加密,才生成对称密钥。这样如果第三次随机数加密被破解,那么本次的加密通信则毫无安全可言。所以RSA算法缺陷是不支持前向加密。
DH算法
DH算法非对称加密算法;是基于离散对数a^i*(mod P)=b 数学算法来实现对称密钥协商算法的。客户端和服务端双方各形成一个随机数作为自己的私钥;然后客户端发送HELLO包和服务端协商DH算法,并公开a和P;服务端通过算法用自己的随机数私钥生成自己的公钥。然后二次握手将自己的公钥发送给客户端。客户端会生成自己的公钥,然后用服务端的公钥和自己的私钥生成本次对称加密的密钥;然后做摘要。而服务端也会用客户端的公钥形成相同的密钥。
根据私钥的形成方式可以分为两种实现方式
DH Static算法
DH Static算法现在已经被废弃。因为这种算法在密钥协商的时候一般都是服务端的私钥静态的是不变的。所以服务端的公钥不变;久而久之黑客就会获取海量协商密钥的数据。从而可以暴力破解出本次协商的密钥。所以这种算法不支持前向加密。
DHE算法
而DHE算法是支持前向加密的。因为每次协商密钥的时吼双方都是随机生成一个随机数当作自己的私钥;每次协商的密钥都不相同,而且相互之间也无关联。所以比较安全。但是呢由于每次都需要离散对数来进行密钥算法;每次TLS握手需要大量的计算开销比较大。
ECDHE算法
现在比较广泛使用的密钥协商算法;在DHE的基础上使用ECC椭圆曲线的特性;用叫啥的计算量就可以协商出密钥。而且支持前向安全。
与RSA相比:更安全;而且ECDHE算法在三次握手的时候就可以进行HTTP数据的加密;不用等四次握手结束才进行数据的加密处理,省去了一次消息往返的时间。而且ECDHE的证书更小,在开销和性能上都有所升级。
ECDHE握手解析
第一次握手
客户端发送Client Hello
第二次握手
服务器收到客户端hello包后,回应一个Server Hello;里面包含自己确认的TLS版本和双方协商的密码套件
服务器为了验证自己的身份发送数字证书
服务器向客户端发送Server Key Exchange消息;这个时间服务器做了三件事:1:选择了x25519的椭圆曲线;曲线选择好就说明基点G确定了下来。 2:服务端生成一个随机数,作为自己的私钥。然后与基点G相乘;得到自己的公钥。 3:服务端保留自己的私钥;将曲线和自己的公钥都公开给客户端。 为了保证自己公钥不被更改;用协商好的密码套件中的签名算法给公钥签名。
服务端发送Server Hello Done ;说明数据已发送完
第三次握手
客户端收到服务器证书,先会验证服务器证书的合法性
客户端先生成一个随机数作为自己的私钥保存下来;会根据服务端发过来的椭圆曲线,计算出自己的公钥,在通过Client Key Exchange包。发送给服务端。接下来通过自己的私钥和对方的公钥会生成一个点,其对应的X坐标+客户端在第一次握手生成的随机数+服务端在第二次握手生成的随机数一起形成本次协商出来的对称加密的密钥。
之后客户端发送Change Cipher Spec,告诉服务器接下来用密钥加密通信
最后发送之前所有握手数据的摘要,通过 Encrypted Handshake Message;供客户端校验。
第四次握手
服务端发送Change Cipher Spec,告诉客户端接下来用密钥加密通信
最后发送之前所有握手数据的摘要,通过 Encrypted Handshake Message;供客户端校验。
HTTPS怎么优化??
分析性能损耗
TSL握手阶段
对于ECDHE算法来说,握手阶段双方都会临时生成曲线公私钥
客户端要通过从CA下载CRL或者OCSP;目的是为了验证证书是否被吊销
双方会计算pre-master;也就是对称加密密钥
对称密钥数据加密阶段
现在常用的对称加密算法AES,CHACHA20;都是比较好的加密算法。而且一些厂商也对这些算法进行了硬件升级。所以这部分的开销非常小
硬件优化
HTTPS协议属于计算密集型;而不是IO密集型。所以要买好一点的CPU;最好买支持AES-IN的CPU
软件优化
可以考虑升级操作系统内核
协议优化
密钥协商算法优化
相比较RSA密钥协商算法来说;ECDHE握手在第三次握手就可以进行数据加密发送。比RSA少了1RTT。同时更安全。对于已经使用了ECDHE算法的来说,椭圆曲线尽量选择 x25519;要是对后面对称加密算法安全没有太高的要求的话;可以选择AES-128-GCM,相比较256密钥的AES算法来说,更快。因为密钥长度更短。
TLS版本优化
如果可以的话,可以用TSL1.3来代替TSL1.2.因为TSL1.3只需要1RTT就可以完成握手。比TSL1.2握手少去了很多时间。
TLS1.3通过在第一次握手的时候;生成一个随机数,并且带上自己支持的所有椭圆曲线的公钥;发送给客户端。 然后服务端就可以生成随机数作为自己的私钥,并且计算出自己的公钥和接下来对称加密的密钥。然后将自己的公钥发送给客户端。1RTT就完成了TLS握手。
证书优化
证书传输优化
为了优化证书传输优化,那么应该选用ECDHE证书,而不是RSA证书。相同安全程度下,ECDHE算法的证书比RSA证书小很多,占用带宽资源较少。
证书验证优化
客户端拿到服务器的数字证书,会走证书的三层证书链,这种验证证书是否可信任会造成网络开销。同时客户端为了能够知道服务器的证书是否被吊销;还需要不定期的访问CA;从CA下载CRL和OCSP等数据,访问属于HTTP访问,需要建立TCP链接等,造成很大的网络开销。
CRL 证书吊销列表(Certificate Revocation List);这个表由CA定期更新;表上都是被撤销信任的证书。客户端需要定期访问CA下载CRL;然后遍历整个CRL查询服务端证书是否被吊销。 但存在两个问题
问题一:具有很差的时效性。加入我们访问的服务端证书刚刚被吊销,但是客户端还没来得及下载CRL,所以客户端还是会信任这个证书。
问题二: 随着被吊销的证书越来越多;CRL的内容越来越大,每次客户端下载CRL就会造成更高的网络开销。
OCSP 在线证书状态协议(Online Certificate Status Protocol) ,原理是向CA发送证书请求;CA响应证书的有效状态。不必像CRL一样下载遍历整个表;
问题: 虽然不需要下载整个CRL来遍历寻求证书的有效状态;但是毕竟是网络请求,如果网络阻塞,那么还是会拖缓HTTPS的连接。
OCSP Stapling 为了解决存在的网络开销;OCSP Stapling中,服务器周期性的向CA查询证书状态;获得一个时间戳和签名的响应结果并缓存他。当服务器进行TSL第二次握手的时候;将服务器缓存的证书缓存结果发送给客户端,因为有签名的存在所以服务端无法更改。这样就不需要客户端自己去花费网络开销去像CA请求证书状态信息了。
会话复用
Session ID
在双方第一次通信结束后,将第一次协商的对称秘钥缓存起来,然后用一个唯一的Session ID标识;当再需要HTTPS通信时,客户端带上Session ID;服务器在内存中找,如果找到了;只需要一个消息往返就可以重新会话复用,不需要后续的握手操作了。这样就减少了握手开销。当然为了安全起见,Session ID也会过期。
问题一: 随着客户端的增多,缓存的Session ID就会越来越多;服务器的内存压力也会越来越大。
问题二: 现在的服务端一般都是由很多服务器负载均衡提供服务;但不是每个服务器内存中都有Session ID表;所以如果请求的服务器在内存中找不到Session ID的话,还是需要进行握手才能建立加密通信。
Session Ticket
为了解决Session ID中存在的问题;提出Session Ticket技术。其中第一次TLS握手协商的秘钥不是双方缓存;而是交给客户端单独缓存;并且在第一次握手后将秘钥加密成Ticket后发给客户端。下次客户端需要进行HTTPS通信时,只需要带上 Ticket;双方就可以会话复用。 而对于集群服务器的话;则需要保证每个服务器加密秘钥相同。
Pre-shared Key
前面两种会话复用都需要1RTT才能重新复用会话;但对于TLS1.3来说,Pre-shared Key 方式和Session Ticket原理差不多类似;但只需要0RTT就可以会话复用。客户端会把Ticket和HTTP请求一起发送给客户端;然后客户端就会响应由秘钥加密的数据。 当然;这种方式也无法避免重放攻击。
HTTPS优化总结
HTTP 2.0
HTTP1.1的性能问题分析
延迟难以下降
现在网络带宽相比以前大多了;但是延迟下降到一定程度就达到了延迟下降的下限了。
并发连接有限
⾕歌浏览器最⼤并发连接数是 6 个,⽽且每⼀个连接都要经过 TCP 和 TLS 握⼿耗时,以及 TCP 慢启动过程给流ᰁ带来的影响;
队头阻塞
同⼀连接只能在完成⼀个 HTTP 事务(请求和响应)后,才能处理下⼀个事务;
HTTP头部巨大且重复
由于 HTTP 协议是⽆状态的,每⼀个请求都得携带 HTTP 头部,特别是对于有携带 cookie 的头部,⽽ cookie 的⼤⼩通常很⼤;
服务器无法主动推送
因此当客户端需要获取通知时,只能通过定时器不断地拉取消息,这⽆疑浪费⼤ᰁ 了带宽和服务器资源。
兼容HTTP1.1
第一点: HTTP/2 没有在 URI ⾥引⼊新的协议名,仍然⽤「http://」表示明⽂协议,⽤「https://」表示加密协议,于是只需要浏览器和服务器在背后⾃动升级协议,这样可以让⽤户意识不到协议的升级,很好的实现了协议的平滑 升级。
第二点: 只在应⽤层做了改变,还是基于 TCP 协议传输,应⽤层⽅⾯为了保持功能上的兼容,HTTP/2 把 HTTP 分解成了「语义」和「语法」两个部分,「语义」层不做改动,与 HTTP/1.1 完全⼀致,⽐如请求⽅法、状态码、头字段等规则保留不变
头部压缩HPACK算法,客户端和服务器双方共同建立和维护同一个字典;用较小的索引号代表重复的字符串;再用Huffman编码压缩数据
静态表
静态表一共61个条目;用不同的索引号来作为Key;Value表示HTTP2.0头部高频字段的内容;是写进HTTP2.0框架里的,是不会变化的。
有些条目没有固定的Header Value是因为这些值都是可以变化的。但需要经过Huffman编码完成后才能发出。举个例子:
动态表
动态表是静态表中不包含的字段范围;如果这个字段不在静态表中,先经过Huffman编码后,Index从62开始,双方就要共同建立并且维护一个新的索引表条目;下一次发送HTTP数据时,就可以不用发送重复冗余的头字段,直接可以发送一个动态表索引号就可以。
动态表生效的条件: 在同一个连接中,重复完全相同的HTTP头部,如果只发送了一次相同字段或者每次字段值都有稍微的变化;就不能充分使用动态表。
设置类似http2_max_requests来限制一个TCP连接里HTTP请求最大的数量;因为随着双方发送的消息越来越多,双方积累的字典也就会越来越大。虽然这样每次只需要发送一个字节的索引号就可以代替重复冗余的字段,大大节约了带宽。但是服务器连接越来越多,字典越来越大就会造成很高的内存压力,会降低服务器性能。所以需要设立连接中请求的上限值;请求数量达到上限,就断开这个连接释放内存。
Huffman编码
二进制帧
相比较文本数据的优点
相比较HTTP1.1的文本格式数据来说,HTTP2.0的二进制极大地提高了传输效率,而且可以更高效的位运算解析
二进制帧格式
HTTP/2 把响应报⽂划分成了两个帧(Frame), HEADERS(⾸部)和 DATA(消息负载) 是帧的类型,也就是说⼀条 HTTP 响应,划分成了两个帧来传输,并且采⽤⼆进制来编码。
帧长度:三个字节表示整个帧的长度大小
HTTP2.0总共分了10中帧类型;大致分为数据帧和控制帧
标志位: 用于携带简单的控制消息; 比如END_HEADERS 表示头数据结束标志,相当于 HTTP/1 ⾥头后的空⾏(“\r\n”); END_STREAM 表示单⽅向数据发送结束,后续不会再有数据帧。 PRIORITY 表示流的优先级;
流表示符:是用来标识在一个TCP连接中帧属于哪一个流的。最高位R保留不用;最多可以标识2^31个流。接收方可以在乱序的帧中根据这个消息找到相同Stream ID的帧,从而有序的组装信息。
并发传输
我们知道在HTTP1.1基于请求响应模型的;可以发送多个请求,但接收方必须按顺序应答。但是在HTTP2.0中;多个流可以同时复用一个TCP连接;一个流表示了一个请求或者响应的全部数据。从而实现并发传输多个请求。
并且在一个TCP连接中,不同流可以并发乱序的帧,但是在一个流中;必须严格遵循序列号递增的顺序,且一个流中不同的帧中Stream ID都相同;用来表示他们属于同一个流。
在一个TCP连接中每个流的Stream ID逐渐递增,不能相同。而且客户端的Stream ID只能为奇数,服务器的Stream ID只能为偶数。而且当流数量到达上限时,发送一个GOAWAY,来断开TCP连接。
客户端可以在帧标志位这里流的优先级。⽐如客户端访问 HTML/CSS 和图⽚资源时,希望服务器先传递 HTML/CSS,再传图⽚,那么就可以通过设置 Stream 的优先级来 实现,以此提⾼⽤户体验。
服务器主动推送
客户端发起的请求,必须使⽤的是奇数号 Stream,服务器主动的推送,使⽤的是偶数号 Stream。服务器在推送资源时,会通过 PUSH_PROMISE 帧传输 HTTP 头部,并通过帧中的 Promised Stream ID 字段告知客户端,接下来会在哪个偶数号 Stream 中发送包体。
HTTP2.0总结
HTTP 3.0
HTTP 2.0的缺点
HTTP2.0的 队头阻塞
虽然HTTP2.0通过流解决了顺序响应阻塞造成的队头阻塞;但是毕竟还是基于TCP协议的。如果在传输时因为网络或者各种原因造成了丢包或者接收方响应超时;会触发TCP超时重传机制。后序列号的帧就算被接收方接收了,应用层也无法从内核读取到数据。
TLS握手时延
在HTTP2.0中,C/S需要TCP三次握手和TLS四次握手,共花费3RTT才能进行数据加密通信。另外, TCP 由于具有「拥塞控制」的特性,所以刚建⽴连接的 TCP 会有个「慢启动」的过程,它会对 TCP 连接产⽣"减速"效果。 这里TCP第三次握手就可以携带TLS第一次握手的数据。
网络迁移需要重新连接
⼀个 TCP 连接是由四元组(源 IP 地址,源端⼝,⽬标 IP 地址,⽬标端⼝)确定的,这意味着如果 IP 地址或者端⼝变动了,就会导致需要 TCP 与 TLS ᯿新握⼿,这不利于移动设备切换⽹络的场景,⽐如 4G ⽹络环境切换成WIFI。
QUIC协议的特点
HTTP2.0的问题都是因为TCP本身存在的问题;所以无法避免。所以HTTP3.0将传输层替换成了UDP;我们都知道UDP是简单的无连接的不可靠的传输协议。HTTP/3 不仅仅只是简单将传输协议替换成了 UDP,还基于 UDP 协议在「应⽤层」实现了 QUIC 协议,它具有类似 TCP 的连接管理、拥塞窗⼝、流ᰁ控制的⽹络特性,相当于将不可靠传输的 UDP 协议变成“可靠”的了
QUIC协议的优点
无队头阻塞
UDP没有超时重传的机制,也不关心数据包的丢失。如果在一个QUIC协议连接里,一个流的帧丢失或被阻塞了。在这个流中序列号比丢失大的帧即使到达接收方,接收方也无法从内核中读取。但其他流不受影响,流之间相互独立
1RTT时延的快速握手连接
客户端在第一次QUIC协议握手的时候就会生成一个随机数私钥保存下来,然后将支持的所有密码套件公钥计算出来一起发送给服务端。1RTT时延的握手,也是为了同步双方的连接ID;网络迁移重新建立连接也是基于连接ID来实现的。但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,⽽是QUIC 内部包含了 TLS,它在⾃⼰的帧会携带 TLS ⾥的“记录”,再加上 QUIC 使⽤的是 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建⽴连接与密钥协商,甚⾄在第⼆次连接的时候,应⽤数据包可以和 QUIC 握⼿信息(连接信息 + TLS 信息)⼀起发送,达到 0-RTT 的效果。
网络迁移不需要重新建立连接
QUIC 协议没有⽤四元组的⽅式来“绑定”连接,⽽是通过连接 ID来标记通信的两个端点,客户端和服务器可以各⾃选择⼀组 ID 来标记⾃⼰,因此即使移动设备的⽹络变化后,导致 IP 地址变化了,只要仍保有上下⽂信息(⽐如连接 ID、TLS 密钥等),就可以“⽆缝”地复⽤原连接,消除᯿连的成本,没有丝毫卡顿感,达到了连接迁移的功能。
HTTP3.0 帧格式
HTTP/3 同 HTTP/2 ⼀样采⽤⼆进制帧的结构,不同的地⽅在于 HTTP/2 的⼆进制帧⾥需要定义 Stream,⽽HTTP/3 ⾃身不需要再定义 Stream,直接使⽤ QUIC ⾥的 Stream,于是 HTTP/3 的帧的结构也变简单了。
QPACK头压缩算法
91项的静态表
动态表:由于动态表是在⾸次请求-响应后,双⽅会将未包含在静态表中的 Header 项更新各⾃的动态表,接着后续传输时仅⽤ 1 个数字表示,然后对⽅可以根据这 1 个数字从动态表查到对应的数据,就不必每次都传输⻓⻓的数据,⼤⼤ 提升了编码效率。 所以动态表是具有时序性的,如果⾸次出现的请求发⽣了丢包,后续的收到请求,对⽅就⽆法解码出HPACK 头部,因为对⽅还没建⽴好动态表,因此后续的请求解码会阻塞到⾸次请求中丢失的数据包重传过来。
HTTP3.0的解决方案:QUIC 会有两个特殊的单向流,所谓的单项流只有⼀端可以发送消息,双向则指两端都可以发送消息,传输 HTTP消息时⽤的是双向流,这两个单向流的⽤法: ⼀个叫 QPACK Encoder Stream, ⽤于将⼀个字典(key-value)传递给对⽅,⽐如⾯对不属于静态表的HTTP 请求头部,客户端可以通过这个 Stream 发送字典; ⼀个叫 QPACK Decoder Stream,⽤于响应对⽅,告诉它刚发的字典已经更新到⾃⼰的本地动态表了,后续就可以使⽤这个字典来编码了。 这两个特殊的单向流是⽤来同步双⽅的动态表,编码⽅收到解码⽅更新确认的通知后,才使⽤动态表编码 HTTP 头部。
Huffman编码与HTTP2.0中的编码方式差不多
HTTP3.0总结:
特性
http状态码
1xx
是协议处理的中间状态,还有后续操作
2xx
200
最常见的成功状态码,表示一切正常;如果是非head请求,服务器返回的响应头都会有body数据
204
于200相同,也是常见的成功状态码,但响应头没有body数据
206
是应用于HTTP分块下载或者断点续传,不过表示服务器响应的body数据并不是全部,二十总体资源的一部分,不过也是处理成功的状态码
3xx
300
从定向,表示需要客户端用新的url发送请求
301
表示永久重定向,说明用原来的url请求的资源已经不存在,需要用新的url来访问
302
表示临时重定向,表示请求的资源还在,需要暂时新的url来访问
303
304
不具有跳转意义,表示资源未修改,重定向已经缓存的文件,也称缓存重定向,用于缓存控制
307
类似302的临时重定向;但请求方法不得改变
308
类似301的永久重定向;但请求方法不得改变
4xx
400
表示笼统的客户端请求报文发生错误
403
表示服务端禁止客户端请求资源
404
表示客户端请求的资源不存在或未找到
5xx
500
表示笼统的服务端出错
501
表示客户端请求的资源或功能暂不支持
502
表示服务器做为网关或者代理服务器返回的错误码,表示自身工作正常,访问后端服务器是发生了错误
503
表示服务端当前很忙,暂时无法响应
HTTP头字段
HOST
www.A.com
Content-Length
服务器在响应数据是会有这个字段表示本次回应的数据长度
Connection
最常用于客户端请求服务端使用TCP持久连接,方便其他请求复用;但为了兼容老版本的HTTP,需要指定字段值为Keep-Alive
Content-Type
表示服务器告诉客户端返回的什么格式的数据
Content-Encoding
表示服务器告诉客户端本次数据的压缩格式是什么
请求方法
GET:从服务器请求资源
POST:与之相反,向指定的url提交资源
安全和幂等
安全:请求操作不会影响服务器资源
幂等:多次相同操作的结果相同
优点
简单
HTTP报文格式是Header+Body格式,头部信息也是Key+Value这种简单的格式
灵活和易于扩展
HTTP协议中URL,请求方法,状态码和头字段都没有被固定死,可以自定义和扩充;同时HTTP工作在第七层,下层可以随意变化
应用广泛和跨平台
缺点
无状态
cookie技术:通过在请求和响应报文中写入cookie信息来控制客户端状态,客户端在下一次请求中就可以在请求报文中附加cookie,服务端回应报文
明文传输
易于抓包分析,但没有加密保证,毫无安全可言
定义
超文本传输协议
在计算机世界里专门在两点之间传输文字,图片,音频等超文本数据的规范和约定
主题
重放攻击
Session ID还是Session Ticket来说;都不支持前向加密;那什么是重放攻击呢?重放攻击相当于黑客作为中间人,在客户端和服务器通信时,截获客户端的密码或者哈希值;然后想向服务器发起请求,然后被要求身份验证时,黑客将从双方通信最后一次获取到的密码或者哈希值,发送给服务端从而被授予权限。
避免重放攻击的方式就是给会话秘钥做一个合理的过期时间