HyBi-10 handshake
Hackishly implemented the HyBi-10 handshake
This commit is contained in:
parent
3af575b4e9
commit
ed1a35ff74
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
namespace Ratchet\Protocol;
|
||||
use Ratchet\Server;
|
||||
use Ratchet\Server\Client;
|
||||
use Ratchet\Protocol\WebSocket\Client;
|
||||
use Ratchet\Protocol\WebSocket\Version;
|
||||
use Ratchet\Server\Message;
|
||||
use Ratchet\Socket;
|
||||
|
||||
@ -15,22 +16,24 @@ class WebSocket implements ProtocolInterface {
|
||||
protected $_server;
|
||||
|
||||
/**
|
||||
* @type Ratchet\Protocol\WebSocket\Version\VersionInterface
|
||||
* @type SplObjectStorage
|
||||
*/
|
||||
protected $_version = null;
|
||||
protected $_lookup;
|
||||
|
||||
protected $_shook_hands = false;
|
||||
public function __construct() {
|
||||
$this->_lookup = new \SplObjectStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Array
|
||||
*/
|
||||
public static function getDefaultConfig() {
|
||||
return Array(
|
||||
return array(
|
||||
'domain' => AF_INET
|
||||
, 'type' => SOCK_STREAM
|
||||
, 'protocol' => SOL_TCP
|
||||
, 'options' => Array(
|
||||
SOL_SOCKET => Array(SO_REUSEADDR => 1)
|
||||
, 'options' => array(
|
||||
SOL_SOCKET => array(SO_REUSEADDR => 1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -38,7 +41,7 @@ class WebSocket implements ProtocolInterface {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
public function getName() {
|
||||
return 'WebSocket';
|
||||
}
|
||||
|
||||
@ -46,12 +49,49 @@ class WebSocket implements ProtocolInterface {
|
||||
$this->_server = $server;
|
||||
}
|
||||
|
||||
function handleConnect(Socket $client) {
|
||||
public function handleConnect(Socket $client) {
|
||||
$this->_lookup[$client] = new Client;
|
||||
}
|
||||
|
||||
function handleMessage($message, Socket $from) {
|
||||
public function handleMessage($message, Socket $from) {
|
||||
$headers = $this->getHeaders($message);
|
||||
$client = $this->_lookup[$from];
|
||||
if (true !== $client->isHandshakeComplete()) {
|
||||
$header = $client->doHandshake($this->getVersion($headers));
|
||||
|
||||
$from->write($header, strlen($header));
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose(Socket $client) {
|
||||
public function handleClose(Socket $client) {
|
||||
unset($this->_lookup[$client]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public function setSubProtocol($name) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
protected function getHeaders($http_message) {
|
||||
return http_parse_headers($http_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Version\VersionInterface
|
||||
*/
|
||||
protected function getVersion(array $headers) {
|
||||
if (isset($headers['Sec-Websocket-Version'])) { // HyBi
|
||||
if ($headers['Sec-Websocket-Version'] == '8') {
|
||||
return new Version\Hybi10($headers);
|
||||
}
|
||||
} elseif (isset($headers['Sec-Websocket-Key2'])) { // Hixie
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('Could not identify WebSocket protocol');
|
||||
}
|
||||
}
|
31
lib/Ratchet/Protocol/WebSocket/Client.php
Normal file
31
lib/Ratchet/Protocol/WebSocket/Client.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Ratchet\Protocol\WebSocket;
|
||||
use Ratchet\Protocol\WebSocket\Version\VersionInterface;
|
||||
|
||||
class Client {
|
||||
/**
|
||||
* @type Ratchet\Protocol\WebSocket\Version\VersionInterface
|
||||
*/
|
||||
protected $_version = null;
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
protected $_hands_shook = false;
|
||||
|
||||
public function doHandshake(VersionInterface $version) {
|
||||
$key = $version->sign();
|
||||
// $tosend['Sec-WebSocket-Accept'] = $key;
|
||||
|
||||
$this->_hands_shook = true;
|
||||
|
||||
return "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {$key}\r\nSec-WebSocket-Protocol: test\r\n\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHandshakeComplete() {
|
||||
return $this->_hands_shook;
|
||||
}
|
||||
}
|
@ -2,6 +2,11 @@
|
||||
namespace Ratchet\Protocol\WebSocket\Version;
|
||||
|
||||
class Hixie76 implements VersionInterface {
|
||||
protected $_headers = array();
|
||||
|
||||
public function __construct(array $headers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Headers
|
||||
* @return string
|
||||
|
@ -4,7 +4,17 @@ namespace Ratchet\Protocol\WebSocket\Version;
|
||||
class Hybi10 implements VersionInterface {
|
||||
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
||||
|
||||
public function sign($key) {
|
||||
protected $_headers = array();
|
||||
|
||||
public function __construct(array $headers) {
|
||||
$this->_headers = $headers;
|
||||
}
|
||||
|
||||
public function sign($key = null) {
|
||||
if (null === $key) {
|
||||
$key = $this->_headers['Sec-Websocket-Key'];
|
||||
}
|
||||
|
||||
return base64_encode(sha1($key . static::GUID, 1));
|
||||
}
|
||||
}
|
@ -2,6 +2,11 @@
|
||||
namespace Ratchet\Protocol\WebSocket\Version;
|
||||
|
||||
interface VersionInterface {
|
||||
/**
|
||||
* @param array
|
||||
*/
|
||||
function __construct(array $headers);
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return string
|
||||
|
@ -89,6 +89,10 @@ class Server implements ServerInterface {
|
||||
return $this->_connections;
|
||||
}
|
||||
|
||||
public function log($msg, $type = 'note') {
|
||||
call_user_func(array($this->_log, $type), $msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param mixed
|
||||
* @param int
|
||||
@ -112,6 +116,8 @@ class Server implements ServerInterface {
|
||||
throw new Exception;
|
||||
}
|
||||
|
||||
$this->_master->set_nonblock();
|
||||
|
||||
do {
|
||||
try {
|
||||
$changed = $this->_resources;
|
||||
@ -156,7 +162,7 @@ class Server implements ServerInterface {
|
||||
}
|
||||
|
||||
protected function onMessage($msg, Socket $from) {
|
||||
$this->_log->note('New message "' . trim($msg) . '"');
|
||||
$this->_log->note('New message "' . $msg . '"');
|
||||
$this->tmpRIterator('handleMessage', $msg, $from);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ use Ratchet\Protocol\ProtocolInterface;
|
||||
/**
|
||||
* A wrapper for the PHP socket_ functions
|
||||
* @author Chris Boden <shout at chrisboden dot ca>
|
||||
* @todo Needs to be observable, Server needs to know when an applicaiton closes a connection
|
||||
*/
|
||||
class Socket {
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user