最近我一直在研究WebSockets,我觉得它们非常酷。然而,如果我看一下这里,有些事情对我来说是不清楚的。
请求:GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
反应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
请求者指定主机,因此中间服务器将知道请求应该到达哪里。请求者发送一个编码为base64的随机字符串,服务器发送回一个加盐的sha1加密密钥。当连接还存在时,这个密钥会在两者之间使用吗?如果是这样,是否有一种方法可以重用这个密钥,即使连接被打破?
正如维基百科链接中提到的:
除了升级报头,客户端发送一个包含base64编码的随机字节的Sec-WebSocket-Key报头,服务器在Sec-WebSocket-Accept报头中回复一个密钥的哈希值。这是为了防止缓存代理重新发送以前的WebSocket会话,并且不提供任何身份验证,隐私或完整性。
Sec-WebSocket-Key
仅在握手中使用,不用于实际通信。
通过发送随机密钥来防止代理缓存请求。如果代理仍然返回缓存的响应,可以通过验证Sec-WebSocket-Accept
头来检查。
客户端可以忽略Sec-WebSocket-Accept
报头(并希望响应没有缓存),WebSocket协议仍然可以正常工作。
在这种情况下,服务器可以实现忽略Sec-WebSocket-Key
报头而不返回Sec-WebSocket-Accept
报头。
如何为响应或验证生成Sec-WebSocket-Accept
头可以在这个答案中阅读:
生成"Sec-WebSocket-Accept"从"Sec-WebSocket-Key"
哈希函数附加固定字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11 (a GUID)的值从应用Sec-WebSocket-Key头(不从base64解码)SHA-1哈希函数,并使用base64对结果进行编码。
https://en.wikipedia.org/wiki/WebSocket协议% 20握手
更多信息请访问:https://www.rfc-editor.org/rfc/rfc6455#section-1.3