问题
I've coded websocket server/client with PHP and it worked for me during 2 years. Now it is not working, saying: 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:
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?
回答1:
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. And the Sec-WebSocket-Key
header was after all cookies. So the $key
was empty every time, giving wrong Sec-WebSocket-Accept
.
Advice: debug more deeply.
来源:https://stackoverflow.com/questions/29590412/error-during-websocket-handshake-incorrect-sec-websocket-accept-header-value