HyBi-10 handshake
Hackishly implemented the HyBi-10 handshake
This commit is contained in:
parent
3af575b4e9
commit
ed1a35ff74
@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Ratchet\Protocol;
|
namespace Ratchet\Protocol;
|
||||||
use Ratchet\Server;
|
use Ratchet\Server;
|
||||||
use Ratchet\Server\Client;
|
use Ratchet\Protocol\WebSocket\Client;
|
||||||
|
use Ratchet\Protocol\WebSocket\Version;
|
||||||
use Ratchet\Server\Message;
|
use Ratchet\Server\Message;
|
||||||
use Ratchet\Socket;
|
use Ratchet\Socket;
|
||||||
|
|
||||||
@ -15,22 +16,24 @@ class WebSocket implements ProtocolInterface {
|
|||||||
protected $_server;
|
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
|
* @return Array
|
||||||
*/
|
*/
|
||||||
public static function getDefaultConfig() {
|
public static function getDefaultConfig() {
|
||||||
return Array(
|
return array(
|
||||||
'domain' => AF_INET
|
'domain' => AF_INET
|
||||||
, 'type' => SOCK_STREAM
|
, 'type' => SOCK_STREAM
|
||||||
, 'protocol' => SOL_TCP
|
, 'protocol' => SOL_TCP
|
||||||
, 'options' => Array(
|
, 'options' => array(
|
||||||
SOL_SOCKET => Array(SO_REUSEADDR => 1)
|
SOL_SOCKET => array(SO_REUSEADDR => 1)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -38,7 +41,7 @@ class WebSocket implements ProtocolInterface {
|
|||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function getName() {
|
public function getName() {
|
||||||
return 'WebSocket';
|
return 'WebSocket';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,12 +49,49 @@ class WebSocket implements ProtocolInterface {
|
|||||||
$this->_server = $server;
|
$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;
|
namespace Ratchet\Protocol\WebSocket\Version;
|
||||||
|
|
||||||
class Hixie76 implements VersionInterface {
|
class Hixie76 implements VersionInterface {
|
||||||
|
protected $_headers = array();
|
||||||
|
|
||||||
|
public function __construct(array $headers) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Headers
|
* @param Headers
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -4,7 +4,17 @@ namespace Ratchet\Protocol\WebSocket\Version;
|
|||||||
class Hybi10 implements VersionInterface {
|
class Hybi10 implements VersionInterface {
|
||||||
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
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));
|
return base64_encode(sha1($key . static::GUID, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,11 @@
|
|||||||
namespace Ratchet\Protocol\WebSocket\Version;
|
namespace Ratchet\Protocol\WebSocket\Version;
|
||||||
|
|
||||||
interface VersionInterface {
|
interface VersionInterface {
|
||||||
|
/**
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
function __construct(array $headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string
|
* @param string
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -89,6 +89,10 @@ class Server implements ServerInterface {
|
|||||||
return $this->_connections;
|
return $this->_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function log($msg, $type = 'note') {
|
||||||
|
call_user_func(array($this->_log, $type), $msg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param mixed
|
* @param mixed
|
||||||
* @param int
|
* @param int
|
||||||
@ -112,6 +116,8 @@ class Server implements ServerInterface {
|
|||||||
throw new Exception;
|
throw new Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->_master->set_nonblock();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
$changed = $this->_resources;
|
$changed = $this->_resources;
|
||||||
@ -156,7 +162,7 @@ class Server implements ServerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function onMessage($msg, Socket $from) {
|
protected function onMessage($msg, Socket $from) {
|
||||||
$this->_log->note('New message "' . trim($msg) . '"');
|
$this->_log->note('New message "' . $msg . '"');
|
||||||
$this->tmpRIterator('handleMessage', $msg, $from);
|
$this->tmpRIterator('handleMessage', $msg, $from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ use Ratchet\Protocol\ProtocolInterface;
|
|||||||
/**
|
/**
|
||||||
* A wrapper for the PHP socket_ functions
|
* A wrapper for the PHP socket_ functions
|
||||||
* @author Chris Boden <shout at chrisboden dot ca>
|
* @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 {
|
class Socket {
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user