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

谁说我不能喝 提交于 2019-12-06 08:01:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!