Refactor just RFC6455, Interfaces, Valication
This commit is contained in:
parent
80124ec05e
commit
aa6bb1b40e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
composer.lock
|
||||||
|
vendor
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2011-2014 Chris Boden
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -1,120 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket\Version;
|
|
||||||
use Ratchet\ConnectionInterface;
|
|
||||||
use Ratchet\MessageInterface;
|
|
||||||
use Ratchet\WebSocket\Version\Hixie76\Connection;
|
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
|
||||||
use Guzzle\Http\Message\Response;
|
|
||||||
use Ratchet\WebSocket\Version\Hixie76\Frame;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FOR THE LOVE OF BEER, PLEASE PLEASE PLEASE DON'T allow the use of this in your application!
|
|
||||||
* Hixie76 is bad for 2 (there's more) reasons:
|
|
||||||
* 1) The handshake is done in HTTP, which includes a key for signing in the body...
|
|
||||||
* BUT there is no Length defined in the header (as per HTTP spec) so the TCP buffer can't tell when the message is done!
|
|
||||||
* 2) By nature it's insecure. Google did a test study where they were able to do a
|
|
||||||
* man-in-the-middle attack on 10%-15% of the people who saw their ad who had a browser (currently only Safari) supporting the Hixie76 protocol.
|
|
||||||
* This was exploited by taking advantage of proxy servers in front of the user who ignored some HTTP headers in the handshake
|
|
||||||
* The Hixie76 is currently implemented by Safari
|
|
||||||
* @link http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
|
||||||
*/
|
|
||||||
class Hixie76 implements VersionInterface {
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function isProtocol(RequestInterface $request) {
|
|
||||||
return !(null === $request->getHeader('Sec-WebSocket-Key2'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getVersionNumber() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Guzzle\Http\Message\RequestInterface $request
|
|
||||||
* @return \Guzzle\Http\Message\Response
|
|
||||||
* @throws \UnderflowException If there hasn't been enough data received
|
|
||||||
*/
|
|
||||||
public function handshake(RequestInterface $request) {
|
|
||||||
$body = substr($request->getBody(), 0, 8);
|
|
||||||
if (8 !== strlen($body)) {
|
|
||||||
throw new \UnderflowException("Not enough data received to issue challenge response");
|
|
||||||
}
|
|
||||||
|
|
||||||
$challenge = $this->sign((string)$request->getHeader('Sec-WebSocket-Key1'), (string)$request->getHeader('Sec-WebSocket-Key2'), $body);
|
|
||||||
|
|
||||||
$headers = array(
|
|
||||||
'Upgrade' => 'WebSocket'
|
|
||||||
, 'Connection' => 'Upgrade'
|
|
||||||
, 'Sec-WebSocket-Origin' => (string)$request->getHeader('Origin')
|
|
||||||
, 'Sec-WebSocket-Location' => 'ws://' . (string)$request->getHeader('Host') . $request->getPath()
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = new Response(101, $headers, $challenge);
|
|
||||||
$response->setStatus(101, 'WebSocket Protocol Handshake');
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function upgradeConnection(ConnectionInterface $conn, MessageInterface $coalescedCallback) {
|
|
||||||
$upgraded = new Connection($conn);
|
|
||||||
|
|
||||||
if (!isset($upgraded->WebSocket)) {
|
|
||||||
$upgraded->WebSocket = new \StdClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
$upgraded->WebSocket->coalescedCallback = $coalescedCallback;
|
|
||||||
|
|
||||||
return $upgraded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onMessage(ConnectionInterface $from, $data) {
|
|
||||||
$overflow = '';
|
|
||||||
|
|
||||||
if (!isset($from->WebSocket->frame)) {
|
|
||||||
$from->WebSocket->frame = $this->newFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
$from->WebSocket->frame->addBuffer($data);
|
|
||||||
if ($from->WebSocket->frame->isCoalesced()) {
|
|
||||||
$overflow = $from->WebSocket->frame->extractOverflow();
|
|
||||||
|
|
||||||
$parsed = $from->WebSocket->frame->getPayload();
|
|
||||||
unset($from->WebSocket->frame);
|
|
||||||
|
|
||||||
$from->WebSocket->coalescedCallback->onMessage($from, $parsed);
|
|
||||||
|
|
||||||
unset($from->WebSocket->frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen($overflow) > 0) {
|
|
||||||
$this->onMessage($from, $overflow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newFrame() {
|
|
||||||
return new Frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateKeyNumber($key) {
|
|
||||||
if (0 === substr_count($key, ' ')) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return preg_replace('[\D]', '', $key) / substr_count($key, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sign($key1, $key2, $code) {
|
|
||||||
return md5(
|
|
||||||
pack('N', $this->generateKeyNumber($key1))
|
|
||||||
. pack('N', $this->generateKeyNumber($key2))
|
|
||||||
. $code
|
|
||||||
, true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket\Version\Hixie76;
|
|
||||||
use Ratchet\AbstractConnectionDecorator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
* @property \StdClass $WebSocket
|
|
||||||
*/
|
|
||||||
class Connection extends AbstractConnectionDecorator {
|
|
||||||
public function send($msg) {
|
|
||||||
if (!$this->WebSocket->closing) {
|
|
||||||
$this->getConnection()->send(chr(0) . $msg . chr(255));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function close() {
|
|
||||||
if (!$this->WebSocket->closing) {
|
|
||||||
$this->getConnection()->send(chr(255));
|
|
||||||
$this->getConnection()->close();
|
|
||||||
|
|
||||||
$this->WebSocket->closing = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket\Version\Hixie76;
|
|
||||||
use Ratchet\WebSocket\Version\FrameInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This does not entirely follow the protocol to spec, but (mostly) works
|
|
||||||
* Hixie76 probably should not even be supported
|
|
||||||
*/
|
|
||||||
class Frame implements FrameInterface {
|
|
||||||
/**
|
|
||||||
* @type string
|
|
||||||
*/
|
|
||||||
protected $_data = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function isCoalesced() {
|
|
||||||
return (boolean)($this->_data[0] == chr(0) && substr($this->_data, -1) == chr(255));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function addBuffer($buf) {
|
|
||||||
$this->_data .= (string)$buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function isFinal() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function isMasked() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getOpcode() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getPayloadLength() {
|
|
||||||
if (!$this->isCoalesced()) {
|
|
||||||
throw new \UnderflowException('Not enough of the message has been buffered to determine the length of the payload');
|
|
||||||
}
|
|
||||||
|
|
||||||
return strlen($this->_data) - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getMaskingKey() {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getPayload() {
|
|
||||||
if (!$this->isCoalesced()) {
|
|
||||||
return new \UnderflowException('Not enough data buffered to read payload');
|
|
||||||
}
|
|
||||||
|
|
||||||
return substr($this->_data, 1, strlen($this->_data) - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getContents() {
|
|
||||||
return $this->_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function extractOverflow() {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket\Version;
|
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
|
||||||
|
|
||||||
class HyBi10 extends RFC6455 {
|
|
||||||
public function isProtocol(RequestInterface $request) {
|
|
||||||
$version = (int)(string)$request->getHeader('Sec-WebSocket-Version');
|
|
||||||
|
|
||||||
return ($version >= 6 && $version < 13);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersionNumber() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket;
|
|
||||||
use Ratchet\WebSocket\Version\VersionInterface;
|
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage the various versions of the WebSocket protocol
|
|
||||||
* This accepts interfaces of versions to enable/disable
|
|
||||||
*/
|
|
||||||
class VersionManager {
|
|
||||||
/**
|
|
||||||
* The header string to let clients know which versions are supported
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $versionString = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage of each version enabled
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $versions = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the protocol negotiator for the request, if supported
|
|
||||||
* @param \Guzzle\Http\Message\RequestInterface $request
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
* @return \Ratchet\WebSocket\Version\VersionInterface
|
|
||||||
*/
|
|
||||||
public function getVersion(RequestInterface $request) {
|
|
||||||
foreach ($this->versions as $version) {
|
|
||||||
if ($version->isProtocol($request)) {
|
|
||||||
return $version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \InvalidArgumentException("Version not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Guzzle\Http\Message\RequestInterface
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isVersionEnabled(RequestInterface $request) {
|
|
||||||
foreach ($this->versions as $version) {
|
|
||||||
if ($version->isProtocol($request)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable support for a specific version of the WebSocket protocol
|
|
||||||
* @param \Ratchet\WebSocket\Version\VersionInterface $version
|
|
||||||
* @return VersionManager
|
|
||||||
*/
|
|
||||||
public function enableVersion(VersionInterface $version) {
|
|
||||||
$this->versions[$version->getVersionNumber()] = $version;
|
|
||||||
|
|
||||||
if (empty($this->versionString)) {
|
|
||||||
$this->versionString = (string)$version->getVersionNumber();
|
|
||||||
} else {
|
|
||||||
$this->versionString .= ", {$version->getVersionNumber()}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable support for a specific WebSocket protocol version
|
|
||||||
* @param int $versionId The version ID to un-support
|
|
||||||
* @return VersionManager
|
|
||||||
*/
|
|
||||||
public function disableVersion($versionId) {
|
|
||||||
unset($this->versions[$versionId]);
|
|
||||||
|
|
||||||
$this->versionString = implode(',', array_keys($this->versions));
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string of version numbers supported (comma delimited)
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getSupportedVersionString() {
|
|
||||||
return $this->versionString;
|
|
||||||
}
|
|
||||||
}
|
|
232
WsServer.php
232
WsServer.php
@ -1,232 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket;
|
|
||||||
use Ratchet\MessageComponentInterface;
|
|
||||||
use Ratchet\ConnectionInterface;
|
|
||||||
use Ratchet\Http\HttpServerInterface;
|
|
||||||
use Guzzle\Http\Message\RequestInterface;
|
|
||||||
use Guzzle\Http\Message\Response;
|
|
||||||
use Ratchet\WebSocket\Version;
|
|
||||||
use Ratchet\WebSocket\Encoding\ToggleableValidator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The adapter to handle WebSocket requests/responses
|
|
||||||
* This is a mediator between the Server and your application to handle real-time messaging through a web browser
|
|
||||||
* @link http://ca.php.net/manual/en/ref.http.php
|
|
||||||
* @link http://dev.w3.org/html5/websockets/
|
|
||||||
*/
|
|
||||||
class WsServer implements HttpServerInterface {
|
|
||||||
/**
|
|
||||||
* Manage the various WebSocket versions to support
|
|
||||||
* @var VersionManager
|
|
||||||
* @note May not expose this in the future, may do through facade methods
|
|
||||||
*/
|
|
||||||
public $versioner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decorated component
|
|
||||||
* @var \Ratchet\MessageComponentInterface
|
|
||||||
*/
|
|
||||||
public $component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \SplObjectStorage
|
|
||||||
*/
|
|
||||||
protected $connections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holder of accepted protocols, implement through WampServerInterface
|
|
||||||
*/
|
|
||||||
protected $acceptedSubProtocols = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-8 validator
|
|
||||||
* @var \Ratchet\WebSocket\Encoding\ValidatorInterface
|
|
||||||
*/
|
|
||||||
protected $validator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag if we have checked the decorated component for sub-protocols
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
private $isSpGenerated = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Ratchet\MessageComponentInterface $component Your application to run with WebSockets
|
|
||||||
* If you want to enable sub-protocols have your component implement WsServerInterface as well
|
|
||||||
*/
|
|
||||||
public function __construct(MessageComponentInterface $component) {
|
|
||||||
$this->versioner = new VersionManager;
|
|
||||||
$this->validator = new ToggleableValidator;
|
|
||||||
|
|
||||||
$this->versioner
|
|
||||||
->enableVersion(new Version\RFC6455($this->validator))
|
|
||||||
->enableVersion(new Version\HyBi10($this->validator))
|
|
||||||
->enableVersion(new Version\Hixie76)
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->component = $component;
|
|
||||||
$this->connections = new \SplObjectStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
|
|
||||||
if (null === $request) {
|
|
||||||
throw new \UnexpectedValueException('$request can not be null');
|
|
||||||
}
|
|
||||||
|
|
||||||
$conn->WebSocket = new \StdClass;
|
|
||||||
$conn->WebSocket->request = $request;
|
|
||||||
$conn->WebSocket->established = false;
|
|
||||||
$conn->WebSocket->closing = false;
|
|
||||||
|
|
||||||
$this->attemptUpgrade($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function onMessage(ConnectionInterface $from, $msg) {
|
|
||||||
if ($from->WebSocket->closing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (true === $from->WebSocket->established) {
|
|
||||||
return $from->WebSocket->version->onMessage($this->connections[$from], $msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->attemptUpgrade($from, $msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function attemptUpgrade(ConnectionInterface $conn, $data = '') {
|
|
||||||
if ('' !== $data) {
|
|
||||||
$conn->WebSocket->request->getBody()->write($data);
|
|
||||||
} else {
|
|
||||||
if (!$this->versioner->isVersionEnabled($conn->WebSocket->request)) {
|
|
||||||
return $this->close($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
$conn->WebSocket->version = $this->versioner->getVersion($conn->WebSocket->request);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$response = $conn->WebSocket->version->handshake($conn->WebSocket->request);
|
|
||||||
} catch (\UnderflowException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null !== ($subHeader = $conn->WebSocket->request->getHeader('Sec-WebSocket-Protocol'))) {
|
|
||||||
if ('' !== ($agreedSubProtocols = $this->getSubProtocolString($subHeader->normalize()))) {
|
|
||||||
$response->setHeader('Sec-WebSocket-Protocol', $agreedSubProtocols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$response->setHeader('X-Powered-By', \Ratchet\VERSION);
|
|
||||||
$conn->send((string)$response);
|
|
||||||
|
|
||||||
if (101 != $response->getStatusCode()) {
|
|
||||||
return $conn->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
$upgraded = $conn->WebSocket->version->upgradeConnection($conn, $this->component);
|
|
||||||
|
|
||||||
$this->connections->attach($conn, $upgraded);
|
|
||||||
|
|
||||||
$upgraded->WebSocket->established = true;
|
|
||||||
|
|
||||||
return $this->component->onOpen($upgraded);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function onClose(ConnectionInterface $conn) {
|
|
||||||
if ($this->connections->contains($conn)) {
|
|
||||||
$decor = $this->connections[$conn];
|
|
||||||
$this->connections->detach($conn);
|
|
||||||
|
|
||||||
$this->component->onClose($decor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function onError(ConnectionInterface $conn, \Exception $e) {
|
|
||||||
if ($conn->WebSocket->established && $this->connections->contains($conn)) {
|
|
||||||
$this->component->onError($this->connections[$conn], $e);
|
|
||||||
} else {
|
|
||||||
$conn->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable a specific version of the WebSocket protocol
|
|
||||||
* @param int $versionId Version ID to disable
|
|
||||||
* @return WsServer
|
|
||||||
*/
|
|
||||||
public function disableVersion($versionId) {
|
|
||||||
$this->versioner->disableVersion($versionId);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle weather to check encoding of incoming messages
|
|
||||||
* @param bool
|
|
||||||
* @return WsServer
|
|
||||||
*/
|
|
||||||
public function setEncodingChecks($opt) {
|
|
||||||
$this->validator->on = (boolean)$opt;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function isSubProtocolSupported($name) {
|
|
||||||
if (!$this->isSpGenerated) {
|
|
||||||
if ($this->component instanceof WsServerInterface) {
|
|
||||||
$this->acceptedSubProtocols = array_flip($this->component->getSubProtocols());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->isSpGenerated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_key_exists($name, $this->acceptedSubProtocols);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Traversable|null $requested
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getSubProtocolString(\Traversable $requested = null) {
|
|
||||||
if (null !== $requested) {
|
|
||||||
foreach ($requested as $sub) {
|
|
||||||
if ($this->isSubProtocolSupported($sub)) {
|
|
||||||
return $sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a connection with an HTTP response
|
|
||||||
* @param \Ratchet\ConnectionInterface $conn
|
|
||||||
* @param int $code HTTP status code
|
|
||||||
*/
|
|
||||||
protected function close(ConnectionInterface $conn, $code = 400) {
|
|
||||||
$response = new Response($code, array(
|
|
||||||
'Sec-WebSocket-Version' => $this->versioner->getSupportedVersionString()
|
|
||||||
, 'X-Powered-By' => \Ratchet\VERSION
|
|
||||||
));
|
|
||||||
|
|
||||||
$conn->send((string)$response);
|
|
||||||
$conn->close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Ratchet\WebSocket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WebSocket Server Interface
|
|
||||||
*/
|
|
||||||
interface WsServerInterface {
|
|
||||||
/**
|
|
||||||
* If any component in a stack supports a WebSocket sub-protocol return each supported in an array
|
|
||||||
* @return array
|
|
||||||
* @temporary This method may be removed in future version (note that will not break code, just make some code obsolete)
|
|
||||||
*/
|
|
||||||
function getSubProtocols();
|
|
||||||
}
|
|
28
composer.json
Normal file
28
composer.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "ratchet/rfc6455"
|
||||||
|
, "type": "library"
|
||||||
|
, "description": "RFC6455 protocol handler"
|
||||||
|
, "keywords": ["WebSockets"]
|
||||||
|
, "homepage": "http://socketo.me"
|
||||||
|
, "license": "MIT"
|
||||||
|
, "authors": [
|
||||||
|
{
|
||||||
|
"name": "Chris Boden"
|
||||||
|
, "email": "cboden@gmail.com"
|
||||||
|
, "role": "Developer"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, "support": {
|
||||||
|
"forum": "https://groups.google.com/forum/#!forum/ratchet-php"
|
||||||
|
, "issues": "https://github.com/ratchetphp/Ratchet/issues"
|
||||||
|
, "irc": "irc://irc.freenode.org/reactphp"
|
||||||
|
}
|
||||||
|
, "autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Ratchet\\WebSocket\\": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, "require": {
|
||||||
|
"php": ">=5.4.2"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user