HTTPS协议的安全性由SSL协议实现,当前使用的TLS协议1.2版本包含了四个核心子协议:握手协议、密钥配置切换协议、应用数据协议及报警协议。
握手协议的作用便是通信双方进行身份确认、协商安全连接各参数(加密算法、密钥等),确保双方身份真实并且协商的算法与密钥能够保证通信安全。
协议交互图:
HTTPS如何保证通信安全,通过握手协议的介绍,我们已经有所了解。
但是,在全面使用HTTPS前,我们还需要考虑一个众所周知的问题——HTTPS性能。
相对HTTP协议来说,HTTPS协议建立数据通道的更加耗时,若直接部署到App中,势必降低数据传递的效率,间接影响用户体验。
随着互联网的快速发展,HTTP1.x协议得到了迅猛发展,但当App一个页面包含了数十个请求时,HTTP1.x协议的局限性便暴露了出来:
HTTP2正是为了解决HTTP1.x暴露出来的问题而诞生的。
说到HTTP2不得不提spdy。
由于HTTP1.x暴露出来的问题,Google设计了全新的名为spdy的新协议。spdy在五层协议栈的TCP层与HTTP层引入了一个新的逻辑层以提高效率。spdy是一个中间层,对TCP层与HTTP层有很好的兼容,不需要修改HTTP层即可改善应用数据传输速度。
spdy通过多路复用技术,使客户端与服务器只需要保持一条链接即可并发多次数据交互,提高了通信效率。
而HTTP2便士基于spdy的思路开发的。
通过流与帧概念的引入,继承了spdy的多路复用,并增加了一些实用特性。
新特性:
HTTP2目前在实际使用中,只用于HTTPS协议场景下,通过握手阶段ClientHello与ServerHello的extension字段协商而来,所以目前HTTP2的使用场景,都是默认安全加密的。
查看了wiki发现:
Netty and OkHttp are the only two implementations supported by Spring.
HTTP2协议的协商是在握手阶段进行的。
协商的方式是通过握手协议extension扩展字段进行扩展,新增Application Layer Protocol Negotiation字段进行协商。
在握手协议的ClientHello阶段,客户端将所支持的协议列表填入Application Layer Protocol Negotiation字段,供服务端进行挑选。
在HTTP2中,同一域名下的请求,可通过同一条TCP链路进行传输,使多个请求不必单独建立链路,节省建立链路的开销。
为了达到这个目的,HTTP2提出了流与帧的概念,流代表请求与响应,而请求与响应具体的数据则包装为帧,对链路中传输的数据通过流ID与帧类型进行区分处理。下图是多路复用的抽象图,每个块代表一帧,而相同颜色的块则代表是同一个流。
归纳下okhttp的多路复用实现思路:
HTTP2为了解决HTTP1.x中头信息过大导致效率低下的问题,提出的解决方案便是压缩头部信息。具体的压缩方式,则引入了HPACK。
HPACK压缩算法是专门为HTTP2头部压缩服务的。为了达到压缩头部信息的目的,HPACK将头部字段缓存为索引,通过索引ID代表头部字段。客户端与服务端维护索引表,通信过程中尽可能采用索引进行通信,收到索引后查询索引表,才能解析出真正的头部信息。
HPACK索引表划分为动态索引表与静态索引表,动态索引表是HTTP2协议通信过程中两端动态维护的索引表,而静态索引表是硬编码进协议中的索引表。
作为分析HPACK压缩头信息的基础,需要先介绍HPACK对索引以及头部字符串的表示方式。
索引
索引以整型数字表示,由于HPACK需要考虑压缩与编解码问题,所以整型数字结构定义下图所示:
联系客服