WebSocket Handshake 76 Simplified

update
there was a superfluous CR+LN with char 0x00 that was causing buffer troubles, now fixed



I am working during my free time (... recently extremely hard to have ...) over a little project that I'd like to show at the Front Trends event this October and WebSocket is the key of this project.

While 2 days ago I eventually found a way to communicate in few lines of php with a WebSocket, yesterday Chromium blog announced they "simply changed it", causing basically problems to all those projects based over the good old handshake75.

After I have found in Axod's Hack that somebody else had basically my same thoughts, I still could not find any valid example able to do the new handshake ... so here I am with the first draft-ietf-hybi-thewebsocketprotocol-00 php implementation I know, inspired somehow from the go version.


<?php

class WebSocketHandshake {

/*! Easy way to handshake a WebSocket via draft-ietf-hybi-thewebsocketprotocol-00
* @link http://www.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-00.txt
* @author Andrea Giammarchi
* @blog webreflection.blogspot.com
* @date 4th June 2010
* @example
* // via function call ...
* $handshake = WebSocketHandshake($buffer);
* // ... or via class
* $handshake = (string)new WebSocketHandshake($buffer);
*
* socket_write($socket, $handshake, strlen($handshake));
*/

private $__value__;

public function __construct($buffer) {
$resource = $host = $origin = $key1 = $key2 = $protocol = $code = $handshake = null;
preg_match('#GET (.*?) HTTP#', $buffer, $match) && $resource = $match[1];
preg_match("#Host: (.*?)\r\n#", $buffer, $match) && $host = $match[1];
preg_match("#Sec-WebSocket-Key1: (.*?)\r\n#", $buffer, $match) && $key1 = $match[1];
preg_match("#Sec-WebSocket-Key2: (.*?)\r\n#", $buffer, $match) && $key2 = $match[1];
preg_match("#Sec-WebSocket-Protocol: (.*?)\r\n#", $buffer, $match) && $protocol = $match[1];
preg_match("#Origin: (.*?)\r\n#", $buffer, $match) && $origin = $match[1];
preg_match("#\r\n(.*?)\$#", $buffer, $match) && $code = $match[1];
$this->__value__ =
"HTTP/1.1 101 WebSocket Protocol Handshake\r\n".
"Upgrade: WebSocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Origin: {$origin}\r\n".
"Sec-WebSocket-Location: ws://{$host}{$resource}\r\n".
($protocol ? "Sec-WebSocket-Protocol: {$protocol}\r\n" : "").
"\r\n".
$this->_createHandshakeThingy($key1, $key2, $code)
;
}

public function __toString() {
return $this->__value__;
}

private function _doStuffToObtainAnInt32($key) {
return preg_match_all('#[0-9]#', $key, $number) && preg_match_all('# #', $key, $space) ?
implode('', $number[0]) / count($space[0]) :
''
;
}

private function _createHandshakeThingy($key1, $key2, $code) {
return md5(
pack('N', $this->_doStuffToObtainAnInt32($key1)).
pack('N', $this->_doStuffToObtainAnInt32($key2)).
$code,
true
);
}
}

// handshake headers strings factory
function WebSocketHandshake($buffer) {
return (string)new WebSocketHandshake($buffer);
}

?>


I am pretty sure above code does not need any other comment and methods are "as much semantic as possible", since I completely agree about the Axod point and the fact it's both over engineered and absolutely badly documented via those "specs" ... weird from a company famous for its simplicity concept that maybe this time forgot some KISS approach ...

Comments

Popular posts from this blog

Resurrecting The With Statement

HEAVY HEADS

back in town with a little CSS present