diff --git a/src/Handshake/Negotiator.php b/src/Handshake/Negotiator.php index 4b6373c..315824b 100644 --- a/src/Handshake/Negotiator.php +++ b/src/Handshake/Negotiator.php @@ -2,7 +2,7 @@ namespace Ratchet\RFC6455\Handshake; use GuzzleHttp\Psr7\Response; -use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\RequestInterface; use Ratchet\RFC6455\Encoding\ValidatorInterface; /** @@ -20,25 +20,16 @@ class Negotiator implements NegotiatorInterface { */ private $validator; - /** - * A lookup of the valid close codes that can be sent in a frame - * @var array - * @deprecated - */ - private $closeCodes = []; - public function __construct(ValidatorInterface $validator) { $this->verifier = new RequestVerifier; - $this->setCloseCodes(); - $this->validator = $validator; } /** * {@inheritdoc} */ - public function isProtocol(ServerRequestInterface $request) { + public function isProtocol(RequestInterface $request) { $version = (int)(string)$request->getHeader('Sec-WebSocket-Version'); return ($this->getVersionNumber() === $version); @@ -54,7 +45,7 @@ class Negotiator implements NegotiatorInterface { /** * {@inheritdoc} */ - public function handshake(ServerRequestInterface $request) { + public function handshake(RequestInterface $request) { if (true !== $this->verifier->verifyAll($request)) { return new Response(400); } @@ -71,9 +62,9 @@ class Negotiator implements NegotiatorInterface { * @param \Ratchet\WebSocket\Version\RFC6455\Connection $from * @param string $data */ - public function onMessage(ConnectionInterface $from, $data) { - - } +// public function onMessage(ConnectionInterface $from, $data) { +// +// } /** * Used when doing the handshake to encode the key, verifying client/server are speaking the same language @@ -84,4 +75,26 @@ class Negotiator implements NegotiatorInterface { public function sign($key) { return base64_encode(sha1($key . static::GUID, true)); } + + /** + * Add supported protocols. If the request has any matching the response will include one + * @param string $id + */ + function addSupportedSubProtocol($id) + { + // TODO: Implement addSupportedSubProtocol() method. + } + + /** + * If enabled and support for a subprotocol has been added handshake + * will not upgrade if a match between request and supported subprotocols + * @param boolean $enable + * @todo Consider extending this interface and moving this there. + * The spec does says the server can fail for this reason, but + * it is not a requirement. This is an implementation detail. + */ + function setStrictSubProtocolCheck($enable) + { + // TODO: Implement setStrictSubProtocolCheck() method. + } } diff --git a/src/Handshake/NegotiatorInterface.php b/src/Handshake/NegotiatorInterface.php index cb7cbaf..a5032f8 100644 --- a/src/Handshake/NegotiatorInterface.php +++ b/src/Handshake/NegotiatorInterface.php @@ -1,8 +1,8 @@ verifyMethod($request->getMethod()); $passes += (int)$this->verifyHTTPVersion($request->getProtocolVersion()); - $passes += (int)$this->verifyRequestURI($request->getPath()); + $passes += (int)$this->verifyRequestURI($request->getUri()->getPath()); $passes += (int)$this->verifyHost((string)$request->getHeader('Host')); $passes += (int)$this->verifyUpgradeRequest((string)$request->getHeader('Upgrade')); $passes += (int)$this->verifyConnection((string)$request->getHeader('Connection')); $passes += (int)$this->verifyKey((string)$request->getHeader('Sec-WebSocket-Key')); - $passes += (int)$this->verifyVersion($headers['Sec-WebSocket-Version']); + $passes += (int)$this->verifyVersion((string)$request->getHeader('Sec-WebSocket-Version')); return (8 === $passes); } diff --git a/src/Messaging/Protocol/Message.php b/src/Messaging/Protocol/Message.php index 96a6b4a..1ff8fd6 100644 --- a/src/Messaging/Protocol/Message.php +++ b/src/Messaging/Protocol/Message.php @@ -7,6 +7,9 @@ class Message implements MessageInterface { */ private $_frames; + /** @var bool */ + private $binary = false; + public function __construct() { $this->_frames = new \SplDoublyLinkedList; } @@ -50,8 +53,12 @@ class Message implements MessageInterface { /** * {@inheritdoc} * @todo Also, I should perhaps check the type...control frames (ping/pong/close) are not to be considered part of a message + * @todo What should we do if there are binary and text mixed together? */ public function addFrame(FrameInterface $fragment) { + if ($this->_frames->isEmpty()) { + $this->binary = $fragment->getOpcode() == Frame::OP_BINARY; + } $this->_frames->push($fragment); return $this; @@ -118,4 +125,12 @@ class Message implements MessageInterface { return $buffer; } + + /** + * @return boolean + */ + public function isBinary() + { + return $this->binary; + } } diff --git a/src/Messaging/Streaming/MessageStreamer.php b/src/Messaging/Streaming/MessageStreamer.php index 2ed1885..9f13957 100644 --- a/src/Messaging/Streaming/MessageStreamer.php +++ b/src/Messaging/Streaming/MessageStreamer.php @@ -19,6 +19,12 @@ class MessageStreamer implements EventEmitterInterface { /** @var array */ private $closeCodes = []; + function __construct() + { + $this->setCloseCodes(); + } + + public function onData($data) { $overflow = ''; @@ -37,6 +43,11 @@ class MessageStreamer implements EventEmitterInterface { if ($frame->isCoalesced()) { $opcode = $frame->getOpcode(); if ($opcode > 2) { + if ($frame->getPayloadLength() > 125) { + // payload only allowed to 125 on control frames ab 2.5 + $this->emit('close', [$frame::CLOSE_PROTOCOL]); + return; + } switch ($opcode) { case $frame::OP_CLOSE: $closeCode = 0;