1

协议升级机制

 2 years ago
source link: https://perkins4j2.github.io/posts/254331/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

协议升级机制

发表于

2020-08-31

| 分类于 架构

| 阅读次数: 93

本文字数: 1.4k

|

阅读时长 ≈ 1 分钟

HTTP协议 提供了一种特殊的机制,这一机制允许将一个已建立的连接升级成新的、不相容的协议。这篇指南涵盖了其工作原理和使用场景。

通常来说这一机制总是由客户端发起的 (不过也有例外,比如说可以由服务端发起升级到传输层安全协议(TLS)), 服务端可以选择是否要升级到新协议。借助这一技术,连接可以以常用的协议启动(如HTTP/1.1),随后再升级到HTTP2甚至是WebSockets.

注意:HTTP/2 明确禁止使用此机制,这个机制只属于HTTP/1.1

协议升级请求总是由客户端发起的;暂时没有服务端请求协议更改的机制。当客户端试图升级到一个新的协议时,可以先发送一个普通的请求(GET,POST等),不过这个请求需要进行特殊配置以包含升级请求。

特别这个请求需要添加两项额外的header:

Connection: Upgrade
设置 Connection 头的值为 “Upgrade” 来指示这是一个升级请求.
Upgrade: protocols
Upgrade 头指定一项或多项协议名,按优先级排序,以逗号分隔。
一个典型的包含升级请求的例子差不多是这样的:

GET /index.html HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: example/1, foo/2

如果服务器决定升级这次连接,就会返回一个 101 Switching Protocols 响应状态码,和一个要切换到的协议的头部字段Upgrade。 如果服务器没有(或者不能)升级这次连接,它会忽略客户端发送的 “Upgrade 头部字段,返回一个常规的响应:例如一个200 OK).

服务在发送 101 状态码之后,就可以使用新的协议,并可以根据需要执行任何其他协议指定的握手。实际上,一旦这次升级完成了,连接就变成了双向管道。并且可以通过新协议完成启动升级的请求。

由HTTP/1.1请求建立的连接可以升级为HTTP/2协议的连接,但是反过来不可以。事实上HTTP/2已经不再支持101状态码了,也不再支持任何连接升级机制。

升级到WebSocket协议的连接

至今为止最经常会需要升级一个HTTP连接的场合就是使用WebSocket。当你用 WebSocket API 以及其他大部分实现WebSockets的库去建立WebSocket连接时,基本上都不用操心升级的过程,因为这些API已经实现了这一步。比如,用如下API打开一个WebSocket连接:

webSocket = new WebSocket("ws://destination.server.ext", "optionalProtocol");

WebSocket() 构造函数已经自动完成了发送初始 HTTP/1.1 请求,处理握手及升级过程。

你也可以用 “wss://“ 地址格式来打开安全的WebSocket连接。

如果想要自己重头实现WebSocket 连接,就必须要处理握手和升级过程。在创建初始HTTP/1.1会话之后你需要发送另一个HTTP标准请求,但在headers中要带上Upgrade and Connection,也就是:

Connection: Upgrade
Upgrade: websocket
------ 本文结束------

本文标题:协议升级机制

文章作者:Perkins

发布时间:2020年08月31日

原始链接:https://perkins4j2.github.io/posts/254331/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK