http/2 协议刚刚发布不久,http1.1的服务器和客户端依然大量存在,新老协议必定长期共存一段时间。这样,浏览器和服务器就需要协商使用何种协议进行通讯。

主流的方法是使用ALPN或者NPN来做协商。

Next Protocol Negotiation (NPN)是一个使SPDY在TLS服务器上对使用何种应用层协议进行协商的协议。IETF(h2的标准化组织)拿到这个,肯定要改改,然后盖个章,把它变成标准。名字也改了叫ALPN(Application Layer Protocol Negotiation)。

区别是有的。就在于谁持有会话协议的决定权。ALPN是由客户端给服务器发送一个协议清单,由服务器来最终选择一个。而NPN则正好相反。

Node 已经在tls模块内实现了NPN支持。只要创建tls服务器(createServer),在options参数内传递服务器支持的协议清单NPNProtocols,在客户端连接(connect)传递NPNProtocols,这样建立连接后,就可以在socket.npnProtocol内得到协商的结果。

请看mocha测试用例:

describe('tls', function() {it('npn', function() {      var fs = require('fs');var path = require('path');var tls = require('tls');tls.createServer({key: fs.readFileSync("example/localhost.key"),// 私有键cert: fs.readFileSync("example/localhost.crt"),// 证书NPNProtocols: ['h2', 'http 1.1','http 1.0'] // 服务器支持协议清单}, function(socket) {console.log("s1:"+socket.npnProtocol);// 协商结果}).listen(1111);//clientprocess.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";tls.connect({ port: 1111 }, function() {});tls.connect({ port: 1111 ,NPNProtocols: ['h2'] }, function() {     });tls.connect({ port: 1111, NPNProtocols: ['http 1.1'] }, function() {});      tls.connect({ port: 1111, NPNProtocols: ['http 1.0'] }, function() {});})})

输出结果

  my.jsscenariotls√ npn (279ms)
s1:http/1.1
s1:h2
s1:http 1.1
s1:http 1.0

程序员的代码常常气死写文字的人——因为一堆艰涩文字,变成代码常常简单无比。

理论上来说,http/2 可以架构在tls(加密通道)上,也可以架构在tcp(平文本)上。协议文本也确实没有限定或者强制使用tls信道。但是,h2的前身是spdy,而spdy是在tls之上的;spdy的主人家google的浏览器,chrome也只支持tls;另外一家主流浏览器firefox也跟进。这就让架构于tls之上就成为http/2的事实上的标准。所有协商协议也都支持NPN(tls的一个扩展)。

两家浏览器厂商的做法,其实并非强梁,而是基于现实考量:
1. 大量现存的代理、中介软件,都假设80端口上跑的是http1.1,并且基于这个假设,对流经它们的流量做出修改。如果h2继续使用80,很可能和这些修改发生冲突。使用tls(默认为443端口)就避开了这个冲突的可能性
2. 加密化信道(相比http1.x)对用户隐私是更好的保护

通过平文本升级协议到h2,依然可能。采用的是现存的http1.1的升级机制。

GET /page HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: (SETTINGS payload) HTTP/1.1 200 OK
Content-length: 243
Content-type: text/html(... HTTP/1.1 response ...)(or)HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c(... HTTP/2 response ...)

由 Upgrade指定升级目标协议, HTTP2-Settings传递base64后的settings。如果服务器为1.1的,那么返回1.1的响应。否则,就发101 Switching Protocols ,随后升级为h2。

因为这个做法比NPN要做一个网络往返,这个做法(101 Switching Protocols )被很多实现忽略。比如,node-http2就没有实现(请脑补标准机构的脸色:)。在程序员友好,客户友好的柔情面纱下面,遇到核心的性能问题,依然是一片丛林景象。

尽管node-http2代码内,把ALPN的协议协商也有,并且堂而皇之的也和NPN一样:

    options.ALPNProtocols = supportedProtocols;options.NPNProtocols = supportedProtocols;...this._server = https.createServer(options);

但是经过测试,node还没有支持ALPN,有测试用例为证:

describe('tls', function() {it('alpn', function() {      var fs = require('fs');var path = require('path');var tls = require('tls');tls.createServer({key: fs.readFileSync("example/localhost.key"),cert: fs.readFileSync("example/localhost.crt"),ALPNProtocols: ['h2', 'http 1.1','http 1.0']}, function(socket) {console.log("s1:"+socket.npnProtocol);}).listen(1111);//clientprocess.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";tls.connect({ port: 1111 }, function() {          });tls.connect({ port: 1111 ,ALPNProtocols: ['h2'] }, function() {});tls.connect({ port: 1111, ALPNProtocols: ['http 1.1'] }, function() {});      tls.connect({ port: 1111, ALPNProtocols: ['http 1.0'] }, function() {});})})

根本就没有协商,怎么样都是http/1.1 !

  my.jsscenariotls√ alpn (307ms)
s1:http/1.1
s1:http/1.1
s1:http/1.1
s1:http/1.1

关于Node对alpn的支持,文档也没有提及,但是在issue内有提到,它们正在等待openssl实现并且稳定。稳!定!openssl这几年出的糗还少吗,什么时候能弄稳定呢。

http2-协议协商过程相关推荐

  1. VNC协议-认证过程

    0x00 VNC是什么 VNC(Virtual Network Computing),是一种使用RFB协议的屏幕画面分享及远程操作软件.此软件借由网络,可发送键盘与鼠标的动作及即时的屏幕画面. VNC ...

  2. 服务器光口自协商协议,千兆光口自协商过程

    千兆光口自协商 千兆光口可以工作在强制和自协商两种模式.802.3规范中千兆光口只支持1000M速率,支持全双工(Full)和半双工(Half)两种双工模式. 自协商和强制最根本的区别就是两者再建立物 ...

  3. 源码编译更新nginx到最新版本,并开始nginx支持http2协议模块.

    最近因为迁移公司vm上的代码,遇到一些问题.有一台vm配置了https协议,原以为迁移安全证书以后,配置nginx就可以了,但是修改nginx配置文件以后,执行 nginx -t 命令后,报如下错误: ...

  4. 你了解HTTP2协议吗?(一)

    1.写在前面 前面的博客我们介绍完了HTTP1.0/1.1的协议,以及WebSocket协议,但是这些协议由于历史的问题,或多或少都有些历史的问题,所以后面的博客我们介绍HTTP2协议,HTTTP2协 ...

  5. http2协议翻译(转)

    超文本传输协议版本 2 IETF HTTP2草案(draft-ietf-httpbis-http2-13) 摘要 本规范描述了一种优化的超文本传输协议(HTTP).HTTP/2通过引进报头字段压缩以及 ...

  6. 连信的会话加密密钥协商过程

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 介绍连信会话加密密钥的协商过程." 公号内之前已经对协议的框架和协议内的数据格式进行了介绍,有需要可以回顾下: 连信协议整体框架 ...

  7. IPSEC ***两个阶段的协商过程

    IPSEC ×××两个阶段的协商过程 第一阶段 有主模式和积极模式2种 注意!!!只有remote ***和Easy ***是积极模式的,其他都是用主模式来协商的 让IKE对等体彼此验证对方并确定会话 ...

  8. PPPoE协议交互过程

    PPPoE协议交互过程 1.发现阶段(PPPoED:PPPoE Discovery) 1.1 PADI(PPPoE Active Discovery Initiation) 1.2 PADO(PPPo ...

  9. VoLTE技术(含IMS注册/去注册流程、IMS呼叫流程、呼叫保持流程、二次协商过程)

    文章目录 VoLTE技术 IMS简介 SIP消息结构 IMS注册流程 IMS去注册流程 什么是Ghost Call 预留资源的呼叫流程 挂断电话流程(主动挂断.拒接) SDP协议,二次协商过程 呼叫保 ...

  10. 国密浏览器如何完成SM2国密SSL协议协商

    国密浏览器需要遵循国密SSL协议规范GM/T 0024-2014.GM/T 0024-2014没有单独规范 SSL协议的文件,而是在SSL VPN技术规范中定义了国密SSL协议.国密SSL协议(SSL ...

最新文章

  1. java遍历集合list,JAVA基础(List集合遍历)
  2. 一个web左侧菜单例子
  3. Python中通过MyQR生成gif动图二维码
  4. 同步锁ReentrantLock
  5. java代码实现通讯录实例,我不知道这有什么用。,
  6. Opencv将处理后的视频保存出现的问题
  7. laravel composer 安装指定版本以及基本的配置
  8. 第10章 接口、继承与多态----对象类型的转换
  9. xcode6-beta下载
  10. 如何搭建合理的BOM
  11. uni-app使用ucharts地图(主要微信小程序-初步使用)
  12. SQL两张表筛选相同数据和不同数据
  13. 【无标题】猜单词小游戏
  14. window.frames用法
  15. 【心理】执行功能障碍
  16. 如何向码云(Gitee)上传项目
  17. ArcGIS for Js Graphic、GraphicLayer、Geometry、(Point,Line,Polygon)、Rings(Coordinates)之间的关系
  18. 分享100个AE模板,AE片头模板第2期
  19. 澎思科技茹敏:人脸识别的泛安防落地及多维数据实战应用|量子位沙龙回顾
  20. 最近写飞秋程序的一些总结

热门文章

  1. MFC(VS2010)编程实例之一(Edit Control控件)
  2. 基于粒子群优化算法的移动机器人全局路径规划-附代码
  3. python -图例设置
  4. icesat-2数据下载的几种方法
  5. excel 使用定位工具批量删除错误值
  6. 【统计分析】4 空间点数据分析与ArcGIS
  7. word中设置论文中英文参考文献对齐方法
  8. 数据结构与算法笔记-------选择排序
  9. h5红包雨代码_【多管闲事】非专业人士H5学习指北:从门还没入到放弃 | 叙一来闲...
  10. jq js json 转字符串_JSON字符串转换成JSON对象的JS代码