@(StuRep)前端
来自百度FEX前端团队
HTTP/1.0只容许在一个链接上创建一个当前未完成的请求。HTTP/1.1管道只部分处理了请求并发和报头阻塞的问题。所以客户端须要发起屡次请求经过数次链接服务器来减小延迟。web
此外,HTTP/1.1的报头字段常常重复和冗长。在产生更多或更大的网络数据包时,可能致使小的初始TCP堵塞窗口被快速填充。这可能在多个请求创建在一个新的TCP链接时致使过分的延迟。算法
本协议经过定义一个优化的基础链接的HTTP语义映射来解决这些问题。 具体地,它容许在同一链接上交错地创建请求和响应消息,并使用高效率编码的HTTP报头字段。 它还容许请求的优先级,让更多的重要的请求更快速的完成,进一步提高了性能。缓存
最终协议设计为对网络更友好,由于它相对HTTP/1.x减小了TCP链接。 这意味着与其余流更少的竞争以及更长时间的链接,从而更有效地利用可用的网络容量。安全
最后,这种封装也经过使用二进制消息帧使信息处理更具扩展性。
_服务器
HTTP/2中基本的协议单位是帧。每一个帧都有不一样的类型和用途。例如,报头(HEADERS)和数据(DATA)帧组成了基本的HTTP 请求和响应;其余帧例如 设置(SETTINGS)、窗口更新(WINDOW_UPDATE)和推送承诺(PUSH_PROMISE)是用来实现HTTP/2的其余功能。网络
HTTP/2添加了一种新的交互模式,即服务器能推送消息给客户端。服务器推送容许服务端预测客户端须要来发送数据给客户端,交换网络使用以阻止潜在的延迟增加。服务器经过复用一个以PUSH_PROMISE帧发送的请求来实现推送,而后服务端能够在一个单独的流里面发送响应给这个合成的请求。并发
帧包含的HTTP报头字段是压缩的。HTTP请求有多是高度冗余的,所以压缩能显著减小请求和响应的大小。
_性能
一个HTTP/2链接是运行在TCP链接上的应用层协议。客户端是TCP链接的发起者。优化
HTTP/2使用与HTTP/1.1相同的"http"和"https" 资源标识符(URI)。使用相同的默认端口:"http" 的80端口及“https”的443端口。所以,实现对例如http://example.org/foo或https://example.com/bar目标资源的URI请求处理须要首先肯定上游服务端(当前客户端但愿创建链接的对等端)是否支持HTTP/2。
这意味着检测“http” 及“https” 的URIs是否支持HTTP/2的方法是不同的。检测"http"URIs在章节3.2中描述。检测"https"URIs 在章节3.3中描述。
客户端没法预知服务端是否支持HTTP/2.0 的状况下使用HTTP升级机制发起“http” URI请求([RFC7230] 章节6.7)。客户端发起一个http1.1请求,其中包含识别HTTP/2的升级报头字段与h2c token。HTTP/1.1必须包含一个确切的HTTP2-Settings中的报头字段。
客户端在不了解服务端是否支持HTTP/2的时候,会使用TSL [TLS12] 于其应用层协议协商扩展 [TLSALPN]。
使用TLS的HTTP/2 使用"h2"程序token。“h2c”token绝对不能由客户端或者选定的服务端发送。
TSL协商一旦完成,客户端和服务端均可以发送链接序言。
在创建TCP链接而且检测到HTTP/2会被各个对等端使用后,每一个端点必须发送一个链接序言最终确认并做为创建HTTP/2链接的初始设置参数。
若是任何一个端点没有以一个有效的链接序言开头,客户端和服务端必须终止TCP链接。若是端点并无使用HTTP/2此时能够省略超时(GOAWAY)帧(章节6.8)。
_
TTP/2链接一旦创建,端点之间能够立刻交换数据帧。
帧报头字段定义是:
HTTP/2报文报头字段是包含一个或多个相关的键值对。他们在HTTP请求响应消息及服务器推送操做(见章节8.2)中使用。
报头集合是0个或多个报头字段的集合。当他经过链接传输的时候,报头集合将使用HTTP报头压缩序列化到报文报头块中。序列化的报头块被分割成一个或多个的字节序列,称为报头分区,并在报头(章节6.2)、推送承诺(章节6.6)及延续帧(章节6.10)的载体中传送。
HTTP报文头压缩并不保留报头字段的相关顺序。具备多个值的报头字段使用特定的分割器被编码分割到一个单独的报头区域(见 章节8.1.2.3 HeaderOrdering),这保留了该报头字段中各类值的对应顺序。
_
流是一个独立的,客户端和服务端在HTTP/2链接下交换帧的双向序列。流有一下几个重要特色:
流由31位字节的无符号整数标识。客户端发起的流必须以奇数标示;服务器发起的流必须使用偶数来标示。0(0x0)用来标识链接控制信息流,且绝对不能用来创建一个新流。
HTTP/1.1升级到HTTP/2的请求将收到一个1(0x1)标识的流的响应。升级完成后,0x1流将对客户端处于“半封闭(本地)”状态。所以,0x1流不能被从HTTP/1.1升级的客户端用来做为一个新的流的标识符。
流标识符不能被重复使用。生存期长的链接可能致使流标识符可用范围耗尽。客户端不能新建流标识符时能够针对新流创建一个新的链接。服务端不能新建流标识符时能够发送一个超时帧(GOAWAY)强制客户端对新的流使用新的链接。
对等端可使用设置帧里面的SETTINGS_MAX_CONCURRENT_STREAMS参数来限制流的并发量。最大并发流设置(章节6.5.2)仅适用于终端而且只对接收到此设置的对等端有效。也就是说:客户端能够指定服务端能启动的流最大并发量,并且服务端能指定客户端能启动的流最大并发量。终端绝对不能超过对等端设置的限制。
终端绝对不能超过对等端设定的设置。终端接收到报头帧致使他们广播的并发流超过限制的必须将这做为流错误(章节5.4.2)处理。终端但愿将SETTINGS_MAX_CONCURRENT_STREAMS的值减小到比当前打开的流更小时能够关闭超过新的设置值的流或者容许流结束。
使用复用流介绍了针对TCP链接的资源争夺致使的流阻塞。流量控制方案等确保同一链接上的流相互之间不会形成破坏性的干扰。流量控制在单个流及整个链接过程当中使用。
HTTP/2 经过使用WINDOW_UPDATE帧类型来提供流量控制(章节6.9)。
HTTP/2流流量控制目标在于容许不须要协议改动的状况下改进流量控制算法。HTTP/2中的流量控制有如下特色:
流量控制的定义是用来保护端点在资源约束条件下的操做。例如,一个代理须要在不少链接之间共享内存,也有可能有缓慢的上游链接和快速的下游链接。流量控制解决的状况是接收端在一个流上处理数据的同时一样想继续处理同个链接上的其余流。
新建流的终端能够在报头帧(章节6.2)中包含优先级信息来对流标记优先级。对于已存在的流,优先级帧(章节6.3)能够用来改变流优先级。
优先级的目的是容许终端表达它如何让对等端管理并发流时分配资源。更重要的是,在发送容量有限时优先级能用来选择流来传输帧。
流的优先级明确设置将输入到优先级处理过程当中。它并不能保证能至关其余相关流有特殊的处理或者传输顺序。终端并不能使用优先级强制要求对等端按照特定顺序处理并发流。所以优先级的表达仅仅是一个建议。
优先级信息能够像它们被建立同样使用报头帧或者使用优先级帧来明确指定或者改变。提供优先级信息是可选的,没有明确指定时使用默认值(章节5.3.5)。
_
错误码是32位字段,用在RST_STREAM和超时帧中用来标识流或者连接错误的缘由。
定义了如下错误码:
_
HTTP/2容许服务端针对客户端一个单独的请求,主动的发送(或推送)一个或者多个相关的响应。这种特定在服务端知道客户端须要这些响应来完整的处理最初的请求的时候特别有用。
_
这段概况了HTTP协议的属性,包括提升互操做性、减小暴露已知的安全漏洞,或者减小执行变更的可能。
HTTP/2链接是永久性的。为了最佳的性能,它期待直到肯定与服务端的进一步沟通再也不必要的时候,客户端才会关闭链接(例如,当用户导航到其余特定的网页),或者直到服务端关闭链接。
_
客户端只有通过权限验证才能获取HTTP/2响应的资源。这在服务器推送中(章节8.2)尤其重要,客户端在接收响应前验证PUSH_PROMISE帧。
HTTP/2依据HTTP/1.1权限定义来检测服务端是否有权限提供给定的响应,见RFC2818 章节3.这依赖于本地“HTTP”URI方案的域名解析,以及服务端提供的“https”方案验证。
客户端绝对不能以任何形式使用服务端提供的客户端没有权限的资源。
在跨协议攻击中,攻击者使客户端在一种协议中向解析另外一种协议的服务器启动一个交易。攻击者可能可以使交易看起来在第二种协议中是合法的。结合对web上下文的利用,这个能够针对保护不力的服务器在秘密网络下进行互动。
HTTP/2报头名称和值编码成带有长度前缀的字节序列。这使得HTTP/2可以携带任何字符串的字节做为报头字段的名称或值。中介端直接转换HTTP/2请求或响应到HTTP/1.1时能够容许HTTP/1.1消息建立的损坏。攻击者能够利用这个行为让中介端建立HTTP/1.1消息时带有非法报头字段、额外报头字段,甚至是彻底伪造的新消息。
推送响应并无一个来自客户端的明确请求;请求是服务端从PUSH_PROMISE帧中提供的。
缓存响应推送多是基于原始服务器的缓存控制报头字段的指导。然而,若是服务端主机包含多个用户可能会致使问题。例如,服务端可能为多个用户每一个提供小部分的URI空间。