【问题标题】:Websocket handshake Sec-WebSocket-Accept header value is incorrectWebsocket 握手 Sec-WebSocket-Accept 标头值不正确
【发布时间】:2016-04-19 02:44:05
【问题描述】:

我正在编写一个 c++ websocket 服务器,chrome 上的开发工具说 sec-websocket-accept 标头值不正确。我已经测试了几天,一切似乎都很好。客户端在没有调用 websocket onopen 的情况下以 readystate 3 关闭,尽管它在 chrome 开发工具中显示为 101。

这是我计算密钥的代码

string magickey = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
string key = msgkey.append(magickey);

unsigned char* sha_str = SHA1(reinterpret_cast<const unsigned char*>(key.c_str()), key.length(), nullptr);
string acceptkey = base64_encode(reinterpret_cast<const unsigned char*>(sha_str), strlen((char*)sha_str));

string handshake_response = "HTTP/1.1 101 Switching Protocols\r\n";
handshake_response.append("Upgrade: websocket\r\n");
handshake_response.append("Connection: Upgrade\r\n");
handshake_response.append("Sec-WebSocket-Accept: "+acceptkey+"\r\n");
handshake_response.append("\r\n");  

Chrome 响应

HTTP/1.1 101 Switching Protocols  
Upgrade: websocket  
Connection: Upgrade  
Sec-WebSocket-Accept: 5T5MvxP1iz40vLpi3kQs/ifDaCo=  

Chrome 请求

GET ws://localhost:4897/echo HTTP/1.1  
Host: localhost:4897  
Connection: Upgrade  
Pragma: no-cache  
Cache-Control: no-cache  
Upgrade: websocket  
Origin: http://localhost  
Sec-WebSocket-Version: 13  
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36  
Accept-Encoding: gzip, deflate, sdch  
Accept-Language: en-US,en;q=0.8  
Sec-WebSocket-Key: LKF8lHGznbKGIgO1UzAOhg==  
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits  

它显示“WebSocket 握手期间出错:'Sec-WebSocket-Accept' 标头值不正确”。

Chrome 还显示了一个额外的帧接收大小为 79 字节的操作码 -1。

谢谢大家!

【问题讨论】:

  • acceptkey 的值是多少?
  • 谢谢,我已经列出了问题中的关键值
  • 您是否尝试过使用 \n 而不是 \r\n ?此外,Chrome 输出中的行顺序似乎不同(来自您的代码)。
  • yes \n 完全一样,我还将 chrome 输出编辑为实际标题而不是解析。
  • 我使用的是 Windows 8,所以 /r/n 应该是正确的。

标签: javascript c++ websocket


【解决方案1】:

Chrome 说“Sec-WebSocket-Accept”不正确。尝试手动计算,不得不同意Chrome。

我的测试:

  1. 连接“LKF8lHGznbKGIgO1UzAOhg==”和“258EAFA5-E914-47DA-95CA-C5AB0DC85B11” => "LKF8lHGznbKGIgO1UzAOhg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11",即key
  2. 计算 SHA1 160 位十六进制:bf15 14e3 7108 0ee4 7782 c709 a767 cc72 423d e5c4
  3. 根据您的日志,您对 base64 的编码为:5T5MvxP1iz40vLpi3kQs/ifDaCo=
  4. 将其解码为十六进制:e53e 4cbf 13f5 8b3e 34bc ba62 de44 2cfe 27c3 682a

粗体值应该相等。如果我在某个地方错了,请随时纠正我。

可能的问题:

  • sha_str 是空终止的吗?即strlen((char*)sha_str) == 20 ?

  • 有符号/无符号字符混合?

【讨论】:

  • aha,我发现问题是原始密钥中的前导空格,因此正如您所指出的,SHA1 不正确,套接字已打开,哇哦!非常感谢。
猜你喜欢
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
相关资源
最近更新 更多