diff --git a/CHANGELOG.md b/CHANGELOG.md index 32616ae..20a1cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- Allow nekland/tools in 2.0 version (still works with 1.0) ## [2.1.0] - 2018-08-02 ### Changed diff --git a/composer.json b/composer.json index 9792cbf..23394d7 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php": "^7.0", "react/event-loop": "^1.0.0", "react/socket": "^1.0.0", - "nekland/tools": "^1.0", + "nekland/tools": "^1.0 || ^2.0", "psr/log": "^1.0", "react/dns": "^0.4.6" }, diff --git a/src/Server/WebSocketServer.php b/src/Server/WebSocketServer.php index d3823aa..75b1323 100644 --- a/src/Server/WebSocketServer.php +++ b/src/Server/WebSocketServer.php @@ -191,6 +191,7 @@ private function getMessageHandler(string $uri, Connection $connection) return $handler; } + $this->logger->warning('Connection on ' . $uri . ' but no handler found.'); return null; } diff --git a/tests/Woketo/Server/WebSocketServerTest.php b/tests/Woketo/Server/WebSocketServerTest.php index a8c4adb..fbc44f3 100644 --- a/tests/Woketo/Server/WebSocketServerTest.php +++ b/tests/Woketo/Server/WebSocketServerTest.php @@ -17,6 +17,7 @@ use Nekland\Woketo\Message\TextMessageHandler; use Nekland\Woketo\Server\WebSocketServer; use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; use React\EventLoop\LoopInterface; use React\EventLoop\TimerInterface; use React\Socket\ConnectionInterface; @@ -58,6 +59,30 @@ public function testItThrowsErrorOnWrongSslConfig() ]); } + public function testItCallTheConnectionMethodOfHandler() + { + $handler = new class extends TextMessageHandler { + public $called = false; + public function onMessage(string $data, AbstractConnection $connection) {} + + public function onConnection(AbstractConnection $connection) + { + $this->called = true; + } + }; + + $server = new WebSocketServer(1000, '127.0.0.1', ['prod' => false]); + $server->setMessageHandler($handler); + $server->setLoop($this->prophesize(LoopInterface::class)->reveal()); + $server->setSocketServer($socket = new FakeSocketServerForTestMethodHandlerConnection()); + $server->setLogger(new NullLogger()); + $server->start(); + $socket->callCb($co = new ServerReactConnectionMock()); + + $co->emit('data', [self::getHandshake()]); + $this->assertTrue($handler->called); + } + /** * @dataProvider getMessageHandlerTestData */ @@ -129,6 +154,24 @@ public function onMessage(string $data, AbstractConnection $connection){} ] ]; } + + public static function getHandshake() + { + return "GET /foo HTTP/1.1\r\n" + . "Host: 127.0.0.1:8088\r\n" + . "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0\r\n" + . "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + . "Accept-Language: en-US,en;q=0.5\r\n" + . "Accept-Encoding: gzip, deflate\r\n" + . "Sec-WebSocket-Version: 13\r\n" + . "Origin: null\r\n" + . "Sec-WebSocket-Extensions: permessage-deflate\r\n" + . "Sec-WebSocket-Key: nm7Ml8Q7dGJGWWdqnfM7AQ==\r\n" + . "Connection: keep-alive, Upgrade\r\n" + . "Pragma: no-cache\r\n" + . "Cache-Control: no-cache\r\n" + . "Upgrade: websocket\r\n\r\n"; + } } /** @@ -205,3 +248,74 @@ public function stop() {} public function addSignal($signal, $listener) {} public function removeSignal($signal, $listener) {} } + + +class FakeSocketServerForTestMethodHandlerConnection implements ServerInterface +{ + private $cb; + public function callCb(ConnectionInterface $connection) + { + $cb = $this->cb; + $cb($connection); + } + public function on($event, callable $listener) { + $this->cb = $listener; + } + public function once($event, callable $listener) {} + public function removeListener($event, callable $listener) {} + public function removeAllListeners($event = null) {} + public function listeners($event = null) {} + public function emit($event, array $arguments = []) {} + public function getAddress() {} + public function pause() {} + public function resume() {} + public function close() {} +} + + +class ServerReactConnectionMock implements ConnectionInterface +{ + public function __construct() + { + } + + private $on = []; + + public function on($event, callable $listener) + { + $this->on[$event] = $listener; + } + + public function emit($event, array $arguments = []) + { + call_user_func_array($this->on[$event], $arguments); + } + + public function getRemoteAddress() {} + + public function once($event, callable $listener) {} + + public function removeListener($event, callable $listener) {} + + public function removeAllListeners($event = null) {} + + public function listeners($event = null) {} + + public function isReadable(){} + + public function pause() {} + + public function resume() {} + + public function pipe(WritableStreamInterface $dest, array $options = array()) {} + + public function close() {} + + public function isWritable() {} + + public function write($data) {} + + public function end($data = null) {} + + public function getLocalAddress(){} +}