Chrome中的WebSocket permessage-deflate,无需上下文接管

WebSocket permessage-deflate in Chrome with no context takeover

我在压缩方面遇到这个问题,并且不确定是否是错误。我的WebSocket服务器不支持上下文接管,并且在发送消息但无法接收消息时遇到问题。

浏览器发出这样的请求:

1
2
3
4
5
6
7
8
GET /socket HTTP/1.1
Host: thirdparty.com
Origin: http://example.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame

如果服务器未指定任何有关上下文接管的选项:

1
2
3
4
5
6
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Access-Control-Allow-Origin: http://example.com
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Extensions: permessage-deflate

我可以读写第一条消息,但不能进行后续的读写,因为Chrome希望服务器保留上下文。

因此,我的服务器提供了以下答案:

1
2
3
4
5
6
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Access-Control-Allow-Origin: http://example.com
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Extensions: permessage-deflate; client_no_context_takeover; server_no_context_takeover

现在,我可以毫无问题地接收消息了,但是再次,我只能发送第一条消息,第二条消息失败,并且我在Chrome浏览器中看到一条错误消息,说它无法使框架膨胀。我尝试发送两个相同的字符串,我可以看到服务器如何发送两次相同的数据,但是客户端第二次无法对其进行解压缩。

因此,似乎Chrome接受client_no_context_takeover参数,该参数指定客户端在压缩时不会对所有邮件使用相同的压缩上下文,而忽略server_no_context_takeover则表示服务器不会使用相同的上下文。

这是Chrome中的错误吗?我不清楚我是否可以发回客户未提供/请求的选项。

我可以使用其他任何选项来禁用客户端上下文接管吗?

更新:

在Chromium源代码的WebSocketPerMessageDeflate.cpp中,我可以看到:

1
2
3
4
5
6
7
8
if (clientNoContextTakeover != parameters.end()) {
    if (!clientNoContextTakeover->value.isNull()) {
        m_failureReason ="Received invalid client_no_context_takeover parameter";
        return false;
    }
    mode = WebSocketDeflater::DoNotTakeOverContext;
    ++numProcessedParameters;
}

但是也:

1
2
3
4
5
6
7
if (serverNoContextTakeover != parameters.end()) {
    if (!serverNoContextTakeover->value.isNull()) {
        m_failureReason ="Received invalid server_no_context_takeover parameter";
        return false;
    }
    ++numProcessedParameters;
}

在第一个代码段中,它设置了" mode"变量,但是在第二个代码中什么都不做,因此似乎基本上是在忽略该参数。

干杯。


仅当客户端请求"无上下文接管"时,服务器才必须在响应中发送server_no_context_takeover参数。从本质上讲,服务器确认客户端的请求。

如果服务器决定自行发送"无上下文接管"(没有客户端请求),那就很好。在这种情况下,服务器不会发送任何参数。

放气发送者可以始终在其自身的下降压缩上下文中和/或减小压缩窗口的大小。无需告诉接收者。放气线格式具有足够的信息供接收器处理。

这是Crossbar.io的配置和握手外观。


我终于找到了问题。

http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-17#section-8.2.3

8.2.3.4. Using a DEFLATE Block with BFINAL Set to 1

通过草稿中的示例,我发现我的服务器正在发送稍微不同的有效负载。原来问题出在BFINAL上,我需要通过在末尾添加一个0字节来将其设置为0。

现在可以了。