diff --git a/WsServer.php b/WsServer.php index c3b1a48..748facc 100644 --- a/WsServer.php +++ b/WsServer.php @@ -15,7 +15,7 @@ use Ratchet\WebSocket\Guzzle\Http\Message\RequestFactory; class WsServer implements MessageComponentInterface { /** * Decorated component - * @var Ratchet\MessageComponentInterface + * @var Ratchet\MessageComponentInterface|WsServerInterface */ protected $_decorating; @@ -41,8 +41,17 @@ class WsServer implements MessageComponentInterface { * @deprecated * @temporary */ - public $accepted_subprotocols = array(); + protected $acceptedSubProtocols = array(); + /** + * Flag if we have checked the decorated component for sub-protocols + * @var boolean + */ + private $isSpGenerated = false; + + /** + * @param Ratchet\MessageComponentInterface Your application to run with WebSockets + */ public function __construct(MessageComponentInterface $component) { $this->_decorating = $component; $this->connections = new \SplObjectStorage; @@ -77,19 +86,10 @@ class WsServer implements MessageComponentInterface { $response = $from->WebSocket->version->handshake($from->WebSocket->headers); $from->WebSocket->handshake = true; - // This block is to be moved/changed later - $agreed_protocols = array(); - $requested_protocols = $from->WebSocket->headers->getTokenizedHeader('Sec-WebSocket-Protocol', ','); - if (null !== $requested_protocols) { - foreach ($this->accepted_subprotocols as $sub_protocol) { - if (false !== $requested_protocols->hasValue($sub_protocol)) { - $agreed_protocols[] = $sub_protocol; - } - } - } - if (count($agreed_protocols) > 0) { - $response->setHeader('Sec-WebSocket-Protocol', implode(',', $agreed_protocols)); + if ('' !== ($agreedSubProtocols = $this->getSubProtocolString($from->WebSocket->headers->getTokenizedHeader('Sec-WebSocket-Protocol', ',')))) { + $response->setHeader('Sec-WebSocket-Protocol', $agreedSubProtocols); } + $response->setHeader('X-Powered-By', \Ratchet\VERSION); $header = (string)$response; @@ -205,6 +205,42 @@ class WsServer implements MessageComponentInterface { return true; } + /** + * @param string + * @return boolean + */ + public function isSubProtocolSupported($name) { + if (!$this->isSpGenerated) { + if ($this->_decorating instanceof WsServerInterface) { + $this->acceptedSubProtocols = array_flip($this->_decorating->getSubProtocols()); + } + + $this->isSpGenerated = true; + } + + return array_key_exists($name, $this->acceptedSubProtocols); + } + + /** + * @param Traversable + * @return string + */ + protected function getSubProtocolString(\Traversable $requested = null) { + if (null === $requested) { + return ''; + } + + $string = ''; + + foreach ($requested as $sub) { + if ($this->isSubProtocolSupported($sub)) { + $string .= $sub . ','; + } + } + + return substr($string, 0, -1); + } + /** * Disable a version of the WebSocket protocol *cough*Hixie76*cough* * @param string The name of the version to disable diff --git a/WsServerInterface.php b/WsServerInterface.php index 30b9ba4..8cb378d 100644 --- a/WsServerInterface.php +++ b/WsServerInterface.php @@ -1,16 +1,11 @@