2

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?

4
  • Hi, it is failing with different browsers? Obvious question, but you didn't specify it. Commented Apr 12, 2015 at 14:21
  • @pietro909 it's failing with Chrome 41, Firefox says: "Firefox can't establish a connection to the server at ws://192.168.1.34:38848/operator/modules/campaign/event_server.php" Commented Apr 12, 2015 at 15:02
  • @pietro909 Safari under MacOS 10.9 says: "[Error] WebSocket connection to 'ws://192.168.1.34:38848/operator/modules/campaign/event_server.php' failed: Invalid UTF-8 sequence in header value (campaign.php, line 0)" Commented Apr 12, 2015 at 15:03
  • IE 11 seems to work though... Commented Apr 12, 2015 at 15:22

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm using substr to get the Sec-WebSocket-Key, but, well... I still get the same error. Can you help me? :(

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.