Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

## 概述

本文为 WebSocket 协议的第九章,本文翻译的主要内容为 WebSocket 安全性相关内容。
本文为 WebSocket 协议的第十章,本文翻译的主要内容为 WebSocket 安全性相关内容。

有兴趣了解该文档之前几章内容的同学可以见:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ frame-unmasked-application-data

掩码值像第5.2节说到的完全包含在帧中的frame-masking-key上。它是用于对定义在同一节中定义的帧负载数据`Payload data`字段中的包含`Extension data`和`Application data`的数据进行添加掩码。

掩码字段是一个由客户端随机选择的32bit的值。当准备掩码帧时,客户端必须从允许的32bit值中须知你咋一个新的掩码值。掩码值必须是不可被预测的;因此,掩码必须来自强大的熵源(entropy),并且给定的掩码不能让服务器或者代理能够很容易的预测到后续帧。掩码的不可预测性对于预防恶意应用作者在网上暴露相关的字节数据至关重要。[RFC 4086][7]讨论了安全敏感的应用需要一个什么样的合适的强大的熵源。
掩码字段是一个由客户端随机选择的32bit的值。当准备掩码帧时,客户端必须从允许的32bit值中选择一个新的掩码值。掩码值必须是不可被预测的;因此,掩码必须来自强大的熵源(entropy),并且给定的掩码不能让服务器或者代理能够很容易的预测到后续帧。掩码的不可预测性对于预防恶意应用作者在网上暴露相关的字节数据至关重要。[RFC 4086][7]讨论了安全敏感的应用需要一个什么样的合适的强大的熵源。

掩码不影响`Payload data`的长度。进行掩码的数据转换为非掩码数据,或者反过来,根据下面的算法即可。这个同样的算法适用于任意操作方向的转换,例如:对数据进行掩码操作和对数据进行反掩码操作所涉及的步骤是相同的。

Expand All @@ -216,11 +216,11 @@ transfromed-octed-i = original-octet-i XOR masking-key-octet-j

### 5.4 消息分片

消息分片的主要目的是允许发送一个未知长度且消息开始发送后不需要缓存的消息。如果消息不能被分片,那么一端必须在缓存整个消息,因此这个消息的长度必须在第一个字节发送前就需要计算出来。如果有消息分片,服务端或者代理可以选择一个合理的缓存长度,当缓存区满了以后,就想网络发送一个片段
消息分片的主要目的是允许发送一个未知长度且消息开始发送后不需要缓存的消息。如果消息不能被分片,那么一端必须在缓存整个消息,因此这个消息的长度必须在第一个字节发送前就需要计算出来。如果有消息分片,服务端或者代理可以选择一个合理的缓存长度,当缓存区满了以后,就向网络发送一个片段

第二个消息分片使用的场景是不适合在一个逻辑通道内传输一个大的消息占满整个输出频道的多路复用场景。多路复用需要能够将消息进行自由的切割成更小的片段来共享输出频道。(注意:多路复用的扩展不在这个文档中讨论)。

除非在扩展中另有规定,否则帧没有语义的含义。如果客户端和服务的没有协商扩展字段,或者服务端和客户端协商了一些扩展字段,并且代理能够完全识别所有的协商扩展字段,在这些扩展字段存在的情况下知道如何进行帧的合并和拆分,代理就可能会合并或者拆分帧。这个的一个含义是指在缺少扩展字段的情况下,发送者和接收者都不能依赖特定的帧边界的存在。
除非在扩展中另有规定,否则帧没有语义的含义。如果客户端和服务端没有协商扩展字段,或者服务端和客户端协商了一些扩展字段,并且代理能够完全识别所有的协商扩展字段,在这些扩展字段存在的情况下知道如何进行帧的合并和拆分,代理就可能会合并或者拆分帧。这个的一个含义是指在缺少扩展字段的情况下,发送者和接收者都不能依赖特定的帧边界的存在。

消息分片相关的规则如下:

Expand Down Expand Up @@ -262,7 +262,7 @@ transfromed-octed-i = original-octet-i XOR masking-key-octet-j

如果终端收到了一个关闭的控制帧并且没有在以前发送一个关闭帧,那么终端必须发送一个关闭帧作为回应。(当发送一个关闭帧作为回应时,终端通常会输出它收到的状态码)响应的关闭帧应该尽快发送。终端可能会推迟发送关闭帧直到当前的消息都已经发送完成(例如:如果大多数分片的消息已经发送了,终端可能会在发送关闭帧之前将剩余的消息片段发送出去)。然而,已经发送关闭帧的终端不能保证会继续处理收到的消息。

在已经发送和收到了关闭帧后,终端认为WebSocket连接以及关闭了,并且必须关闭底层的TCP连接。服务端必须马上关闭底层的TCP连接,客户端应该等待服务端关闭连接,但是也可以在收到关闭帧以后任意时间关闭连接。例如:如果在合理的时间段内没有收到TCP关闭指令。
在已经发送和收到了关闭帧后,终端认为WebSocket连接已经关闭了,并且必须关闭底层的TCP连接。服务端必须马上关闭底层的TCP连接,客户端应该等待服务端关闭连接,但是也可以在收到关闭帧以后任意时间关闭连接。例如:如果在合理的时间段内没有收到TCP关闭指令。

如果客户端和服务端咋同一个时间发送了关闭帧,两个终端都会发送和接收到一条关闭的消息,并且应该认为WebSocket连接已经关闭,同时关闭底层的TCP连接。

Expand All @@ -272,7 +272,7 @@ transfromed-octed-i = original-octet-i XOR masking-key-octet-j

关闭帧可能包含“应用数据”。

如果收到了一个心跳Ping帧,那么终端必须发送一个心跳Pong 帧作为回应,除非已经收到了一个关闭帧。终端应该尽快恢复Pong帧。Pong帧将会在5.5.3节讨论。
如果收到了一个心跳Ping帧,那么终端必须发送一个心跳Pong 帧作为回应,除非已经收到了一个关闭帧。终端应该尽快回复Pong帧。Pong帧将会在5.5.3节讨论。

终端可能会在建立连接后与连接关闭前中间的任意时间发送Ping帧。

Expand All @@ -288,11 +288,11 @@ transfromed-octed-i = original-octet-i XOR masking-key-octet-j

如果终端收到一个Ping帧但是没有发送Pong帧来回应之前的ping帧,那么终端可能选择用Pong帧来回复最近处理的那个Ping帧。

Pong帧可以被主动发送。这会作为一个单项的心跳。预期外的Pong包的响应没有规定。
Pong帧可以被主动发送。这会作为一个单向的心跳。预期外的Pong包的响应没有规定。

### 5.6 数据帧

数据帧(例如非控制帧)的定义是操作码的最高位值为0。当前定义的数据帧操作吗包含0x1(文本)、0x2(二进制)。操作码0x3-0x7是被保留作为非控制帧的操作码。
数据帧(例如非控制帧)的定义是操作码的最高位值为0。当前定义的数据帧操作码包含0x1(文本)、0x2(二进制)。操作码0x3-0x7是被保留作为非控制帧的操作码。

数据帧会携带应用层/扩展层数据。操作码决定了携带的数据解析方式:

Expand Down