0

I'm trying to develop the handshake for websocket hybi-17 protocol (https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17). According to that draft, I made the following code for the client (user-agent):

var host = 'ws://localhost/server.php';
if ('MozWebSocket' in window) ws = new MozWebSocket (host);
else ws = new WebSocket (host);

and this code for the server (I skipped the socket initialization/management part):

$key = $value = null;
preg_match ("#Sec-WebSocket-Key: (.*?)\r\n#", $buffer, $match) && $key = $match[1];
$key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
$key = sha1 ($key);
$key = pack ('H*', $key);
$key = base64_encode ($key);

$value = 
  "HTTP/1.1 101 Switching Protocols\r\n" .
  "Upgrade: websocket\r\n" .
  "Connection: Upgrade\r\n" .
  "Sec-WebSocket-Accept: {$key}";

socket_write ($socket, $value, strlen ($value));

Now, following an example, starting with the client request (simply done with 'new MozWebSocket (host)' call):

GET /server.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: http://localhost
Sec-WebSocket-Extensions: deflate-stream
Sec-WebSocket-Key: oqFCBULD7k+BM41Bc3VEeA==
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

The server response (echoed in the local shell, as a debug line):

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: TlKc0Ck7WpqsLhMm/QXABMQWARk=

I followed what specified in the IETF hybi-17 draft but the client request is still pending and there's no real connection between client and server.

What's wrong? What I have to do more?

Thanks in advance.

Community
  • 1
  • 1
Wilk
  • 7,873
  • 9
  • 46
  • 70

1 Answers1

1

A HTTP response is defined as:

   Response      = Status-Line               ; Section 6.1
                   *(( general-header        ; Section 4.5
                    | response-header        ; Section 6.2
                    | entity-header ) CRLF)  ; Section 7.1
                   CRLF
                   [ message-body ]          ; Section 7.2

The message body is empty, but there should still be two CRLFs after all headers (one CRLF after each header and one final extra one).

So your code should look like:

$value = 
  "HTTP/1.1 101 Switching Protocols\r\n" .
  "Upgrade: websocket\r\n" .
  "Connection: Upgrade\r\n" .
  "Sec-WebSocket-Accept: {$key}\r\n\r\n";
Community
  • 1
  • 1
pimvdb
  • 151,816
  • 78
  • 307
  • 352