为什么HTTP Upgrade的时候,需要Connection: upgrade
很久之前,在看HTTP头部的时候,发现WebSocket等协议的Upgrade请求,需要同时带上Connection和Upgrade头部。但是,如果是仅仅Upgrade的话,Connection头部不就是多余的设计了么?
比如一个典型的WebSocket升级请求如下:
1 2 3 4 5 6 |
GET /chat HTTP/1.1 Host: example.com:8000 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 |
当时在知乎提了一个问题,结果到现在没有满意了回答,只能自己来回答了。
Connection的起源
最开始,在HTTP/1.0出现没多久,人们就意识到HTTP持久连接的重要性(毕竟三次握手还是很慢的),所以各个服务器实现都采用了Keep-Alive头部来表示这个请求支持连接持久化。
HTTP/1.1中的Connection
在HTTP/1.1中,正式标准化了Connection头部:
Connection头部一般表示那些头部是属于逐跳头部的,比如Connection: Custom-Header,就表示在这个连接中,Custom-Header是一个逐跳头部,不应当被代理原样传递给upstream。
有两个例外:close表示会话不持久化,keep-alive表示会话支持持久化(虽然有一个Keep-Alive头部,但是大小写不一样)。
上面,我们提到了逐跳头部:
逐跳头部(hop-by-hop header),用来描述当前浏览器与直连服务器(比如Nginx反向代理)的连接信息。比如Keep-Alive头部,仅仅表示浏览器尝试和Nginx之间连接持久化,而不管Nginx和后端服务器之间的连接。proxy要处理这些头部,并按照自己的需要来修改这些头部。默认的逐条头部如下:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailers
- Transfer-Encoding
- Upgrade
其他的头部都是端到端头部(end-to-end header),用来描述这个浏览器和最终处理请求的服务器之间的信息,比如Accept头部,表示客户端想从后端服务器得到的数据类型,而和中间的Nginx无关。proxy不能修改这些头部。
再回到HTTP 1.1的Connection头部,这儿有一个兼容性问题:我们以Upgrade头部为例,某个proxy实现了HTTP 1.0协议,将Upgrade原样转发给后端,后端和proxy升级协议,但是这个情况下,proxy不认识升级后的协议啊。
所以,RFC有增加了一条规定:
如果只有Upgrade: xxx
,而没有Connection: Upgrade
,那么就当作普通请求来处理。
Connection头部的扩展
然后很多地方就开始使用了,比如开始提到的WebSocket的Upgrade请求:
1 2 3 4 5 6 |
GET /chat HTTP/1.1 Host: example.com:8000 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 |
结论
Connection
头部和Upgrade
头部有不同的语义和使用场景:
Connection: Upgrade
表示Upgrade是一个hop-by-hop的字段。这个头部是给proxy看的Upgrade: websocket
表示浏览器想要升级到WebSocket协议。这个头部是给最终处理请求的程序看的。- 如果只有
Upgrade: websocket
,说明proxy不支持WebSocket升级,按照标准应该视为普通HTTP请求。
参考资料:
- HTTP/1.0就有了Keep-Alive头部(非标准化字段)
- rfc7230
- HTTP协议的Connection头 | 人过不留名 雁过不留声
为什么HTTP Upgrade的时候,需要Connection: upgrade相关推荐
- upgrade yum 指定版本_yum upgrade和yum update的区别
Linux升级命令有两个分别是yum upgrade和yum update, 这个两个命令是有区别的: yum -y update 升级所有包同时也升级软件.系统版本和系统内核 yum -y upgr ...
- python---websocket的使用
一:简介 推文:WebSocket 是什么原理?为什么可以实现持久连接? 推文:WebSocket:5分钟从入门到精通(很好) WebSocket协议是基于TCP的一种新的协议.WebSocket最初 ...
- 接收服务器显示帧控制错误,Websocket连接关闭,出现错误“接收到意外的继续帧”...
我只是想用WebSockets.我用python编写服务器代码.服务器运行良好,但当尝试使用浏览器连接到套接字时,我得到了错误"WebSocket connection to 'ws://l ...
- Python3 websocket通信
一. 客户端服务端进行握手 1.客户端向服务端发送握手包 GET ws://localhost:8000/ HTTP/1.1 Host: localhost:8000 Connection: Upgr ...
- 网上测试了很多关于PYTHON的WEBSOCKET样例,下面这个才成功了
这是最底层的, 嘿嘿,我 还是习惯搞个框架来实现急需要的功能... 这个东东玩得很有意思的.. 服务器端的代码: import simplejson import socket import sys ...
- VB6+Winsock编写的websocket服务端
2017/07/08 - 最新的封装模块在:http://www.cnblogs.com/xiii/p/7135233.html,这篇可以忽略了 早就写好了,看这方面资料比较少,索性贴出来.只是一个D ...
- python websocket例程_python 实现websocket
#!/usr/bin python#-*- coding:UTF-8 -*- importredisimporttime, threading, sched, json, socket, base64 ...
- javascript python 通信_Python通过websocket与js客户端通信示例分析
具体的 websocket 介绍可见 http://zh.wikipedia.org/wiki/WebSocket 这里,介绍如何使用 Python 与前端 js 进行通信. websocket 使用 ...
- http协议基础(七)通用首部字段
通用首部字段的意思,就是:请求和响应报文双方都会使用的首部 1.Cache-Control 通过指定它的指令,能操作缓存的工作机制 指令参数是可选的,多个指令通过","分隔 Cac ...
最新文章
- 花最少的钱,训超6的机器人:谷歌大脑推出机器人强化学习平台,硬件代码全开源...
- Java虚拟机中的栈和堆
- linux挂载分区至目录
- @Transactional 注解的失效场景
- hibernate工厂模式_Hibernate锁定模式–乐观锁定模式如何工作
- 免装版_无缝贴图制作软件 PixPlant2中文免装版
- C++学习—— mutable和 extern
- 地图定位的坐标和mapview中显示的当前位置信息不一致
- C++程序设计:原理与实践(进阶篇)15.4 链表
- java框架实例---自定义标签实例
- [导入]用户控件包装器
- NGN学习笔记6——NGN的业务提供技术
- Betwin实现电脑一分为二
- linux node安装菜鸟教程,手把手告诉你如何安装多个版本的node
- vfp python_Python dbfpy和FoxPro
- 齐聚一堂:共话网络安全人才培养新模式
- 免费Web 托管公司遭黑客攻击 1350万用户数据泄露
- 从头构建自己的Linux系统
- 笔记怎么放思维导图图片
- 华硕笔记本安装linux失败