82 views

HTTP/2标准的发展 6 – HTTP/2标准现状

image

HTTP/2第一个draft从SPDY直接拷贝,到现在两三年了,修改到版本16。对Google来说,算是乌龟爬行,实现SPDY也就用了两年。对于IETF是进展神速。现在的HTTP/2和SPDY还有不少细节差距,各自独立发展,最终会汇合一处。

1.协议进展

有了前面的基础,不用完全再过一遍8,90页的HTTP/2文档了,只需要关注协议附录的版本“Change Log”。协议尚未定稿,还会变动,这里内容基于当前的版本16。

1.1HTTP/2版本识别

第一个draft起,HTTP/2就增加了协议识别(HTTP/2 Version Identification)章节。使Client和Server在后向兼容前提下发现并使用HTTP/2。

1.1.1 明文方式

利用HTTP1.1的upgrade header机制,并为该header定义了常量“h2c”-代表明文HTTP/2。下面是交互例子:

Client如果希望使用明文HTTP/2发送:

 

 

Server如果支持HTTP/2则回应:

 

 

1.1.2 SSL/TLS方式

最初SPDY强制使用SSL/tTLS方式,基于TLS NPN扩展。后NPN扩展被废弃,替换为ALPN扩展。上图是我们前面章节nodejs例子中抓到的TLS NPN扩展报文:

image

TNP扩展协商步骤是:

1.Client在Client Hello之中发起NPN扩展协商。

2.Server通过Server Hello中的NPN扩展返回支持的协议列表。

3.Client在加密的Change Cipher Spec Message里面,选中SPDY/3。

这和常规的TLS扩展多都在Client Hello和Server Hello明文阶段协商不同,引起了争议。

 

ALPN照搬NPN概念,区别是在

1.Client在Client Hello加入支持的协议类型列表

2.Server在明文的Server Hello之中选定协议类型。

只需两步交互。也有人也提出来,协商都在明文阶段,会给防火墙等中间设备干预应用协商的机会。但最终两次交互胜过三次,google又加快了连接速度,节省了几个bit的电力消耗。NPN出局。

ALPN扩展中新定义了“h2”代表HTTPS下的HTTP/2协议,以后会逐渐淘汰spdy3,spdy3.1等非标准协议。

 

1.2 Stream信令改动

第一个draft就干掉了SPDY的两个很显眼的信令:

SYN_STREAM

SYN_REPLY

基于底层TCP的可靠连接,这两个信令设计的确实冗余。Stream ID增加就可以表示新Stream。

 

1.3 Push的增强

前文提到SPDY Server Push有Race Condition问题。HTTP/2对这个问题做了处理,引入了PUSH_PROMISE。

即在Server Push之前,首先发送PUSH_PROMISE这个Frame,其中包括HTTP request的header 部分(回忆一下SPDY的Associated-Stream-ID)。

Client明确接受Push之后,数据传输才开始进行。

这种机制使得Server Push对应用工程师透明,编码时也不需额外注意避免Race Condition了。

 

1.4 Stream Dependencies

这个是基于SPDY简单的用Number表示Stream Priority的“过度”升级版,用于资源分配。stream dependency使得不同stream形成树形依赖关系,依赖关系用于为Server资源分配时做参考。

可能的资源分配算法例子是:

A是父亲,B, C是孩子。Server对于这棵树分配一定资源,如果A不能操作,则B,C会各自分享这棵树的资源各半。

对于stream dependency tree提供了两种插入操作:

1.成为指定Stream的孩子

2.成为指定Stream的父亲

image

上图是Draft中一个dependency tree的插入操作例子,原本好好一棵树,D是A的孙子,现在D要成为A的父亲,于是变换为另一棵树。

不知道引入这类对象关系到底有多大实际价值,个人觉得,太复杂了。实际部署中,如果浏览器运行起来,加载应用磕磕绊绊时,调试困难。

1.5 提供更多实现指导

协议还提供了一些实现指导,例如下面的Stream生命周期状态机,可以直接映射为代码。

image

send:   endpoint sends this frame
recv:   endpoint receives this frame

H:  HEADERS frame (with implied CONTINUATIONs)
PP: PUSH_PROMISE frame (with implied CONTINUATIONs)
ES: END_STREAM flag
R:  RST_STREAM frame

 

1.5 考虑更多的部署

1.5.1 引入CONNET方法

通过HTTP/2 tunnel发送HTTP/1X的请求,适用于有中间的HTTP/2 proxy,可以和旧的HTTP server互联的情况。

1.5.2 TLS 1.2 Features部署考量

相对于SPDY的一个重要变化是HTTP/2强制使用最新的TLS1.2及以上版本。SSL以及早期TLS版本中的设计漏洞和已有攻击都可以不用考虑了。

1.HTTP/2 over TLS 1.2 MUST disable compression

2.HTTP/2 over TLS 1.2 MUST disable renegotiation.

等建议

 

1.6 考虑更多的安全

参照下一篇日志。

 

2.反面声音

 

看完协议,整体感觉复杂。如果Google “HTTP2 too complex”关键字,会得到不少和我的感受类似的声音。这里就有讨论用HTTP over SCTP解决HTTP并发这个最主要问题的建议。咨询了一些同事,还是可以工作的。

SPDY本就复杂,二进制协议承载文本,中间网关从零实现费时费力。HTTP/2又改动良多,和SPDY差别不少,路漫漫其修远。

另外,我们网络工程师再也不能用Telnet或netcat拷贝粘贴,简单构造HTTP请求报文以及肉眼观测报文内容了。

 

【参考】

1.ALPN(Application-Layer Protocol Negotiation) – http://tools.ietf.org/html/rfc7301

2.NPN(Next Protocol Negotiation Extension) – http://tools.ietf.org/id/draft-agl-tls-nextprotoneg-03.html

3.NPN and ALPN – https://www.imperialviolet.org/2013/03/20/alpn.html

4.HTTP2 – http://tools.ietf.org/html/draft-ietf-httpbis-http2-16

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">