简体   繁体   English

WebSocket握手期间出错:PHP的“Sec-WebSocket-Accept”标头值不正确

[英]Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value with PHP

I've coded websocket server/client with PHP and it worked for me during 2 years. 我用PHP编写了websocket服务器/客户端,它在2年内为我工作。 Now it is not working, saying: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value 现在它不起作用,说: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

My clientside code is essentially this: 我的客户端代码基本上是这样的:

socket = new WebSocket("ws://<?= EVENT_SERVER_ADDR ?>:"+EVENT_SERVER_PORT+"<?= EVENT_SERVER_WWW_PATH ?>");

PHP serverside code is this: PHP服务器端代码是这样的:

list ($resource, $host, $connection, $version, $origin, $key, $protocol, $upgrade) = $this->getheaders ($buffer);

$this->log ("Handshaking...");
$reply  = 
    "HTTP/1.1 101 Switching Protocols\r\n" .
    "Upgrade: {$upgrade}\r\n" .
    "Connection: {$connection}\r\n" .
    "Sec-WebSocket-Version: {$version}\r\n" .
    "Sec-WebSocket-Origin: {$origin}\r\n" .
    "Sec-WebSocket-Location: ws://{$host}{$resource}\r\n" .
    "Sec-WebSocket-Accept: " . $this->calcKey ($key) . "\r\n";
if ($protocol)
    $reply .= "Sec-WebSocket-Protocol: $protocol\r\n";
$reply .=   "\r\n";

// Closes the handshake
socket_write ($user->socket, $reply, strlen ($reply));

function calcKey ($key) {
    // Constant string as specified in the ietf-hybi-17 draft
    $key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    $key = sha1 ($key, true);
    // $key = pack ('H*', $key); // should I uncomment this line?
    $key = base64_encode ($key);

    return $key;
}

function getheaders ($buffer) {
    $resource = $host = $connection = $version = $origin = $key = $protocol = $upgrade = null;

    preg_match ('#GET (.*?) HTTP#', $buffer, $match) && $resource = $match[1];
    preg_match ("#Host: (.*?)\r\n#", $buffer, $match) && $host = $match[1];
    preg_match ("#Connection: (.*?)\r\n#", $buffer, $match) && $connection = $match[1];
    preg_match ("#Sec-WebSocket-Version: (.*?)\r\n#", $buffer, $match) && $version = $match[1];
    preg_match ("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1];
    preg_match ("#Sec-WebSocket-Key:\s*(.*?)\r\n#", $buffer, $match) && $key = $match[1];
    preg_match ("#Sec-WebSocket-Protocol:\s*(.*?)\r\n#", $buffer, $match) && $protocol = $match[1];
    preg_match ("#Upgrade: (.*?)\r\n#", $buffer, $match) && $upgrade = $match[1];

    return array ($resource, $host, $connection, $version, $origin, $key, $protocol, $upgrade);
}

It's funny that those guys just changed the standard without keeping old code functioning and without saying anything online (I really tried to google it very hard). 有趣的是,那些家伙只是改变了标准而没有保持旧代码的功能,也没有在网上说任何话(我真的很努力地去谷歌)。 Does anyone know what's my problem? 有谁知道我的问题是什么?

So I figured out the problem. 所以我想出了问题所在。 And that was the buffer limit . 那是缓冲限制

Apparently, the variable $buffer contained only about 4 KB of data, and because of cookies that were coming from dataTables, the input data was much more. 显然,变量$buffer只包含大约4 KB的数据,而且由于来自dataTables的cookie,输入数据要多得多。 And the Sec-WebSocket-Key header was after all cookies. 并且Sec-WebSocket-Key标题是在所有cookie之后。 So the $key was empty every time, giving wrong Sec-WebSocket-Accept . 所以$key每次都是空的,给出了错误的Sec-WebSocket-Accept

Advice: debug more deeply . 建议: 调试更深入

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM