From fc9401f04a3aca5abb22f87ebc210de8afe11d32 Mon Sep 17 00:00:00 2001
From: marvin-borner@live.com
Date: Tue, 10 Apr 2018 21:50:16 +0200
Subject: Initial Commit
---
assets/php/vendor/cboden/ratchet/.gitignore | 5 +
assets/php/vendor/cboden/ratchet/.travis.yml | 20 ++
assets/php/vendor/cboden/ratchet/CHANGELOG.md | 135 ++++++++++
assets/php/vendor/cboden/ratchet/LICENSE | 19 ++
assets/php/vendor/cboden/ratchet/Makefile | 42 +++
assets/php/vendor/cboden/ratchet/README.md | 83 ++++++
assets/php/vendor/cboden/ratchet/composer.json | 36 +++
assets/php/vendor/cboden/ratchet/phpunit.xml.dist | 30 +++
.../src/Ratchet/AbstractConnectionDecorator.php | 41 +++
.../php/vendor/cboden/ratchet/src/Ratchet/App.php | 145 ++++++++++
.../ratchet/src/Ratchet/ComponentInterface.php | 31 +++
.../ratchet/src/Ratchet/ConnectionInterface.php | 26 ++
.../src/Ratchet/Http/CloseResponseTrait.php | 22 ++
.../ratchet/src/Ratchet/Http/HttpRequestParser.php | 64 +++++
.../cboden/ratchet/src/Ratchet/Http/HttpServer.php | 76 ++++++
.../src/Ratchet/Http/HttpServerInterface.php | 14 +
.../src/Ratchet/Http/NoOpHttpServerController.php | 18 ++
.../ratchet/src/Ratchet/Http/OriginCheck.php | 65 +++++
.../cboden/ratchet/src/Ratchet/Http/Router.php | 96 +++++++
.../src/Ratchet/MessageComponentInterface.php | 5 +
.../ratchet/src/Ratchet/MessageInterface.php | 12 +
.../ratchet/src/Ratchet/Server/EchoServer.php | 23 ++
.../ratchet/src/Ratchet/Server/FlashPolicy.php | 200 ++++++++++++++
.../ratchet/src/Ratchet/Server/IoConnection.php | 38 +++
.../cboden/ratchet/src/Ratchet/Server/IoServer.php | 140 ++++++++++
.../ratchet/src/Ratchet/Server/IpBlackList.php | 111 ++++++++
.../Ratchet/Session/Serialize/HandlerInterface.php | 16 ++
.../Ratchet/Session/Serialize/PhpBinaryHandler.php | 33 +++
.../src/Ratchet/Session/Serialize/PhpHandler.php | 49 ++++
.../src/Ratchet/Session/SessionProvider.php | 243 +++++++++++++++++
.../Ratchet/Session/Storage/Proxy/VirtualProxy.php | 54 ++++
.../Session/Storage/VirtualSessionStorage.php | 88 ++++++
.../cboden/ratchet/src/Ratchet/Wamp/Exception.php | 5 +
.../ratchet/src/Ratchet/Wamp/JsonException.php | 31 +++
.../ratchet/src/Ratchet/Wamp/ServerProtocol.php | 161 +++++++++++
.../cboden/ratchet/src/Ratchet/Wamp/Topic.php | 99 +++++++
.../ratchet/src/Ratchet/Wamp/TopicManager.php | 125 +++++++++
.../ratchet/src/Ratchet/Wamp/WampConnection.php | 115 ++++++++
.../cboden/ratchet/src/Ratchet/Wamp/WampServer.php | 67 +++++
.../src/Ratchet/Wamp/WampServerInterface.php | 43 +++
.../ratchet/src/Ratchet/WebSocket/ConnContext.php | 20 ++
.../Ratchet/WebSocket/MessageCallableInterface.php | 8 +
.../WebSocket/MessageComponentInterface.php | 6 +
.../ratchet/src/Ratchet/WebSocket/WsConnection.php | 45 ++++
.../ratchet/src/Ratchet/WebSocket/WsServer.php | 225 ++++++++++++++++
.../src/Ratchet/WebSocket/WsServerInterface.php | 14 +
.../ratchet/tests/autobahn/bin/fuzzingserver.php | 36 +++
.../ratchet/tests/autobahn/fuzzingclient-all.json | 15 ++
.../tests/autobahn/fuzzingclient-profile.json | 12 +
.../tests/autobahn/fuzzingclient-quick.json | 12 +
.../php/vendor/cboden/ratchet/tests/bootstrap.php | 4 +
.../Ratchet/AbstractMessageComponentTestCase.php | 50 ++++
.../tests/helpers/Ratchet/Mock/Component.php | 35 +++
.../tests/helpers/Ratchet/Mock/Connection.php | 20 ++
.../helpers/Ratchet/Mock/ConnectionDecorator.php | 22 ++
.../tests/helpers/Ratchet/Mock/WampComponent.php | 43 +++
.../tests/helpers/Ratchet/NullComponent.php | 28 ++
.../Ratchet/Wamp/Stub/WsWampServerInterface.php | 7 +
.../WebSocket/Stub/WsMessageComponentInterface.php | 7 +
.../tests/unit/AbstractConnectionDecoratorTest.php | 147 ++++++++++
.../tests/unit/Http/HttpRequestParserTest.php | 50 ++++
.../ratchet/tests/unit/Http/HttpServerTest.php | 64 +++++
.../ratchet/tests/unit/Http/OriginCheckTest.php | 46 ++++
.../cboden/ratchet/tests/unit/Http/RouterTest.php | 165 ++++++++++++
.../ratchet/tests/unit/Server/EchoServerTest.php | 26 ++
.../tests/unit/Server/FlashPolicyComponentTest.php | 152 +++++++++++
.../ratchet/tests/unit/Server/IoConnectionTest.php | 32 +++
.../ratchet/tests/unit/Server/IoServerTest.php | 118 +++++++++
.../tests/unit/Server/IpBlackListComponentTest.php | 125 +++++++++
.../unit/Session/Serialize/PhpHandlerTest.php | 43 +++
.../tests/unit/Session/SessionComponentTest.php | 124 +++++++++
.../Storage/VirtualSessionStoragePDOTest.php | 53 ++++
.../ratchet/tests/unit/Wamp/ServerProtocolTest.php | 295 +++++++++++++++++++++
.../ratchet/tests/unit/Wamp/TopicManagerTest.php | 226 ++++++++++++++++
.../cboden/ratchet/tests/unit/Wamp/TopicTest.php | 164 ++++++++++++
.../ratchet/tests/unit/Wamp/WampConnectionTest.php | 77 ++++++
.../ratchet/tests/unit/Wamp/WampServerTest.php | 49 ++++
77 files changed, 5191 insertions(+)
create mode 100644 assets/php/vendor/cboden/ratchet/.gitignore
create mode 100644 assets/php/vendor/cboden/ratchet/.travis.yml
create mode 100644 assets/php/vendor/cboden/ratchet/CHANGELOG.md
create mode 100644 assets/php/vendor/cboden/ratchet/LICENSE
create mode 100644 assets/php/vendor/cboden/ratchet/Makefile
create mode 100644 assets/php/vendor/cboden/ratchet/README.md
create mode 100644 assets/php/vendor/cboden/ratchet/composer.json
create mode 100644 assets/php/vendor/cboden/ratchet/phpunit.xml.dist
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/App.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/ConnectionInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/CloseResponseTrait.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/NoOpHttpServerController.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/OriginCheck.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/MessageInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Server/EchoServer.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpBinaryHandler.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/PhpHandler.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/JsonException.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/ServerProtocol.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/ConnContext.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageComponentInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsConnection.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php
create mode 100644 assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/autobahn/bin/fuzzingserver.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json
create mode 100644 assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json
create mode 100644 assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json
create mode 100644 assets/php/vendor/cboden/ratchet/tests/bootstrap.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Wamp/Stub/WsWampServerInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/WebSocket/Stub/WsMessageComponentInterface.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/AbstractConnectionDecoratorTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php
create mode 100644 assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php
(limited to 'assets/php/vendor/cboden')
diff --git a/assets/php/vendor/cboden/ratchet/.gitignore b/assets/php/vendor/cboden/ratchet/.gitignore
new file mode 100644
index 0000000..793ef58
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/.gitignore
@@ -0,0 +1,5 @@
+phpunit.xml
+reports
+sandbox
+vendor
+composer.lock
\ No newline at end of file
diff --git a/assets/php/vendor/cboden/ratchet/.travis.yml b/assets/php/vendor/cboden/ratchet/.travis.yml
new file mode 100644
index 0000000..6c0dc15
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/.travis.yml
@@ -0,0 +1,20 @@
+language: php
+
+php:
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - hhvm
+
+dist: trusty
+
+matrix:
+ allow_failures:
+ - php: hhvm
+
+before_script:
+ - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then echo "session.serialize_handler = php" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
+ - php -m
+ - composer install --dev --prefer-source
diff --git a/assets/php/vendor/cboden/ratchet/CHANGELOG.md b/assets/php/vendor/cboden/ratchet/CHANGELOG.md
new file mode 100644
index 0000000..5169993
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/CHANGELOG.md
@@ -0,0 +1,135 @@
+CHANGELOG
+=========
+
+### Legend
+
+* "BC": Backwards compatibility break (from public component APIs)
+* "BF": Bug fix
+
+---
+
+* 0.4.1 (2017-12-11)
+ * Only enableKeepAlive in App if no WsServer passed allowing user to set their own timeout duration
+ * Support Symfony 4
+ * BF: Plug NOOP controller in connection from router in case of misbehaving client
+ * BF: Raise error from invalid WAMP payload
+
+* 0.4 (2017-09-14)
+ * BC: $conn->WebSocket->request replaced with $conn->httpRequest which is a PSR-7 object
+ * Binary messages now supported via Ratchet\WebSocket\MessageComponentInterface
+ * Added heartbeat support via ping/pong in WsServer
+ * BC: No longer support old (and insecure) Hixie76 and Hybi protocols
+ * BC: No longer support disabling UTF-8 checks
+ * BC: The Session component implements HttpServerInterface instead of WsServerInterface
+ * BC: PHP 5.3 no longer supported
+ * BC: Update to newer version of react/socket dependency
+ * BC: WAMP topics reduced to 0 subscriptions are deleted, new subs to same name will result in new Topic instance
+ * Significant performance enhancements
+
+* 0.3.6 (2017-01-06)
+ * BF: Keep host and scheme in HTTP request object attatched to connection
+ * BF: Return correct HTTP response (405) when non-GET request made
+
+* 0.3.5 (2016-05-25)
+ * BF: Unmask responding close frame
+ * Added write handler for PHP session serializer
+
+* 0.3.4 (2015-12-23)
+ * BF: Edge case where version check wasn't run on message coalesce
+ * BF: Session didn't start when using pdo_sqlite
+ * BF: WAMP currie prefix check when using '#'
+ * Compatibility with Symfony 3
+
+* 0.3.3 (2015-05-26)
+ * BF: Framing bug on large messages upon TCP fragmentation
+ * BF: Symfony Router query parameter defaults applied to Request
+ * BF: WAMP CURIE on all URIs
+ * OriginCheck rules applied to FlashPolicy
+ * Switched from PSR-0 to PSR-4
+
+* 0.3.2 (2014-06-08)
+ * BF: No messages after closing handshake (fixed rare race condition causing 100% CPU)
+ * BF: Fixed accidental BC break from v0.3.1
+ * Added autoDelete parameter to Topic to destroy when empty of connections
+ * Exposed React Socket on IoServer (allowing FlashPolicy shutdown in App)
+ * Normalized Exceptions in WAMP
+
+* 0.3.1 (2014-05-26)
+ * Added query parameter support to Router, set in HTTP request (ws://server?hello=world)
+ * HHVM compatibility
+ * BF: React/0.4 support; CPU starvation bug fixes
+ * BF: Allow App::route to ignore Host header
+ * Added expected filters to WAMP Topic broadcast method
+ * Resource cleanup in WAMP TopicManager
+
+* 0.3.0 (2013-10-14)
+ * Added the `App` class to help making Ratchet so easy to use it's silly
+ * BC: Require hostname to do HTTP Host header match and do Origin HTTP header check, verify same name by default, helping prevent CSRF attacks
+ * Added Symfony/2.2 based HTTP Router component to allowing for a single Ratchet server to handle multiple apps -> Ratchet\Http\Router
+ * BC: Decoupled HTTP from WebSocket component -> Ratchet\Http\HttpServer
+ * BF: Single sub-protocol selection to conform with RFC6455
+ * BF: Sanity checks on WAMP protocol to prevent errors
+
+* 0.2.8 (2013-09-19)
+ * React 0.3 support
+
+* 0.2.7 (2013-06-09)
+ * BF: Sub-protocol negotation with Guzzle 3.6
+
+* 0.2.6 (2013-06-01)
+ * Guzzle 3.6 support
+
+* 0.2.5 (2013-04-01)
+ * Fixed Hixie-76 handshake bug
+
+* 0.2.4 (2013-03-09)
+ * Support for Symfony 2.2 and Guzzle 2.3
+ * Minor bug fixes when handling errors
+
+* 0.2.3 (2012-11-21)
+ * Bumped dep: Guzzle to v3, React to v0.2.4
+ * More tests
+
+* 0.2.2 (2012-10-20)
+ * Bumped deps to use React v0.2
+
+* 0.2.1 (2012-10-13)
+ * BF: No more UTF-8 warnings in browsers (no longer sending empty sub-protocol string)
+ * Documentation corrections
+ * Using new composer structure
+
+* 0.2 (2012-09-07)
+ * Ratchet passes every non-binary-frame test from the Autobahn Testsuite
+ * Major performance improvements
+ * BC: Renamed "WampServer" to "ServerProtocol"
+ * BC: New "WampServer" component passes Topic container objects of subscribed Connections
+ * Option to turn off UTF-8 checks in order to increase performance
+ * Switched dependency guzzle/guzzle to guzzle/http (no API changes)
+ * mbstring no longer required
+
+* 0.1.5 (2012-07-12)
+ * BF: Error where service wouldn't run on PHP <= 5.3.8
+ * Dependency library updates
+
+* 0.1.4 (2012-06-17)
+ * Fixed dozens of failing AB tests
+ * BF: Proper socket buffer handling
+
+* 0.1.3 (2012-06-15)
+ * Major refactor inside WebSocket protocol handling, more loosley coupled
+ * BF: Proper error handling on failed WebSocket connections
+ * BF: Handle TCP message concatenation
+ * Inclusion of the AutobahnTestSuite checking WebSocket protocol compliance
+ * mb_string now a requirement
+
+* 0.1.2 (2012-05-19)
+ * BC/BF: Updated WAMP API to coincide with the official spec
+ * Tweaks to improve running as a long lived process
+
+* 0.1.1 (2012-05-14)
+ * Separated interfaces allowing WebSockets to support multiple sub protocols
+ * BF: remoteAddress variable on connections returns proper value
+
+* 0.1 (2012-05-11)
+ * First release with components: IoServer, WsServer, SessionProvider, WampServer, FlashPolicy, IpBlackList
+ * I/O now handled by React, making Ratchet fully asynchronous
diff --git a/assets/php/vendor/cboden/ratchet/LICENSE b/assets/php/vendor/cboden/ratchet/LICENSE
new file mode 100644
index 0000000..24abba1
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2017 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.
diff --git a/assets/php/vendor/cboden/ratchet/Makefile b/assets/php/vendor/cboden/ratchet/Makefile
new file mode 100644
index 0000000..a2526c0
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/Makefile
@@ -0,0 +1,42 @@
+# This file is intended to ease the author's development and testing process
+# Users do not need to use `make`; Ratchet does not need to be compiled
+
+test:
+ phpunit
+
+cover:
+ phpunit --coverage-text --coverage-html=reports/coverage
+
+abtests:
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8001 LibEvent &
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8002 StreamSelect &
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8004 LibEv &
+ wstest -m testeeserver -w ws://localhost:8000 &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-all.json
+ killall php wstest
+
+abtest:
+ ulimit -n 2048 && php tests/autobahn/bin/fuzzingserver.php 8000 StreamSelect &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-quick.json
+ killall php
+
+profile:
+ php -d 'xdebug.profiler_enable=1' tests/autobahn/bin/fuzzingserver.php 8000 LibEvent &
+ sleep 1
+ wstest -m fuzzingclient -s tests/autobahn/fuzzingclient-profile.json
+ killall php
+
+apidocs:
+ apigen --title Ratchet -d reports/api \
+ -s src/ \
+ -s vendor/ratchet/rfc6455/src \
+ -s vendor/react/event-loop/src \
+ -s vendor/react/socket/src \
+ -s vendor/react/stream/src \
+ -s vendor/psr/http-message/src \
+ -s vendor/symfony/http-foundation/Session \
+ -s vendor/symfony/routing \
+ -s vendor/evenement/evenement/src/Evenement \
+ --exclude=vendor/symfony/routing/Tests \
diff --git a/assets/php/vendor/cboden/ratchet/README.md b/assets/php/vendor/cboden/ratchet/README.md
new file mode 100644
index 0000000..3f1a345
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/README.md
@@ -0,0 +1,83 @@
+# Ratchet
+
+[](http://travis-ci.org/ratchetphp/Ratchet)
+[](http://socketo.me/reports/ab/index.html)
+[](https://packagist.org/packages/cboden/ratchet)
+
+A PHP library for asynchronously serving WebSockets.
+Build up your application through simple interfaces and re-use your application without changing any of its code just by combining different components.
+
+## Requirements
+
+Shell access is required and root access is recommended.
+To avoid proxy/firewall blockage it's recommended WebSockets are requested on port 80 or 443 (SSL), which requires root access.
+In order to do this, along with your sync web stack, you can either use a reverse proxy or two separate machines.
+You can find more details in the [server conf docs](http://socketo.me/docs/deploy#serverconfiguration).
+
+### Documentation
+
+User and API documentation is available on Ratchet's website: http://socketo.me
+
+See https://github.com/cboden/Ratchet-examples for some out-of-the-box working demos using Ratchet.
+
+Need help? Have a question? Want to provide feedback? Write a message on the [Google Groups Mailing List](https://groups.google.com/forum/#!forum/ratchet-php).
+
+---
+
+### A quick example
+
+```php
+clients = new \SplObjectStorage;
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->clients->attach($conn);
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ foreach ($this->clients as $client) {
+ if ($from != $client) {
+ $client->send($msg);
+ }
+ }
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->clients->detach($conn);
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+}
+
+ // Run the server application through the WebSocket protocol on port 8080
+ $app = new Ratchet\App('localhost', 8080);
+ $app->route('/chat', new MyChat);
+ $app->route('/echo', new Ratchet\Server\EchoServer, array('*'));
+ $app->run();
+```
+
+ $ php chat.php
+
+```javascript
+ // Then some JavaScript in the browser:
+ var conn = new WebSocket('ws://localhost:8080/echo');
+ conn.onmessage = function(e) { console.log(e.data); };
+ conn.onopen = function(e) { conn.send('Hello Me!'); };
+```
diff --git a/assets/php/vendor/cboden/ratchet/composer.json b/assets/php/vendor/cboden/ratchet/composer.json
new file mode 100644
index 0000000..9529618
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/composer.json
@@ -0,0 +1,36 @@
+{
+ "name": "cboden/ratchet"
+ , "type": "library"
+ , "description": "PHP WebSocket library"
+ , "keywords": ["WebSockets", "Server", "Ratchet", "Sockets", "WebSocket"]
+ , "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\\": "src/Ratchet"
+ }
+ }
+ , "require": {
+ "php": ">=5.4.2"
+ , "ratchet/rfc6455": "^0.2"
+ , "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5"
+ , "guzzlehttp/psr7": "^1.0"
+ , "symfony/http-foundation": "^2.6|^3.0|^4.0"
+ , "symfony/routing": "^2.6|^3.0|^4.0"
+ }
+ , "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/phpunit.xml.dist b/assets/php/vendor/cboden/ratchet/phpunit.xml.dist
new file mode 100644
index 0000000..0cc5451
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/phpunit.xml.dist
@@ -0,0 +1,30 @@
+
+
+
+
+
+ ./tests/unit/
+
+
+
+
+
+ ./tests/integration/
+
+
+
+
+
+ ./src/
+
+
+
\ No newline at end of file
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php
new file mode 100644
index 0000000..9707951
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/AbstractConnectionDecorator.php
@@ -0,0 +1,41 @@
+wrappedConn = $conn;
+ }
+
+ /**
+ * @return ConnectionInterface
+ */
+ protected function getConnection() {
+ return $this->wrappedConn;
+ }
+
+ public function __set($name, $value) {
+ $this->wrappedConn->$name = $value;
+ }
+
+ public function __get($name) {
+ return $this->wrappedConn->$name;
+ }
+
+ public function __isset($name) {
+ return isset($this->wrappedConn->$name);
+ }
+
+ public function __unset($name) {
+ unset($this->wrappedConn->$name);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/App.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/App.php
new file mode 100644
index 0000000..f378534
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/App.php
@@ -0,0 +1,145 @@
+httpHost = $httpHost;
+ $this->port = $port;
+
+ $socket = new Reactor($address . ':' . $port, $loop);
+
+ $this->routes = new RouteCollection;
+ $this->_server = new IoServer(new HttpServer(new Router(new UrlMatcher($this->routes, new RequestContext))), $socket, $loop);
+
+ $policy = new FlashPolicy;
+ $policy->addAllowedAccess($httpHost, 80);
+ $policy->addAllowedAccess($httpHost, $port);
+
+ if (80 == $port) {
+ $flashUri = '0.0.0.0:843';
+ } else {
+ $flashUri = 8843;
+ }
+ $flashSock = new Reactor($flashUri, $loop);
+ $this->flashServer = new IoServer($policy, $flashSock);
+ }
+
+ /**
+ * Add an endpoint/application to the server
+ * @param string $path The URI the client will connect to
+ * @param ComponentInterface $controller Your application to server for the route. If not specified, assumed to be for a WebSocket
+ * @param array $allowedOrigins An array of hosts allowed to connect (same host by default), ['*'] for any
+ * @param string $httpHost Override the $httpHost variable provided in the __construct
+ * @return ComponentInterface|WsServer
+ */
+ public function route($path, ComponentInterface $controller, array $allowedOrigins = array(), $httpHost = null) {
+ if ($controller instanceof HttpServerInterface || $controller instanceof WsServer) {
+ $decorated = $controller;
+ } elseif ($controller instanceof WampServerInterface) {
+ $decorated = new WsServer(new WampServer($controller));
+ $decorated->enableKeepAlive($this->_server->loop);
+ } elseif ($controller instanceof MessageComponentInterface) {
+ $decorated = new WsServer($controller);
+ $decorated->enableKeepAlive($this->_server->loop);
+ } else {
+ $decorated = $controller;
+ }
+
+ if ($httpHost === null) {
+ $httpHost = $this->httpHost;
+ }
+
+ $allowedOrigins = array_values($allowedOrigins);
+ if (0 === count($allowedOrigins)) {
+ $allowedOrigins[] = $httpHost;
+ }
+ if ('*' !== $allowedOrigins[0]) {
+ $decorated = new OriginCheck($decorated, $allowedOrigins);
+ }
+
+ //allow origins in flash policy server
+ if(empty($this->flashServer) === false) {
+ foreach($allowedOrigins as $allowedOrgin) {
+ $this->flashServer->app->addAllowedAccess($allowedOrgin, $this->port);
+ }
+ }
+
+ $this->routes->add('rr-' . ++$this->_routeCounter, new Route($path, array('_controller' => $decorated), array('Origin' => $this->httpHost), array(), $httpHost, array(), array('GET')));
+
+ return $decorated;
+ }
+
+ /**
+ * Run the server by entering the event loop
+ */
+ public function run() {
+ $this->_server->run();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php
new file mode 100644
index 0000000..37e41b1
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/ComponentInterface.php
@@ -0,0 +1,31 @@
+ \Ratchet\VERSION
+ ], $additional_headers));
+
+ $conn->send(gPsr\str($response));
+ $conn->close();
+ }
+}
\ No newline at end of file
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php
new file mode 100644
index 0000000..9c44114
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpRequestParser.php
@@ -0,0 +1,64 @@
+httpBuffer)) {
+ $context->httpBuffer = '';
+ }
+
+ $context->httpBuffer .= $data;
+
+ if (strlen($context->httpBuffer) > (int)$this->maxSize) {
+ throw new \OverflowException("Maximum buffer size of {$this->maxSize} exceeded parsing HTTP header");
+ }
+
+ if ($this->isEom($context->httpBuffer)) {
+ $request = $this->parse($context->httpBuffer);
+
+ unset($context->httpBuffer);
+
+ return $request;
+ }
+ }
+
+ /**
+ * Determine if the message has been buffered as per the HTTP specification
+ * @param string $message
+ * @return boolean
+ */
+ public function isEom($message) {
+ return (boolean)strpos($message, static::EOM);
+ }
+
+ /**
+ * @param string $headers
+ * @return \Psr\Http\Message\RequestInterface
+ */
+ public function parse($headers) {
+ return gPsr\parse_request($headers);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php
new file mode 100644
index 0000000..bbd8d53
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServer.php
@@ -0,0 +1,76 @@
+_httpServer = $component;
+ $this->_reqParser = new HttpRequestParser;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $conn->httpHeadersReceived = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if (true !== $from->httpHeadersReceived) {
+ try {
+ if (null === ($request = $this->_reqParser->onMessage($from, $msg))) {
+ return;
+ }
+ } catch (\OverflowException $oe) {
+ return $this->close($from, 413);
+ }
+
+ $from->httpHeadersReceived = true;
+
+ return $this->_httpServer->onOpen($from, $request);
+ }
+
+ $this->_httpServer->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if ($conn->httpHeadersReceived) {
+ $this->_httpServer->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if ($conn->httpHeadersReceived) {
+ $this->_httpServer->onError($conn, $e);
+ } else {
+ $this->close($conn, 500);
+ }
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php
new file mode 100644
index 0000000..2c37c49
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/HttpServerInterface.php
@@ -0,0 +1,14 @@
+_component = $component;
+ $this->allowedOrigins += $allowed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ $header = (string)$request->getHeader('Origin')[0];
+ $origin = parse_url($header, PHP_URL_HOST) ?: $header;
+
+ if (!in_array($origin, $this->allowedOrigins)) {
+ return $this->close($conn, 403);
+ }
+
+ return $this->_component->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_component->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ return $this->_component->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_component->onError($conn, $e);
+ }
+}
\ No newline at end of file
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php
new file mode 100644
index 0000000..df7fe82
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Http/Router.php
@@ -0,0 +1,96 @@
+_matcher = $matcher;
+ $this->_noopController = new NoOpHttpServerController;
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ if (null === $request) {
+ throw new \UnexpectedValueException('$request can not be null');
+ }
+
+ $conn->controller = $this->_noopController;
+
+ $uri = $request->getUri();
+
+ $context = $this->_matcher->getContext();
+ $context->setMethod($request->getMethod());
+ $context->setHost($uri->getHost());
+
+ try {
+ $route = $this->_matcher->match($uri->getPath());
+ } catch (MethodNotAllowedException $nae) {
+ return $this->close($conn, 405, array('Allow' => $nae->getAllowedMethods()));
+ } catch (ResourceNotFoundException $nfe) {
+ return $this->close($conn, 404);
+ }
+
+ if (is_string($route['_controller']) && class_exists($route['_controller'])) {
+ $route['_controller'] = new $route['_controller'];
+ }
+
+ if (!($route['_controller'] instanceof HttpServerInterface)) {
+ throw new \UnexpectedValueException('All routes must implement Ratchet\Http\HttpServerInterface');
+ }
+
+ $parameters = [];
+ foreach($route as $key => $value) {
+ if ((is_string($key)) && ('_' !== substr($key, 0, 1))) {
+ $parameters[$key] = $value;
+ }
+ }
+ $parameters = array_merge($parameters, gPsr\parse_query($uri->getQuery() ?: ''));
+
+ $request = $request->withUri($uri->withQuery(gPsr\build_query($parameters)));
+
+ $conn->controller = $route['_controller'];
+ $conn->controller->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $from->controller->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if (isset($conn->controller)) {
+ $conn->controller->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if (isset($conn->controller)) {
+ $conn->controller->onError($conn, $e);
+ }
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php
new file mode 100644
index 0000000..b4a92e2
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/MessageComponentInterface.php
@@ -0,0 +1,5 @@
+send($msg);
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php
new file mode 100644
index 0000000..4a1b8bd
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/FlashPolicy.php
@@ -0,0 +1,200 @@
+';
+
+ /**
+ * Stores an array of allowed domains and their ports
+ * @var array
+ */
+ protected $_access = array();
+
+ /**
+ * @var string
+ */
+ protected $_siteControl = '';
+
+ /**
+ * @var string
+ */
+ protected $_cache = '';
+
+ /**
+ * @var string
+ */
+ protected $_cacheValid = false;
+
+ /**
+ * Add a domain to an allowed access list.
+ *
+ * @param string $domain Specifies a requesting domain to be granted access. Both named domains and IP
+ * addresses are acceptable values. Subdomains are considered different domains. A wildcard (*) can
+ * be used to match all domains when used alone, or multiple domains (subdomains) when used as a
+ * prefix for an explicit, second-level domain name separated with a dot (.)
+ * @param string $ports A comma-separated list of ports or range of ports that a socket connection
+ * is allowed to connect to. A range of ports is specified through a dash (-) between two port numbers.
+ * Ranges can be used with individual ports when separated with a comma. A single wildcard (*) can
+ * be used to allow all ports.
+ * @param bool $secure
+ * @throws \UnexpectedValueException
+ * @return FlashPolicy
+ */
+ public function addAllowedAccess($domain, $ports = '*', $secure = false) {
+ if (!$this->validateDomain($domain)) {
+ throw new \UnexpectedValueException('Invalid domain');
+ }
+
+ if (!$this->validatePorts($ports)) {
+ throw new \UnexpectedValueException('Invalid Port');
+ }
+
+ $this->_access[] = array($domain, $ports, (boolean)$secure);
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * Removes all domains from the allowed access list.
+ *
+ * @return \Ratchet\Server\FlashPolicy
+ */
+ public function clearAllowedAccess() {
+ $this->_access = array();
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * site-control defines the meta-policy for the current domain. A meta-policy specifies acceptable
+ * domain policy files other than the master policy file located in the target domain's root and named
+ * crossdomain.xml.
+ *
+ * @param string $permittedCrossDomainPolicies
+ * @throws \UnexpectedValueException
+ * @return FlashPolicy
+ */
+ public function setSiteControl($permittedCrossDomainPolicies = 'all') {
+ if (!$this->validateSiteControl($permittedCrossDomainPolicies)) {
+ throw new \UnexpectedValueException('Invalid site control set');
+ }
+
+ $this->_siteControl = $permittedCrossDomainPolicies;
+ $this->_cacheValid = false;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if (!$this->_cacheValid) {
+ $this->_cache = $this->renderPolicy()->asXML();
+ $this->_cacheValid = true;
+ }
+
+ $from->send($this->_cache . "\0");
+ $from->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $conn->close();
+ }
+
+ /**
+ * Builds the crossdomain file based on the template policy
+ *
+ * @throws \UnexpectedValueException
+ * @return \SimpleXMLElement
+ */
+ public function renderPolicy() {
+ $policy = new \SimpleXMLElement($this->_policy);
+
+ $siteControl = $policy->addChild('site-control');
+
+ if ($this->_siteControl == '') {
+ $this->setSiteControl();
+ }
+
+ $siteControl->addAttribute('permitted-cross-domain-policies', $this->_siteControl);
+
+ if (empty($this->_access)) {
+ throw new \UnexpectedValueException('You must add a domain through addAllowedAccess()');
+ }
+
+ foreach ($this->_access as $access) {
+ $tmp = $policy->addChild('allow-access-from');
+ $tmp->addAttribute('domain', $access[0]);
+ $tmp->addAttribute('to-ports', $access[1]);
+ $tmp->addAttribute('secure', ($access[2] === true) ? 'true' : 'false');
+ }
+
+ return $policy;
+ }
+
+ /**
+ * Make sure the proper site control was passed
+ *
+ * @param string $permittedCrossDomainPolicies
+ * @return bool
+ */
+ public function validateSiteControl($permittedCrossDomainPolicies) {
+ //'by-content-type' and 'by-ftp-filename' are not available for sockets
+ return (bool)in_array($permittedCrossDomainPolicies, array('none', 'master-only', 'all'));
+ }
+
+ /**
+ * Validate for proper domains (wildcards allowed)
+ *
+ * @param string $domain
+ * @return bool
+ */
+ public function validateDomain($domain) {
+ return (bool)preg_match("/^((http(s)?:\/\/)?([a-z0-9-_]+\.|\*\.)*([a-z0-9-_\.]+)|\*)$/i", $domain);
+ }
+
+ /**
+ * Make sure valid ports were passed
+ *
+ * @param string $port
+ * @return bool
+ */
+ public function validatePorts($port) {
+ return (bool)preg_match('/^(\*|(\d+[,-]?)*\d+)$/', $port);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php
new file mode 100644
index 0000000..9f864bb
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoConnection.php
@@ -0,0 +1,38 @@
+conn = $conn;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function send($data) {
+ $this->conn->write($data);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close() {
+ $this->conn->end();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php
new file mode 100644
index 0000000..b3fb7e0
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php
@@ -0,0 +1,140 @@
+loop = $loop;
+ $this->app = $app;
+ $this->socket = $socket;
+
+ $socket->on('connection', array($this, 'handleConnect'));
+ }
+
+ /**
+ * @param \Ratchet\MessageComponentInterface $component The application that I/O will call when events are received
+ * @param int $port The port to server sockets on
+ * @param string $address The address to receive sockets on (0.0.0.0 means receive connections from any)
+ * @return IoServer
+ */
+ public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0') {
+ $loop = LoopFactory::create();
+ $socket = new Reactor($address . ':' . $port, $loop);
+
+ return new static($component, $socket, $loop);
+ }
+
+ /**
+ * Run the application by entering the event loop
+ * @throws \RuntimeException If a loop was not previously specified
+ */
+ public function run() {
+ if (null === $this->loop) {
+ throw new \RuntimeException("A React Loop was not provided during instantiation");
+ }
+
+ // @codeCoverageIgnoreStart
+ $this->loop->run();
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * Triggered when a new connection is received from React
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleConnect($conn) {
+ $conn->decor = new IoConnection($conn);
+ $conn->decor->resourceId = (int)$conn->stream;
+
+ $uri = $conn->getRemoteAddress();
+ $conn->decor->remoteAddress = trim(
+ parse_url((strpos($uri, '://') === false ? 'tcp://' : '') . $uri, PHP_URL_HOST),
+ '[]'
+ );
+
+ $this->app->onOpen($conn->decor);
+
+ $conn->on('data', function ($data) use ($conn) {
+ $this->handleData($data, $conn);
+ });
+ $conn->on('close', function () use ($conn) {
+ $this->handleEnd($conn);
+ });
+ $conn->on('error', function (\Exception $e) use ($conn) {
+ $this->handleError($e, $conn);
+ });
+ }
+
+ /**
+ * Data has been received from React
+ * @param string $data
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleData($data, $conn) {
+ try {
+ $this->app->onMessage($conn->decor, $data);
+ } catch (\Exception $e) {
+ $this->handleError($e, $conn);
+ }
+ }
+
+ /**
+ * A connection has been closed by React
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleEnd($conn) {
+ try {
+ $this->app->onClose($conn->decor);
+ } catch (\Exception $e) {
+ $this->handleError($e, $conn);
+ }
+
+ unset($conn->decor);
+ }
+
+ /**
+ * An error has occurred, let the listening application know
+ * @param \Exception $e
+ * @param \React\Socket\ConnectionInterface $conn
+ */
+ public function handleError(\Exception $e, $conn) {
+ $this->app->onError($conn->decor, $e);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php
new file mode 100644
index 0000000..9342254
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Server/IpBlackList.php
@@ -0,0 +1,111 @@
+_decorating = $component;
+ }
+
+ /**
+ * Add an address to the blacklist that will not be allowed to connect to your application
+ * @param string $ip IP address to block from connecting to your application
+ * @return IpBlackList
+ */
+ public function blockAddress($ip) {
+ $this->_blacklist[$ip] = true;
+
+ return $this;
+ }
+
+ /**
+ * Unblock an address so they can access your application again
+ * @param string $ip IP address to unblock from connecting to your application
+ * @return IpBlackList
+ */
+ public function unblockAddress($ip) {
+ if (isset($this->_blacklist[$this->filterAddress($ip)])) {
+ unset($this->_blacklist[$this->filterAddress($ip)]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $address
+ * @return bool
+ */
+ public function isBlocked($address) {
+ return (isset($this->_blacklist[$this->filterAddress($address)]));
+ }
+
+ /**
+ * Get an array of all the addresses blocked
+ * @return array
+ */
+ public function getBlockedAddresses() {
+ return array_keys($this->_blacklist);
+ }
+
+ /**
+ * @param string $address
+ * @return string
+ */
+ public function filterAddress($address) {
+ if (strstr($address, ':') && substr_count($address, '.') == 3) {
+ list($address, $port) = explode(':', $address);
+ }
+
+ return $address;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onOpen(ConnectionInterface $conn) {
+ if ($this->isBlocked($conn->remoteAddress)) {
+ return $conn->close();
+ }
+
+ return $this->_decorating->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_decorating->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ if (!$this->isBlocked($conn->remoteAddress)) {
+ $this->_decorating->onClose($conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ if (!$this->isBlocked($conn->remoteAddress)) {
+ $this->_decorating->onError($conn, $e);
+ }
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php
new file mode 100644
index 0000000..b83635f
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Serialize/HandlerInterface.php
@@ -0,0 +1,16 @@
+ $bucketData) {
+ $preSerialized[] = $bucket . '|' . serialize($bucketData);
+ }
+ $serialized = implode('', $preSerialized);
+ }
+
+ return $serialized;
+ }
+
+ /**
+ * {@inheritdoc}
+ * @link http://ca2.php.net/manual/en/function.session-decode.php#108037 Code from this comment on php.net
+ * @throws \UnexpectedValueException If there is a problem parsing the data
+ */
+ public function unserialize($raw) {
+ $returnData = array();
+ $offset = 0;
+
+ while ($offset < strlen($raw)) {
+ if (!strstr(substr($raw, $offset), "|")) {
+ throw new \UnexpectedValueException("invalid data, remaining: " . substr($raw, $offset));
+ }
+
+ $pos = strpos($raw, "|", $offset);
+ $num = $pos - $offset;
+ $varname = substr($raw, $offset, $num);
+ $offset += $num + 1;
+ $data = unserialize(substr($raw, $offset));
+
+ $returnData[$varname] = $data;
+ $offset += strlen(serialize($data));
+ }
+
+ return $returnData;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php
new file mode 100644
index 0000000..44276c5
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/SessionProvider.php
@@ -0,0 +1,243 @@
+_app = $app;
+ $this->_handler = $handler;
+ $this->_null = new NullSessionHandler;
+
+ ini_set('session.auto_start', 0);
+ ini_set('session.cache_limiter', '');
+ ini_set('session.use_cookies', 0);
+
+ $this->setOptions($options);
+
+ if (null === $serializer) {
+ $serialClass = __NAMESPACE__ . "\\Serialize\\{$this->toClassCase(ini_get('session.serialize_handler'))}Handler"; // awesome/terrible hack, eh?
+ if (!class_exists($serialClass)) {
+ throw new \RuntimeException('Unable to parse session serialize handler');
+ }
+
+ $serializer = new $serialClass;
+ }
+
+ $this->_serializer = $serializer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ $sessionName = ini_get('session.name');
+
+ $id = array_reduce($request->getHeader('Cookie'), function($accumulator, $cookie) use ($sessionName) {
+ if ($accumulator) {
+ return $accumulator;
+ }
+
+ $crumbs = $this->parseCookie($cookie);
+
+ return isset($crumbs['cookies'][$sessionName]) ? $crumbs['cookies'][$sessionName] : false;
+ }, false);
+
+ if (null === $request || false === $id) {
+ $saveHandler = $this->_null;
+ $id = '';
+ } else {
+ $saveHandler = $this->_handler;
+ }
+
+ $conn->Session = new Session(new VirtualSessionStorage($saveHandler, $id, $this->_serializer));
+
+ if (ini_get('session.auto_start')) {
+ $conn->Session->start();
+ }
+
+ return $this->_app->onOpen($conn, $request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onMessage(ConnectionInterface $from, $msg) {
+ return $this->_app->onMessage($from, $msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onClose(ConnectionInterface $conn) {
+ // "close" session for Connection
+
+ return $this->_app->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_app->onError($conn, $e);
+ }
+
+ /**
+ * Set all the php session. ini options
+ * © Symfony
+ * @param array $options
+ * @return array
+ */
+ protected function setOptions(array $options) {
+ $all = array(
+ 'auto_start', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
+ 'cookie_lifetime', 'cookie_path', 'cookie_secure',
+ 'entropy_file', 'entropy_length', 'gc_divisor',
+ 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
+ 'hash_function', 'name', 'referer_check',
+ 'serialize_handler', 'use_cookies',
+ 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
+ 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
+ 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'
+ );
+
+ foreach ($all as $key) {
+ if (!array_key_exists($key, $options)) {
+ $options[$key] = ini_get("session.{$key}");
+ } else {
+ ini_set("session.{$key}", $options[$key]);
+ }
+ }
+
+ return $options;
+ }
+
+ /**
+ * @param string $langDef Input to convert
+ * @return string
+ */
+ protected function toClassCase($langDef) {
+ return str_replace(' ', '', ucwords(str_replace('_', ' ', $langDef)));
+ }
+
+ /**
+ * Taken from Guzzle3
+ */
+ private static $cookieParts = array(
+ 'domain' => 'Domain',
+ 'path' => 'Path',
+ 'max_age' => 'Max-Age',
+ 'expires' => 'Expires',
+ 'version' => 'Version',
+ 'secure' => 'Secure',
+ 'port' => 'Port',
+ 'discard' => 'Discard',
+ 'comment' => 'Comment',
+ 'comment_url' => 'Comment-Url',
+ 'http_only' => 'HttpOnly'
+ );
+
+ /**
+ * Taken from Guzzle3
+ */
+ private function parseCookie($cookie, $host = null, $path = null, $decode = false) {
+ // Explode the cookie string using a series of semicolons
+ $pieces = array_filter(array_map('trim', explode(';', $cookie)));
+
+ // The name of the cookie (first kvp) must include an equal sign.
+ if (empty($pieces) || !strpos($pieces[0], '=')) {
+ return false;
+ }
+
+ // Create the default return array
+ $data = array_merge(array_fill_keys(array_keys(self::$cookieParts), null), array(
+ 'cookies' => array(),
+ 'data' => array(),
+ 'path' => $path ?: '/',
+ 'http_only' => false,
+ 'discard' => false,
+ 'domain' => $host
+ ));
+ $foundNonCookies = 0;
+
+ // Add the cookie pieces into the parsed data array
+ foreach ($pieces as $part) {
+
+ $cookieParts = explode('=', $part, 2);
+ $key = trim($cookieParts[0]);
+
+ if (count($cookieParts) == 1) {
+ // Can be a single value (e.g. secure, httpOnly)
+ $value = true;
+ } else {
+ // Be sure to strip wrapping quotes
+ $value = trim($cookieParts[1], " \n\r\t\0\x0B\"");
+ if ($decode) {
+ $value = urldecode($value);
+ }
+ }
+
+ // Only check for non-cookies when cookies have been found
+ if (!empty($data['cookies'])) {
+ foreach (self::$cookieParts as $mapValue => $search) {
+ if (!strcasecmp($search, $key)) {
+ $data[$mapValue] = $mapValue == 'port' ? array_map('trim', explode(',', $value)) : $value;
+ $foundNonCookies++;
+ continue 2;
+ }
+ }
+ }
+
+ // If cookies have not yet been retrieved, or this value was not found in the pieces array, treat it as a
+ // cookie. IF non-cookies have been parsed, then this isn't a cookie, it's cookie data. Cookies then data.
+ $data[$foundNonCookies ? 'data' : 'cookies'][$key] = $value;
+ }
+
+ // Calculate the expires date
+ if (!$data['expires'] && $data['max_age']) {
+ $data['expires'] = time() + (int) $data['max_age'];
+ }
+
+ return $data;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php
new file mode 100644
index 0000000..b478d03
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/Proxy/VirtualProxy.php
@@ -0,0 +1,54 @@
+saveHandlerName = 'user';
+ $this->_sessionName = ini_get('session.name');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId() {
+ return $this->_sessionId;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id) {
+ $this->_sessionId = $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName() {
+ return $this->_sessionName;
+ }
+
+ /**
+ * DO NOT CALL THIS METHOD
+ * @internal
+ */
+ public function setName($name) {
+ throw new \RuntimeException("Can not change session name in VirtualProxy");
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php
new file mode 100644
index 0000000..daa10bb
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Session/Storage/VirtualSessionStorage.php
@@ -0,0 +1,88 @@
+setSaveHandler($handler);
+ $this->saveHandler->setId($sessionId);
+ $this->_serializer = $serializer;
+ $this->setMetadataBag(null);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start() {
+ if ($this->started && !$this->closed) {
+ return true;
+ }
+
+ // You have to call Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::open() to use
+ // pdo_sqlite (and possible pdo_*) as session storage, if you are using a DSN string instead of a \PDO object
+ // in the constructor. The method arguments are filled with the values, which are also used by the symfony
+ // framework in this case. This must not be the best choice, but it works.
+ $this->saveHandler->open(session_save_path(), session_name());
+
+ $rawData = $this->saveHandler->read($this->saveHandler->getId());
+ $sessionData = $this->_serializer->unserialize($rawData);
+
+ $this->loadSession($sessionData);
+
+ if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false, $lifetime = null) {
+ // .. ?
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save() {
+ // get the data from the bags?
+ // serialize the data
+ // save the data using the saveHandler
+// $this->saveHandler->write($this->saveHandler->getId(),
+
+ if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ $this->closed = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setSaveHandler($saveHandler = null) {
+ if (!($saveHandler instanceof \SessionHandlerInterface)) {
+ throw new \InvalidArgumentException('Handler must be instance of SessionHandlerInterface');
+ }
+
+ if (!($saveHandler instanceof VirtualProxy)) {
+ $saveHandler = new VirtualProxy($saveHandler);
+ }
+
+ $this->saveHandler = $saveHandler;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php
new file mode 100644
index 0000000..6c824da
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Exception.php
@@ -0,0 +1,5 @@
+_decorating = $serverComponent;
+ $this->connections = new \SplObjectStorage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ if ($this->_decorating instanceof WsServerInterface) {
+ $subs = $this->_decorating->getSubProtocols();
+ $subs[] = 'wamp';
+
+ return $subs;
+ }
+
+ return ['wamp'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $decor = new WampConnection($conn);
+ $this->connections->attach($conn, $decor);
+
+ $this->_decorating->onOpen($decor);
+ }
+
+ /**
+ * {@inheritdoc}
+ * @throws \Ratchet\Wamp\Exception
+ * @throws \Ratchet\Wamp\JsonException
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $from = $this->connections[$from];
+
+ if (null === ($json = @json_decode($msg, true))) {
+ throw new JsonException;
+ }
+
+ if (!is_array($json) || $json !== array_values($json)) {
+ throw new Exception("Invalid WAMP message format");
+ }
+
+ if (isset($json[1]) && !(is_string($json[1]) || is_numeric($json[1]))) {
+ throw new Exception('Invalid Topic, must be a string');
+ }
+
+ switch ($json[0]) {
+ case static::MSG_PREFIX:
+ $from->WAMP->prefixes[$json[1]] = $json[2];
+ break;
+
+ case static::MSG_CALL:
+ array_shift($json);
+ $callID = array_shift($json);
+ $procURI = array_shift($json);
+
+ if (count($json) == 1 && is_array($json[0])) {
+ $json = $json[0];
+ }
+
+ $this->_decorating->onCall($from, $callID, $from->getUri($procURI), $json);
+ break;
+
+ case static::MSG_SUBSCRIBE:
+ $this->_decorating->onSubscribe($from, $from->getUri($json[1]));
+ break;
+
+ case static::MSG_UNSUBSCRIBE:
+ $this->_decorating->onUnSubscribe($from, $from->getUri($json[1]));
+ break;
+
+ case static::MSG_PUBLISH:
+ $exclude = (array_key_exists(3, $json) ? $json[3] : null);
+ if (!is_array($exclude)) {
+ if (true === (boolean)$exclude) {
+ $exclude = [$from->WAMP->sessionId];
+ } else {
+ $exclude = [];
+ }
+ }
+
+ $eligible = (array_key_exists(4, $json) ? $json[4] : []);
+
+ $this->_decorating->onPublish($from, $from->getUri($json[1]), $json[2], $exclude, $eligible);
+ break;
+
+ default:
+ throw new Exception('Invalid WAMP message type');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $decor = $this->connections[$conn];
+ $this->connections->detach($conn);
+
+ $this->_decorating->onClose($decor);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ return $this->_decorating->onError($this->connections[$conn], $e);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php
new file mode 100644
index 0000000..bca8f67
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/Topic.php
@@ -0,0 +1,99 @@
+id = $topicId;
+ $this->subscribers = new \SplObjectStorage;
+ }
+
+ /**
+ * @return string
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ public function __toString() {
+ return $this->getId();
+ }
+
+ /**
+ * Send a message to all the connections in this topic
+ * @param string|array $msg Payload to publish
+ * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
+ * @param array $eligible A list of session Ids the message should be send to (whitelist)
+ * @return Topic The same Topic object to chain
+ */
+ public function broadcast($msg, array $exclude = array(), array $eligible = array()) {
+ $useEligible = (bool)count($eligible);
+ foreach ($this->subscribers as $client) {
+ if (in_array($client->WAMP->sessionId, $exclude)) {
+ continue;
+ }
+
+ if ($useEligible && !in_array($client->WAMP->sessionId, $eligible)) {
+ continue;
+ }
+
+ $client->event($this->id, $msg);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return boolean
+ */
+ public function has(ConnectionInterface $conn) {
+ return $this->subscribers->contains($conn);
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return Topic
+ */
+ public function add(ConnectionInterface $conn) {
+ $this->subscribers->attach($conn);
+
+ return $this;
+ }
+
+ /**
+ * @param WampConnection $conn
+ * @return Topic
+ */
+ public function remove(ConnectionInterface $conn) {
+ if ($this->subscribers->contains($conn)) {
+ $this->subscribers->detach($conn);
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator() {
+ return $this->subscribers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function count() {
+ return $this->subscribers->count();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php
new file mode 100644
index 0000000..dd06ada
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/TopicManager.php
@@ -0,0 +1,125 @@
+app = $app;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $conn->WAMP->subscriptions = new \SplObjectStorage;
+ $this->app->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
+ $this->app->onCall($conn, $id, $this->getTopic($topic), $params);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onSubscribe(ConnectionInterface $conn, $topic) {
+ $topicObj = $this->getTopic($topic);
+
+ if ($conn->WAMP->subscriptions->contains($topicObj)) {
+ return;
+ }
+
+ $this->topicLookup[$topic]->add($conn);
+ $conn->WAMP->subscriptions->attach($topicObj);
+ $this->app->onSubscribe($conn, $topicObj);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onUnsubscribe(ConnectionInterface $conn, $topic) {
+ $topicObj = $this->getTopic($topic);
+
+ if (!$conn->WAMP->subscriptions->contains($topicObj)) {
+ return;
+ }
+
+ $this->cleanTopic($topicObj, $conn);
+
+ $this->app->onUnsubscribe($conn, $topicObj);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
+ $this->app->onPublish($conn, $this->getTopic($topic), $event, $exclude, $eligible);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $this->app->onClose($conn);
+
+ foreach ($this->topicLookup as $topic) {
+ $this->cleanTopic($topic, $conn);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->app->onError($conn, $e);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ if ($this->app instanceof WsServerInterface) {
+ return $this->app->getSubProtocols();
+ }
+
+ return array();
+ }
+
+ /**
+ * @param string
+ * @return Topic
+ */
+ protected function getTopic($topic) {
+ if (!array_key_exists($topic, $this->topicLookup)) {
+ $this->topicLookup[$topic] = new Topic($topic);
+ }
+
+ return $this->topicLookup[$topic];
+ }
+
+ protected function cleanTopic(Topic $topic, ConnectionInterface $conn) {
+ if ($conn->WAMP->subscriptions->contains($topic)) {
+ $conn->WAMP->subscriptions->detach($topic);
+ }
+
+ $this->topicLookup[$topic->getId()]->remove($conn);
+
+ if (0 === $topic->count()) {
+ unset($this->topicLookup[$topic->getId()]);
+ }
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php
new file mode 100644
index 0000000..dda1e4e
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampConnection.php
@@ -0,0 +1,115 @@
+WAMP = new \StdClass;
+ $this->WAMP->sessionId = str_replace('.', '', uniqid(mt_rand(), true));
+ $this->WAMP->prefixes = array();
+
+ $this->send(json_encode(array(WAMP::MSG_WELCOME, $this->WAMP->sessionId, 1, \Ratchet\VERSION)));
+ }
+
+ /**
+ * Successfully respond to a call made by the client
+ * @param string $id The unique ID given by the client to respond to
+ * @param array $data an object or array
+ * @return WampConnection
+ */
+ public function callResult($id, $data = array()) {
+ return $this->send(json_encode(array(WAMP::MSG_CALL_RESULT, $id, $data)));
+ }
+
+ /**
+ * Respond with an error to a client call
+ * @param string $id The unique ID given by the client to respond to
+ * @param string $errorUri The URI given to identify the specific error
+ * @param string $desc A developer-oriented description of the error
+ * @param string $details An optional human readable detail message to send back
+ * @return WampConnection
+ */
+ public function callError($id, $errorUri, $desc = '', $details = null) {
+ if ($errorUri instanceof Topic) {
+ $errorUri = (string)$errorUri;
+ }
+
+ $data = array(WAMP::MSG_CALL_ERROR, $id, $errorUri, $desc);
+
+ if (null !== $details) {
+ $data[] = $details;
+ }
+
+ return $this->send(json_encode($data));
+ }
+
+ /**
+ * @param string $topic The topic to broadcast to
+ * @param mixed $msg Data to send with the event. Anything that is json'able
+ * @return WampConnection
+ */
+ public function event($topic, $msg) {
+ return $this->send(json_encode(array(WAMP::MSG_EVENT, (string)$topic, $msg)));
+ }
+
+ /**
+ * @param string $curie
+ * @param string $uri
+ * @return WampConnection
+ */
+ public function prefix($curie, $uri) {
+ $this->WAMP->prefixes[$curie] = (string)$uri;
+
+ return $this->send(json_encode(array(WAMP::MSG_PREFIX, $curie, (string)$uri)));
+ }
+
+ /**
+ * Get the full request URI from the connection object if a prefix has been established for it
+ * @param string $uri
+ * @return string
+ */
+ public function getUri($uri) {
+ $curieSeperator = ':';
+
+ if (preg_match('/http(s*)\:\/\//', $uri) == false) {
+ if (strpos($uri, $curieSeperator) !== false) {
+ list($prefix, $action) = explode($curieSeperator, $uri);
+
+ if(isset($this->WAMP->prefixes[$prefix]) === true){
+ return $this->WAMP->prefixes[$prefix] . '#' . $action;
+ }
+ }
+ }
+
+ return $uri;
+ }
+
+ /**
+ * @internal
+ */
+ public function send($data) {
+ $this->getConnection()->send($data);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close($opt = null) {
+ $this->getConnection()->close($opt);
+ }
+
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php
new file mode 100644
index 0000000..5d710aa
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServer.php
@@ -0,0 +1,67 @@
+wampProtocol = new ServerProtocol(new TopicManager($app));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn) {
+ $this->wampProtocol->onOpen($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $conn, $msg) {
+ try {
+ $this->wampProtocol->onMessage($conn, $msg);
+ } catch (Exception $we) {
+ $conn->close(1007);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ $this->wampProtocol->onClose($conn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->wampProtocol->onError($conn, $e);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSubProtocols() {
+ return $this->wampProtocol->getSubProtocols();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php
new file mode 100644
index 0000000..15c521d
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/Wamp/WampServerInterface.php
@@ -0,0 +1,43 @@
+connection = $conn;
+ $this->buffer = $buffer;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php
new file mode 100644
index 0000000..b5c094e
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/MessageCallableInterface.php
@@ -0,0 +1,8 @@
+WebSocket->closing) {
+ if (!($msg instanceof DataInterface)) {
+ $msg = new Frame($msg);
+ }
+
+ $this->getConnection()->send($msg->getContents());
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param int|\Ratchet\RFC6455\Messaging\DataInterface
+ */
+ public function close($code = 1000) {
+ if ($this->WebSocket->closing) {
+ return;
+ }
+
+ if ($code instanceof DataInterface) {
+ $this->send($code);
+ } else {
+ $this->send(new Frame(pack('n', $code), true, Frame::OP_CLOSE));
+ }
+
+ $this->getConnection()->close();
+
+ $this->WebSocket->closing = true;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php
new file mode 100644
index 0000000..8030604
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServer.php
@@ -0,0 +1,225 @@
+msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {
+ $this->delegate->onMessage($conn, $msg);
+ };
+ } elseif ($component instanceof DataComponentInterface) {
+ $this->msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {
+ $this->delegate->onMessage($conn, $msg->getPayload());
+ };
+ } else {
+ throw new \UnexpectedValueException('Expected instance of \Ratchet\WebSocket\MessageComponentInterface or \Ratchet\MessageComponentInterface');
+ }
+
+ if (bin2hex('✓') !== 'e29c93') {
+ throw new \DomainException('Bad encoding, unicode character ✓ did not match expected value. Ensure charset UTF-8 and check ini val mbstring.func_autoload');
+ }
+
+ $this->delegate = $component;
+ $this->connections = new \SplObjectStorage;
+
+ $this->closeFrameChecker = new CloseFrameChecker;
+ $this->handshakeNegotiator = new ServerNegotiator(new RequestVerifier);
+ $this->handshakeNegotiator->setStrictSubProtocolCheck(true);
+
+ if ($component instanceof WsServerInterface) {
+ $this->handshakeNegotiator->setSupportedSubProtocols($component->getSubProtocols());
+ }
+
+ $this->pongReceiver = function() {};
+
+ $reusableUnderflowException = new \UnderflowException;
+ $this->ueFlowFactory = function() use ($reusableUnderflowException) {
+ return $reusableUnderflowException;
+ };
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
+ if (null === $request) {
+ throw new \UnexpectedValueException('$request can not be null');
+ }
+
+ $conn->httpRequest = $request;
+
+ $conn->WebSocket = new \StdClass;
+ $conn->WebSocket->closing = false;
+
+ $response = $this->handshakeNegotiator->handshake($request)->withHeader('X-Powered-By', \Ratchet\VERSION);
+
+ $conn->send(gPsr\str($response));
+
+ if (101 !== $response->getStatusCode()) {
+ return $conn->close();
+ }
+
+ $wsConn = new WsConnection($conn);
+
+ $streamer = new MessageBuffer(
+ $this->closeFrameChecker,
+ function(MessageInterface $msg) use ($wsConn) {
+ $cb = $this->msgCb;
+ $cb($wsConn, $msg);
+ },
+ function(FrameInterface $frame) use ($wsConn) {
+ $this->onControlFrame($frame, $wsConn);
+ },
+ true,
+ $this->ueFlowFactory
+ );
+
+ $this->connections->attach($conn, new ConnContext($wsConn, $streamer));
+
+ return $this->delegate->onOpen($wsConn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onMessage(ConnectionInterface $from, $msg) {
+ if ($from->WebSocket->closing) {
+ return;
+ }
+
+ $this->connections[$from]->buffer->onData($msg);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onClose(ConnectionInterface $conn) {
+ if ($this->connections->contains($conn)) {
+ $context = $this->connections[$conn];
+ $this->connections->detach($conn);
+
+ $this->delegate->onClose($context->connection);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ if ($this->connections->contains($conn)) {
+ $this->delegate->onError($this->connections[$conn]->connection, $e);
+ } else {
+ $conn->close();
+ }
+ }
+
+ public function onControlFrame(FrameInterface $frame, WsConnection $conn) {
+ switch ($frame->getOpCode()) {
+ case Frame::OP_CLOSE:
+ $conn->close($frame);
+ break;
+ case Frame::OP_PING:
+ $conn->send(new Frame($frame->getPayload(), true, Frame::OP_PONG));
+ break;
+ case Frame::OP_PONG:
+ $pongReceiver = $this->pongReceiver;
+ $pongReceiver($frame, $conn);
+ break;
+ }
+ }
+
+ public function setStrictSubProtocolCheck($enable) {
+ $this->handshakeNegotiator->setStrictSubProtocolCheck($enable);
+ }
+
+ public function enableKeepAlive(LoopInterface $loop, $interval = 30) {
+ $lastPing = new Frame(uniqid(), true, Frame::OP_PING);
+ $pingedConnections = new \SplObjectStorage;
+ $splClearer = new \SplObjectStorage;
+
+ $this->pongReceiver = function(FrameInterface $frame, $wsConn) use ($pingedConnections, &$lastPing) {
+ if ($frame->getPayload() === $lastPing->getPayload()) {
+ $pingedConnections->detach($wsConn);
+ }
+ };
+
+ $loop->addPeriodicTimer((int)$interval, function() use ($pingedConnections, &$lastPing, $splClearer) {
+ foreach ($pingedConnections as $wsConn) {
+ $wsConn->close();
+ }
+ $pingedConnections->removeAllExcept($splClearer);
+
+ $lastPing = new Frame(uniqid(), true, Frame::OP_PING);
+
+ foreach ($this->connections as $key => $conn) {
+ $wsConn = $this->connections[$conn]->connection;
+
+ $wsConn->send($lastPing);
+ $pingedConnections->attach($wsConn);
+ }
+ });
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php
new file mode 100644
index 0000000..15d1f7b
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/src/Ratchet/WebSocket/WsServerInterface.php
@@ -0,0 +1,14 @@
+send($msg);
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ }
+}
+
+ $port = $argc > 1 ? $argv[1] : 8000;
+ $impl = sprintf('React\EventLoop\%sLoop', $argc > 2 ? $argv[2] : 'StreamSelect');
+
+ $loop = new $impl;
+ $sock = new React\Socket\Server('0.0.0.0:' . $port, $loop);
+
+ $wsServer = new Ratchet\WebSocket\WsServer(new BinaryEcho);
+ // This is enabled to test https://github.com/ratchetphp/Ratchet/issues/430
+ // The time is left at 10 minutes so that it will not try to every ping anything
+ // This causes the Ratchet server to crash on test 2.7
+ $wsServer->enableKeepAlive($loop, 600);
+
+ $app = new Ratchet\Http\HttpServer($wsServer);
+
+ $server = new Ratchet\Server\IoServer($app, $sock, $loop);
+ $server->run();
diff --git a/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json
new file mode 100644
index 0000000..0494cf3
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-all.json
@@ -0,0 +1,15 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/ab"
+
+ , "servers": [
+ {"agent": "Ratchet/0.4 libevent", "url": "ws://localhost:8001", "options": {"version": 18}}
+ , {"agent": "Ratchet/0.4 libev", "url": "ws://localhost:8004", "options": {"version": 18}}
+ , {"agent": "Ratchet/0.4 streams", "url": "ws://localhost:8002", "options": {"version": 18}}
+ , {"agent": "AutobahnTestSuite/0.5.9", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["*"]
+ , "exclude-cases": []
+ , "exclude-agent-cases": {}
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json
new file mode 100644
index 0000000..e81a9fd
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-profile.json
@@ -0,0 +1,12 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/profile"
+
+ , "servers": [
+ {"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["9.7.4"]
+ , "exclude-cases": ["1.2.*", "2.3", "2.4", "2.6", "9.2.*", "9.4.*", "9.6.*", "9.8.*"]
+ , "exclude-agent-cases": {}
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json
new file mode 100644
index 0000000..c92e805
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/autobahn/fuzzingclient-quick.json
@@ -0,0 +1,12 @@
+{
+ "options": {"failByDrop": false}
+ , "outdir": "reports/rfc"
+
+ , "servers": [
+ {"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
+ ]
+
+ , "cases": ["*"]
+ , "exclude-cases": []
+ , "exclude-agent-cases": {}
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/bootstrap.php b/assets/php/vendor/cboden/ratchet/tests/bootstrap.php
new file mode 100644
index 0000000..40791ba
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/bootstrap.php
@@ -0,0 +1,4 @@
+addPsr4('Ratchet\\', __DIR__ . '/helpers/Ratchet');
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php
new file mode 100644
index 0000000..8c298e5
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/AbstractMessageComponentTestCase.php
@@ -0,0 +1,50 @@
+_app = $this->getMock($this->getComponentClassString());
+ $decorator = $this->getDecoratorClassString();
+ $this->_serv = new $decorator($this->_app);
+ $this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
+
+ $this->doOpen($this->_conn);
+ }
+
+ protected function doOpen($conn) {
+ $this->_serv->onOpen($conn);
+ }
+
+ public function isExpectedConnection() {
+ return new \PHPUnit_Framework_Constraint_IsInstanceOf($this->getConnectionClassString());
+ }
+
+ public function testOpen() {
+ $this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
+ $this->doOpen($this->getMock('\Ratchet\ConnectionInterface'));
+ }
+
+ public function testOnClose() {
+ $this->_app->expects($this->once())->method('onClose')->with($this->isExpectedConnection());
+ $this->_serv->onClose($this->_conn);
+ }
+
+ public function testOnError() {
+ $e = new \Exception('Whoops!');
+ $this->_app->expects($this->once())->method('onError')->with($this->isExpectedConnection(), $e);
+ $this->_serv->onError($this->_conn, $e);
+ }
+
+ public function passthroughMessageTest($value) {
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $value);
+ $this->_serv->onMessage($this->_conn, $value);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php
new file mode 100644
index 0000000..e152988
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Component.php
@@ -0,0 +1,35 @@
+last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onMessage(ConnectionInterface $from, $msg) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function getSubProtocols() {
+ return $this->protocols;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php
new file mode 100644
index 0000000..5918296
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/Connection.php
@@ -0,0 +1,20 @@
+ ''
+ , 'close' => false
+ );
+
+ public $remoteAddress = '127.0.0.1';
+
+ public function send($data) {
+ $this->last[__FUNCTION__] = $data;
+ }
+
+ public function close() {
+ $this->last[__FUNCTION__] = true;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php
new file mode 100644
index 0000000..5570c07
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/ConnectionDecorator.php
@@ -0,0 +1,22 @@
+ ''
+ , 'end' => false
+ );
+
+ public function send($data) {
+ $this->last[__FUNCTION__] = $data;
+
+ $this->getConnection()->send($data);
+ }
+
+ public function close() {
+ $this->last[__FUNCTION__] = true;
+
+ $this->getConnection()->close();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php
new file mode 100644
index 0000000..cd526cb
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/Mock/WampComponent.php
@@ -0,0 +1,43 @@
+protocols;
+ }
+
+ public function onCall(ConnectionInterface $conn, $id, $procURI, array $params) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onSubscribe(ConnectionInterface $conn, $topic) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onUnSubscribe(ConnectionInterface $conn, $topic) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ $this->last[__FUNCTION__] = func_get_args();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php
new file mode 100644
index 0000000..90def21
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/helpers/Ratchet/NullComponent.php
@@ -0,0 +1,28 @@
+mock = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->l1 = new ConnectionDecorator($this->mock);
+ $this->l2 = new ConnectionDecorator($this->l1);
+ }
+
+ public function testGet() {
+ $var = 'hello';
+ $val = 'world';
+
+ $this->mock->$var = $val;
+
+ $this->assertEquals($val, $this->l1->$var);
+ $this->assertEquals($val, $this->l2->$var);
+ }
+
+ public function testSet() {
+ $var = 'Chris';
+ $val = 'Boden';
+
+ $this->l1->$var = $val;
+
+ $this->assertEquals($val, $this->mock->$var);
+ }
+
+ public function testSetLevel2() {
+ $var = 'Try';
+ $val = 'Again';
+
+ $this->l2->$var = $val;
+
+ $this->assertEquals($val, $this->mock->$var);
+ }
+
+ public function testIsSetTrue() {
+ $var = 'PHP';
+ $val = 'Ratchet';
+
+ $this->mock->$var = $val;
+
+ $this->assertTrue(isset($this->l1->$var));
+ $this->assertTrue(isset($this->l2->$var));
+ }
+
+ public function testIsSetFalse() {
+ $var = 'herp';
+ $val = 'derp';
+
+ $this->assertFalse(isset($this->l1->$var));
+ $this->assertFalse(isset($this->l2->$var));
+ }
+
+ public function testUnset() {
+ $var = 'Flying';
+ $val = 'Monkey';
+
+ $this->mock->$var = $val;
+ unset($this->l1->$var);
+
+ $this->assertFalse(isset($this->mock->$var));
+ }
+
+ public function testUnsetLevel2() {
+ $var = 'Flying';
+ $val = 'Monkey';
+
+ $this->mock->$var = $val;
+ unset($this->l2->$var);
+
+ $this->assertFalse(isset($this->mock->$var));
+ }
+
+ public function testGetConnection() {
+ $class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $conn = $method->invokeArgs($this->l1, array());
+
+ $this->assertSame($this->mock, $conn);
+ }
+
+ public function testGetConnectionLevel2() {
+ $class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $conn = $method->invokeArgs($this->l2, array());
+
+ $this->assertSame($this->l1, $conn);
+ }
+
+ public function testWrapperCanStoreSelfInDecorator() {
+ $this->mock->decorator = $this->l1;
+
+ $this->assertSame($this->l1, $this->l2->decorator);
+ }
+
+ public function testDecoratorRecursion() {
+ $this->mock->decorator = new \stdClass;
+ $this->mock->decorator->conn = $this->l1;
+
+ $this->assertSame($this->l1, $this->mock->decorator->conn);
+ $this->assertSame($this->l1, $this->l1->decorator->conn);
+ $this->assertSame($this->l1, $this->l2->decorator->conn);
+ }
+
+ public function testDecoratorRecursionLevel2() {
+ $this->mock->decorator = new \stdClass;
+ $this->mock->decorator->conn = $this->l2;
+
+ $this->assertSame($this->l2, $this->mock->decorator->conn);
+ $this->assertSame($this->l2, $this->l1->decorator->conn);
+ $this->assertSame($this->l2, $this->l2->decorator->conn);
+
+ // just for fun
+ $this->assertSame($this->l2, $this->l2->decorator->conn->decorator->conn->decorator->conn);
+ }
+
+ public function testWarningGettingNothing() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->mock->nonExistant;
+ }
+
+ public function testWarningGettingNothingLevel1() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->l1->nonExistant;
+ }
+
+ public function testWarningGettingNothingLevel2() {
+ $this->setExpectedException('PHPUnit_Framework_Error');
+ $var = $this->l2->nonExistant;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php
new file mode 100644
index 0000000..6af8402
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpRequestParserTest.php
@@ -0,0 +1,50 @@
+parser = new HttpRequestParser;
+ }
+
+ public function headersProvider() {
+ return array(
+ array(false, "GET / HTTP/1.1\r\nHost: socketo.me\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n1")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖\r\n\r\n")
+ , array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie\r\n")
+ );
+ }
+
+ /**
+ * @dataProvider headersProvider
+ */
+ public function testIsEom($expected, $message) {
+ $this->assertEquals($expected, $this->parser->isEom($message));
+ }
+
+ public function testBufferOverflowResponse() {
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+
+ $this->parser->maxSize = 20;
+
+ $this->assertNull($this->parser->onMessage($conn, "GET / HTTP/1.1\r\n"));
+
+ $this->setExpectedException('OverflowException');
+
+ $this->parser->onMessage($conn, "Header-Is: Too Big");
+ }
+
+ public function testReturnTypeIsRequest() {
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $return = $this->parser->onMessage($conn, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n");
+
+ $this->assertInstanceOf('\Psr\Http\Message\RequestInterface', $return);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php
new file mode 100644
index 0000000..7041d66
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Http/HttpServerTest.php
@@ -0,0 +1,64 @@
+_conn->httpHeadersReceived = true;
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\Http\HttpServer';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function testOpen() {
+ $headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
+
+ $this->_conn->httpHeadersReceived = false;
+ $this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
+ $this->_serv->onMessage($this->_conn, $headers);
+ }
+
+ public function testOnMessageAfterHeaders() {
+ $headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
+ $this->_conn->httpHeadersReceived = false;
+ $this->_serv->onMessage($this->_conn, $headers);
+
+ $message = "Hello World!";
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
+ $this->_serv->onMessage($this->_conn, $message);
+ }
+
+ public function testBufferOverflow() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_conn->httpHeadersReceived = false;
+
+ $this->_serv->onMessage($this->_conn, str_repeat('a', 5000));
+ }
+
+ public function testCloseIfNotEstablished() {
+ $this->_conn->httpHeadersReceived = false;
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onError($this->_conn, new \Exception('Whoops!'));
+ }
+
+ public function testBufferHeaders() {
+ $this->_conn->httpHeadersReceived = false;
+ $this->_app->expects($this->never())->method('onOpen');
+ $this->_app->expects($this->never())->method('onMessage');
+
+ $this->_serv->onMessage($this->_conn, "GET / HTTP/1.1");
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php
new file mode 100644
index 0000000..c1c4012
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Http/OriginCheckTest.php
@@ -0,0 +1,46 @@
+_reqStub = $this->getMock('Psr\Http\Message\RequestInterface');
+ $this->_reqStub->expects($this->any())->method('getHeader')->will($this->returnValue(['localhost']));
+
+ parent::setUp();
+
+ $this->_serv->allowedOrigins[] = 'localhost';
+ }
+
+ protected function doOpen($conn) {
+ $this->_serv->onOpen($conn, $this->_reqStub);
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\Http\OriginCheck';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function testCloseOnNonMatchingOrigin() {
+ $this->_serv->allowedOrigins = ['socketo.me'];
+ $this->_conn->expects($this->once())->method('close');
+
+ $this->_serv->onOpen($this->_conn, $this->_reqStub);
+ }
+
+ public function testOnMessage() {
+ $this->passthroughMessageTest('Hello World!');
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php
new file mode 100644
index 0000000..1ca4cbc
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Http/RouterTest.php
@@ -0,0 +1,165 @@
+_conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_uri = $this->getMock('Psr\Http\Message\UriInterface');
+ $this->_req = $this->getMock('\Psr\Http\Message\RequestInterface');
+ $this->_req
+ ->expects($this->any())
+ ->method('getUri')
+ ->will($this->returnValue($this->_uri));
+ $this->_matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
+ $this->_matcher
+ ->expects($this->any())
+ ->method('getContext')
+ ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext')));
+ $this->_router = new Router($this->_matcher);
+
+ $this->_uri->expects($this->any())->method('getPath')->will($this->returnValue('ws://doesnt.matter/'));
+ $this->_uri->expects($this->any())->method('withQuery')->with($this->callback(function($val) {
+ $this->setResult($val);
+
+ return true;
+ }))->will($this->returnSelf());
+ $this->_uri->expects($this->any())->method('getQuery')->will($this->returnCallback([$this, 'getResult']));
+ $this->_req->expects($this->any())->method('withUri')->will($this->returnSelf());
+ }
+
+ public function testFourOhFour() {
+ $this->_conn->expects($this->once())->method('close');
+
+ $nope = new ResourceNotFoundException;
+ $this->_matcher->expects($this->any())->method('match')->will($this->throwException($nope));
+
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testNullRequest() {
+ $this->setExpectedException('\UnexpectedValueException');
+ $this->_router->onOpen($this->_conn);
+ }
+
+ public function testControllerIsMessageComponentInterface() {
+ $this->setExpectedException('\UnexpectedValueException');
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => new \StdClass)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testControllerOnOpen() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+
+ $expectedConn = new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\ConnectionInterface');
+ $controller->expects($this->once())->method('onOpen')->with($expectedConn, $this->_req);
+
+ $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
+ $this->_router->onOpen($this->_conn, $this->_req);
+ }
+
+ public function testControllerOnMessageBubbles() {
+ $message = "The greatest trick the Devil ever pulled was convincing the world he didn't exist";
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onMessage')->with($this->_conn, $message);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onMessage($this->_conn, $message);
+ }
+
+ public function testControllerOnCloseBubbles() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onClose')->with($this->_conn);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onClose($this->_conn);
+ }
+
+ public function testControllerOnErrorBubbles() {
+ $e= new \Exception('One cannot be betrayed if one has no exceptions');
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $controller->expects($this->once())->method('onError')->with($this->_conn, $e);
+
+ $this->_conn->controller = $controller;
+
+ $this->_router->onError($this->_conn, $e);
+ }
+
+ public function testRouterGeneratesRouteParameters() {
+ /** @var $controller WsServerInterface */
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ /** @var $matcher UrlMatcherInterface */
+ $this->_matcher->expects($this->any())->method('match')->will(
+ $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
+ );
+ $conn = $this->getMock('Ratchet\Mock\Connection');
+
+ $router = new Router($this->_matcher);
+
+ $router->onOpen($conn, $this->_req);
+
+ $this->assertEquals('foo=bar&baz=qux', $this->_req->getUri()->getQuery());
+ }
+
+ public function testQueryParams() {
+ $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
+ $this->_matcher->expects($this->any())->method('match')->will(
+ $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
+ );
+
+ $conn = $this->getMock('Ratchet\Mock\Connection');
+ $request = $this->getMock('Psr\Http\Message\RequestInterface');
+ $uri = new \GuzzleHttp\Psr7\Uri('ws://doesnt.matter/endpoint?hello=world&foo=nope');
+
+ $request->expects($this->any())->method('getUri')->will($this->returnCallback(function() use (&$uri) {
+ return $uri;
+ }));
+ $request->expects($this->any())->method('withUri')->with($this->callback(function($url) use (&$uri) {
+ $uri = $url;
+
+ return true;
+ }))->will($this->returnSelf());
+
+ $router = new Router($this->_matcher);
+ $router->onOpen($conn, $request);
+
+ $this->assertEquals('foo=nope&baz=qux&hello=world', $request->getUri()->getQuery());
+ $this->assertEquals('ws', $request->getUri()->getScheme());
+ $this->assertEquals('doesnt.matter', $request->getUri()->getHost());
+ }
+
+ public function testImpatientClientOverflow() {
+ $this->_conn->expects($this->once())->method('close');
+
+ $header = "GET /nope HTTP/1.1
+Upgrade: websocket
+Connection: upgrade
+Host: localhost
+Origin: http://localhost
+Sec-WebSocket-Version: 13\r\n\r\n";
+
+ $app = new HttpServer(new Router(new UrlMatcher(new RouteCollection, new RequestContext)));
+ $app->onOpen($this->_conn);
+ $app->onMessage($this->_conn, $header);
+ $app->onMessage($this->_conn, 'Silly body');
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php
new file mode 100644
index 0000000..47fb0e2
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Server/EchoServerTest.php
@@ -0,0 +1,26 @@
+_conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_comp = new EchoServer;
+ }
+
+ public function testMessageEchod() {
+ $message = 'Tillsonburg, my back still aches when I hear that word.';
+ $this->_conn->expects($this->once())->method('send')->with($message);
+ $this->_comp->onMessage($this->_conn, $message);
+ }
+
+ public function testErrorClosesConnection() {
+ ob_start();
+ $this->_conn->expects($this->once())->method('close');
+ $this->_comp->onError($this->_conn, new \Exception);
+ ob_end_clean();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php
new file mode 100644
index 0000000..38fc96a
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Server/FlashPolicyComponentTest.php
@@ -0,0 +1,152 @@
+_policy = new FlashPolicy();
+ }
+
+ public function testPolicyRender() {
+ $this->_policy->setSiteControl('all');
+ $this->_policy->addAllowedAccess('example.com', '*');
+ $this->_policy->addAllowedAccess('dev.example.com', '*');
+
+ $this->assertInstanceOf('SimpleXMLElement', $this->_policy->renderPolicy());
+ }
+
+ public function testInvalidPolicyReader() {
+ $this->setExpectedException('UnexpectedValueException');
+ $this->_policy->renderPolicy();
+ }
+
+ public function testInvalidDomainPolicyReader() {
+ $this->setExpectedException('UnexpectedValueException');
+ $this->_policy->setSiteControl('all');
+ $this->_policy->addAllowedAccess('dev.example.*', '*');
+ $this->_policy->renderPolicy();
+ }
+
+ /**
+ * @dataProvider siteControl
+ */
+ public function testSiteControlValidation($accept, $permittedCrossDomainPolicies) {
+ $this->assertEquals($accept, $this->_policy->validateSiteControl($permittedCrossDomainPolicies));
+ }
+
+ public static function siteControl() {
+ return array(
+ array(true, 'all')
+ , array(true, 'none')
+ , array(true, 'master-only')
+ , array(false, 'by-content-type')
+ , array(false, 'by-ftp-filename')
+ , array(false, '')
+ , array(false, 'all ')
+ , array(false, 'asdf')
+ , array(false, '@893830')
+ , array(false, '*')
+ );
+ }
+
+ /**
+ * @dataProvider URI
+ */
+ public function testDomainValidation($accept, $domain) {
+ $this->assertEquals($accept, $this->_policy->validateDomain($domain));
+ }
+
+ public static function URI() {
+ return array(
+ array(true, '*')
+ , array(true, 'example.com')
+ , array(true, 'exam-ple.com')
+ , array(true, '*.example.com')
+ , array(true, 'www.example.com')
+ , array(true, 'dev.dev.example.com')
+ , array(true, 'http://example.com')
+ , array(true, 'https://example.com')
+ , array(true, 'http://*.example.com')
+ , array(false, 'exam*ple.com')
+ , array(true, '127.0.255.1')
+ , array(true, 'localhost')
+ , array(false, 'www.example.*')
+ , array(false, 'www.exa*le.com')
+ , array(false, 'www.example.*com')
+ , array(false, '*.example.*')
+ , array(false, 'gasldf*$#a0sdf0a8sdf')
+ );
+ }
+
+ /**
+ * @dataProvider ports
+ */
+ public function testPortValidation($accept, $ports) {
+ $this->assertEquals($accept, $this->_policy->validatePorts($ports));
+ }
+
+ public static function ports() {
+ return array(
+ array(true, '*')
+ , array(true, '80')
+ , array(true, '80,443')
+ , array(true, '507,516-523')
+ , array(true, '507,516-523,333')
+ , array(true, '507,516-523,507,516-523')
+ , array(false, '516-')
+ , array(true, '516-523,11')
+ , array(false, '516,-523,11')
+ , array(false, 'example')
+ , array(false, 'asdf,123')
+ , array(false, '--')
+ , array(false, ',,,')
+ , array(false, '838*')
+ );
+ }
+
+ public function testAddAllowedAccessOnlyAcceptsValidPorts() {
+ $this->setExpectedException('UnexpectedValueException');
+
+ $this->_policy->addAllowedAccess('*', 'nope');
+ }
+
+ public function testSetSiteControlThrowsException() {
+ $this->setExpectedException('UnexpectedValueException');
+
+ $this->_policy->setSiteControl('nope');
+ }
+
+ public function testErrorClosesConnection() {
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->expects($this->once())->method('close');
+
+ $this->_policy->onError($conn, new \Exception);
+ }
+
+ public function testOnMessageSendsString() {
+ $this->_policy->addAllowedAccess('*', '*');
+
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->expects($this->once())->method('send')->with($this->isType('string'));
+
+ $this->_policy->onMessage($conn, ' ');
+ }
+
+ public function testOnOpenExists() {
+ $this->assertTrue(method_exists($this->_policy, 'onOpen'));
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_policy->onOpen($conn);
+ }
+
+ public function testOnCloseExists() {
+ $this->assertTrue(method_exists($this->_policy, 'onClose'));
+ $conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->_policy->onClose($conn);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php
new file mode 100644
index 0000000..07130f6
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoConnectionTest.php
@@ -0,0 +1,32 @@
+sock = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $this->conn = new IoConnection($this->sock);
+ }
+
+ public function testCloseBubbles() {
+ $this->sock->expects($this->once())->method('end');
+ $this->conn->close();
+ }
+
+ public function testSendBubbles() {
+ $msg = '6 hour rides are productive';
+
+ $this->sock->expects($this->once())->method('write')->with($msg);
+ $this->conn->send($msg);
+ }
+
+ public function testSendReturnsSelf() {
+ $this->assertSame($this->conn, $this->conn->send('fluent interface'));
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php
new file mode 100644
index 0000000..284fbde
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IoServerTest.php
@@ -0,0 +1,118 @@
+app = $this->getMock('\\Ratchet\\MessageComponentInterface');
+
+ $loop = new StreamSelectLoop;
+ $this->reactor = new Server(0, $loop);
+
+ $uri = $this->reactor->getAddress();
+ $this->port = parse_url((strpos($uri, '://') === false ? 'tcp://' : '') . $uri, PHP_URL_PORT);
+ $this->server = new IoServer($this->app, $this->reactor, $loop);
+ }
+
+ public function testOnOpen() {
+ $this->app->expects($this->once())->method('onOpen')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
+
+ $client = stream_socket_client("tcp://localhost:{$this->port}");
+
+ $this->server->loop->tick();
+
+ //$this->assertTrue(is_string($this->app->last['onOpen'][0]->remoteAddress));
+ //$this->assertTrue(is_int($this->app->last['onOpen'][0]->resourceId));
+ }
+
+ public function testOnData() {
+ $msg = 'Hello World!';
+
+ $this->app->expects($this->once())->method('onMessage')->with(
+ $this->isInstanceOf('\\Ratchet\\ConnectionInterface')
+ , $msg
+ );
+
+ $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
+ socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
+ socket_set_block($client);
+ socket_connect($client, 'localhost', $this->port);
+
+ $this->server->loop->tick();
+
+ socket_write($client, $msg);
+ $this->server->loop->tick();
+
+ socket_shutdown($client, 1);
+ socket_shutdown($client, 0);
+ socket_close($client);
+
+ $this->server->loop->tick();
+ }
+
+ public function testOnClose() {
+ $this->app->expects($this->once())->method('onClose')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
+
+ $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
+ socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
+ socket_set_block($client);
+ socket_connect($client, 'localhost', $this->port);
+
+ $this->server->loop->tick();
+
+ socket_shutdown($client, 1);
+ socket_shutdown($client, 0);
+ socket_close($client);
+
+ $this->server->loop->tick();
+ }
+
+ public function testFactory() {
+ $this->assertInstanceOf('\\Ratchet\\Server\\IoServer', IoServer::factory($this->app, 0));
+ }
+
+ public function testNoLoopProvidedError() {
+ $this->setExpectedException('RuntimeException');
+
+ $io = new IoServer($this->app, $this->reactor);
+ $io->run();
+ }
+
+ public function testOnErrorPassesException() {
+ $conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $conn->decor = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $err = new \Exception("Nope");
+
+ $this->app->expects($this->once())->method('onError')->with($conn->decor, $err);
+
+ $this->server->handleError($err, $conn);
+ }
+
+ public function onErrorCalledWhenExceptionThrown() {
+ $this->markTestIncomplete("Need to learn how to throw an exception from a mock");
+
+ $conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
+ $this->server->handleConnect($conn);
+
+ $e = new \Exception;
+ $this->app->expects($this->once())->method('onMessage')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'), 'f')->will($e);
+ $this->app->expects($this->once())->method('onError')->with($this->instanceOf('\\Ratchet\\ConnectionInterface', $e));
+
+ $this->server->handleData('f', $conn);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php
new file mode 100644
index 0000000..90f4185
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Server/IpBlackListComponentTest.php
@@ -0,0 +1,125 @@
+mock = $this->getMock('\\Ratchet\\MessageComponentInterface');
+ $this->blocker = new IpBlackList($this->mock);
+ }
+
+ public function testOnOpen() {
+ $this->mock->expects($this->exactly(3))->method('onOpen');
+
+ $conn1 = $this->newConn();
+ $conn2 = $this->newConn();
+ $conn3 = $this->newConn();
+
+ $this->blocker->onOpen($conn1);
+ $this->blocker->onOpen($conn3);
+ $this->blocker->onOpen($conn2);
+ }
+
+ public function testBlockDoesNotTriggerOnOpen() {
+ $conn = $this->newConn();
+
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $this->mock->expects($this->never())->method('onOpen');
+
+ $ret = $this->blocker->onOpen($conn);
+ }
+
+ public function testBlockDoesNotTriggerOnClose() {
+ $conn = $this->newConn();
+
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $this->mock->expects($this->never())->method('onClose');
+
+ $ret = $this->blocker->onOpen($conn);
+ }
+
+ public function testOnMessageDecoration() {
+ $conn = $this->newConn();
+ $msg = 'Hello not being blocked';
+
+ $this->mock->expects($this->once())->method('onMessage')->with($conn, $msg);
+
+ $this->blocker->onMessage($conn, $msg);
+ }
+
+ public function testOnCloseDecoration() {
+ $conn = $this->newConn();
+
+ $this->mock->expects($this->once())->method('onClose')->with($conn);
+
+ $this->blocker->onClose($conn);
+ }
+
+ public function testBlockClosesConnection() {
+ $conn = $this->newConn();
+ $this->blocker->blockAddress($conn->remoteAddress);
+
+ $conn->expects($this->once())->method('close');
+
+ $this->blocker->onOpen($conn);
+ }
+
+ public function testAddAndRemoveWithFluentInterfaces() {
+ $blockOne = '127.0.0.1';
+ $blockTwo = '192.168.1.1';
+ $unblock = '75.119.207.140';
+
+ $this->blocker
+ ->blockAddress($unblock)
+ ->blockAddress($blockOne)
+ ->unblockAddress($unblock)
+ ->blockAddress($blockTwo)
+ ;
+
+ $this->assertEquals(array($blockOne, $blockTwo), $this->blocker->getBlockedAddresses());
+ }
+
+ public function testDecoratorPassesErrors() {
+ $conn = $this->newConn();
+ $e = new \Exception('I threw an error');
+
+ $this->mock->expects($this->once())->method('onError')->with($conn, $e);
+
+ $this->blocker->onError($conn, $e);
+ }
+
+ public function addressProvider() {
+ return array(
+ array('127.0.0.1', '127.0.0.1')
+ , array('localhost', 'localhost')
+ , array('fe80::1%lo0', 'fe80::1%lo0')
+ , array('127.0.0.1', '127.0.0.1:6392')
+ );
+ }
+
+ /**
+ * @dataProvider addressProvider
+ */
+ public function testFilterAddress($expected, $input) {
+ $this->assertEquals($expected, $this->blocker->filterAddress($input));
+ }
+
+ public function testUnblockingSilentlyFails() {
+ $this->assertInstanceOf('\\Ratchet\\Server\\IpBlackList', $this->blocker->unblockAddress('localhost'));
+ }
+
+ protected function newConn() {
+ $conn = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn->remoteAddress = '127.0.0.1';
+
+ return $conn;
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php
new file mode 100644
index 0000000..4acf5bc
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Session/Serialize/PhpHandlerTest.php
@@ -0,0 +1,43 @@
+_handler = new PhpHandler;
+ }
+
+ public function serializedProvider() {
+ return array(
+ array(
+ '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}'
+ , array(
+ '_sf2_attributes' => array(
+ 'hello' => 'world'
+ , 'last' => 1332872102
+ )
+ , '_sf2_flashes' => array()
+ )
+ )
+ );
+ }
+
+ /**
+ * @dataProvider serializedProvider
+ */
+ public function testUnserialize($in, $expected) {
+ $this->assertEquals($expected, $this->_handler->unserialize($in));
+ }
+
+ /**
+ * @dataProvider serializedProvider
+ */
+ public function testSerialize($serialized, $original) {
+ $this->assertEquals($serialized, $this->_handler->serialize($original));
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php
new file mode 100644
index 0000000..ebfdde4
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Session/SessionComponentTest.php
@@ -0,0 +1,124 @@
+markTestSkipped('Dependency of Symfony HttpFoundation failed');
+ }
+
+ parent::setUp();
+ $this->_serv = new SessionProvider($this->_app, new NullSessionHandler);
+ }
+
+ public function tearDown() {
+ ini_set('session.serialize_handler', 'php');
+ }
+
+ public function getConnectionClassString() {
+ return '\Ratchet\ConnectionInterface';
+ }
+
+ public function getDecoratorClassString() {
+ return '\Ratchet\NullComponent';
+ }
+
+ public function getComponentClassString() {
+ return '\Ratchet\Http\HttpServerInterface';
+ }
+
+ public function classCaseProvider() {
+ return array(
+ array('php', 'Php')
+ , array('php_binary', 'PhpBinary')
+ );
+ }
+
+ /**
+ * @dataProvider classCaseProvider
+ */
+ public function testToClassCase($in, $out) {
+ $ref = new \ReflectionClass('\\Ratchet\\Session\\SessionProvider');
+ $method = $ref->getMethod('toClassCase');
+ $method->setAccessible(true);
+
+ $component = new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
+ $this->assertEquals($out, $method->invokeArgs($component, array($in)));
+ }
+
+ /**
+ * I think I have severely butchered this test...it's not so much of a unit test as it is a full-fledged component test
+ */
+ public function testConnectionValueFromPdo() {
+ if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
+ return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
+ }
+
+ $sessionId = md5('testSession');
+
+ $dbOptions = array(
+ 'db_table' => 'sessions'
+ , 'db_id_col' => 'sess_id'
+ , 'db_data_col' => 'sess_data'
+ , 'db_time_col' => 'sess_time'
+ , 'db_lifetime_col' => 'sess_lifetime'
+ );
+
+ $pdo = new \PDO("sqlite::memory:");
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $pdo->exec(vsprintf("CREATE TABLE %s (%s TEXT NOT NULL PRIMARY KEY, %s BLOB NOT NULL, %s INTEGER NOT NULL, %s INTEGER)", $dbOptions));
+
+ $pdoHandler = new PdoSessionHandler($pdo, $dbOptions);
+ $pdoHandler->write($sessionId, '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}');
+
+ $component = new SessionProvider($this->getMock($this->getComponentClassString()), $pdoHandler, array('auto_start' => 1));
+ $connection = $this->getMock('Ratchet\\ConnectionInterface');
+
+ $headers = $this->getMock('Psr\Http\Message\RequestInterface');
+ $headers->expects($this->once())->method('getHeader')->will($this->returnValue([ini_get('session.name') . "={$sessionId};"]));
+
+ $component->onOpen($connection, $headers);
+
+ $this->assertEquals('world', $connection->Session->get('hello'));
+ }
+
+ protected function newConn() {
+ $conn = $this->getMock('Ratchet\ConnectionInterface');
+
+ $headers = $this->getMock('Psr\Http\Message\Request', array('getCookie'), array('POST', '/', array()));
+ $headers->expects($this->once())->method('getCookie', array(ini_get('session.name')))->will($this->returnValue(null));
+
+ return $conn;
+ }
+
+ public function testOnMessageDecorator() {
+ $message = "Database calls are usually blocking :(";
+ $this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
+ $this->_serv->onMessage($this->_conn, $message);
+ }
+
+ public function testRejectInvalidSeralizers() {
+ if (!function_exists('wddx_serialize_value')) {
+ $this->markTestSkipped();
+ }
+
+ ini_set('session.serialize_handler', 'wddx');
+ $this->setExpectedException('\RuntimeException');
+ new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
+ }
+
+ protected function doOpen($conn) {
+ $request = $this->getMock('Psr\Http\Message\RequestInterface');
+ $request->expects($this->any())->method('getHeader')->will($this->returnValue([]));
+
+ $this->_serv->onOpen($conn, $request);
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
new file mode 100644
index 0000000..2727484
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Session/Storage/VirtualSessionStoragePDOTest.php
@@ -0,0 +1,53 @@
+markTestSkipped('Session test requires PDO and pdo_sqlite');
+ }
+
+ $schema = <<_pathToDB = tempnam(sys_get_temp_dir(), 'SQ3');;
+ $dsn = 'sqlite:' . $this->_pathToDB;
+
+ $pdo = new \PDO($dsn);
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $pdo->exec($schema);
+ $pdo = null;
+
+ $sessionHandler = new PdoSessionHandler($dsn);
+ $serializer = new PhpHandler();
+ $this->_virtualSessionStorage = new VirtualSessionStorage($sessionHandler, 'foobar', $serializer);
+ $this->_virtualSessionStorage->registerBag(new FlashBag());
+ $this->_virtualSessionStorage->registerBag(new AttributeBag());
+ }
+
+ public function tearDown() {
+ unlink($this->_pathToDB);
+ }
+
+ public function testStartWithDSN() {
+ $this->_virtualSessionStorage->start();
+
+ $this->assertTrue($this->_virtualSessionStorage->isStarted());
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php
new file mode 100644
index 0000000..8ff68c2
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/ServerProtocolTest.php
@@ -0,0 +1,295 @@
+_app = new TestComponent;
+ $this->_comp = new ServerProtocol($this->_app);
+ }
+
+ protected function newConn() {
+ return new Connection;
+ }
+
+ public function invalidMessageProvider() {
+ return [
+ [0]
+ , [3]
+ , [4]
+ , [8]
+ , [9]
+ ];
+ }
+
+ /**
+ * @dataProvider invalidMessageProvider
+ */
+ public function testInvalidMessages($type) {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = $this->newConn();
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode([$type]));
+ }
+
+ public function testWelcomeMessage() {
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+
+ $message = $conn->last['send'];
+ $json = json_decode($message);
+
+ $this->assertEquals(4, count($json));
+ $this->assertEquals(0, $json[0]);
+ $this->assertTrue(is_string($json[1]));
+ $this->assertEquals(1, $json[2]);
+ }
+
+ public function testSubscribe() {
+ $uri = 'http://example.com';
+ $clientMessage = array(5, $uri);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($uri, $this->_app->last['onSubscribe'][1]);
+ }
+
+ public function testUnSubscribe() {
+ $uri = 'http://example.com/endpoint';
+ $clientMessage = array(6, $uri);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($uri, $this->_app->last['onUnSubscribe'][1]);
+ }
+
+ public function callProvider() {
+ return [
+ [2, 'a', 'b']
+ , [2, ['a', 'b']]
+ , [1, 'one']
+ , [3, 'one', 'two', 'three']
+ , [3, ['un', 'deux', 'trois']]
+ , [2, 'hi', ['hello', 'world']]
+ , [2, ['hello', 'world'], 'hi']
+ , [2, ['hello' => 'world', 'herp' => 'derp']]
+ ];
+ }
+
+ /**
+ * @dataProvider callProvider
+ */
+ public function testCall() {
+ $args = func_get_args();
+ $paramNum = array_shift($args);
+
+ $uri = 'http://example.com/endpoint/' . rand(1, 100);
+ $id = uniqid('', false);
+ $clientMessage = array_merge(array(2, $id, $uri), $args);
+
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($id, $this->_app->last['onCall'][1]);
+ $this->assertEquals($uri, $this->_app->last['onCall'][2]);
+
+ $this->assertEquals($paramNum, count($this->_app->last['onCall'][3]));
+ }
+
+ public function testPublish() {
+ $conn = $this->newConn();
+
+ $topic = 'pubsubhubbub';
+ $event = 'Here I am, publishing data';
+
+ $clientMessage = array(7, $topic, $event);
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode($clientMessage));
+
+ $this->assertEquals($topic, $this->_app->last['onPublish'][1]);
+ $this->assertEquals($event, $this->_app->last['onPublish'][2]);
+ $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
+ $this->assertEquals(array(), $this->_app->last['onPublish'][4]);
+ }
+
+ public function testPublishAndExcludeMe() {
+ $conn = $this->newConn();
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', true)));
+
+ $this->assertEquals($conn->WAMP->sessionId, $this->_app->last['onPublish'][3][0]);
+ }
+
+ public function testPublishAndEligible() {
+ $conn = $this->newConn();
+
+ $buddy = uniqid('', false);
+ $friend = uniqid('', false);
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', false, array($buddy, $friend))));
+
+ $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
+ $this->assertEquals(2, count($this->_app->last['onPublish'][4]));
+ }
+
+ public function eventProvider() {
+ return array(
+ array('http://example.com', array('one', 'two'))
+ , array('curie', array(array('hello' => 'world', 'herp' => 'derp')))
+ );
+ }
+
+ /**
+ * @dataProvider eventProvider
+ */
+ public function testEvent($topic, $payload) {
+ $conn = new WampConnection($this->newConn());
+ $conn->event($topic, $payload);
+
+ $eventString = $conn->last['send'];
+
+ $this->assertSame(array(8, $topic, $payload), json_decode($eventString, true));
+ }
+
+ public function testOnClosePropagation() {
+ $conn = new Connection;
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onClose($conn);
+
+ $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $check = $method->invokeArgs($this->_app->last['onClose'][0], array());
+
+ $this->assertSame($conn, $check);
+ }
+
+ public function testOnErrorPropagation() {
+ $conn = new Connection;
+
+ $e = new \Exception('Nope');
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onError($conn, $e);
+
+ $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
+ $method = $class->getMethod('getConnection');
+ $method->setAccessible(true);
+
+ $check = $method->invokeArgs($this->_app->last['onError'][0], array());
+
+ $this->assertSame($conn, $check);
+ $this->assertSame($e, $this->_app->last['onError'][1]);
+ }
+
+ public function testPrefix() {
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $prefix = 'incoming';
+ $fullURI = "http://example.com/$prefix";
+ $method = 'call';
+
+ $this->_comp->onMessage($conn, json_encode(array(1, $prefix, $fullURI)));
+
+ $this->assertEquals($fullURI, $conn->WAMP->prefixes[$prefix]);
+ $this->assertEquals("$fullURI#$method", $conn->getUri("$prefix:$method"));
+ }
+
+ public function testMessageMustBeJson() {
+ $this->setExpectedException('\\Ratchet\\Wamp\\JsonException');
+
+ $conn = new Connection;
+
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, 'Hello World!');
+ }
+
+ public function testGetSubProtocolsReturnsArray() {
+ $this->assertTrue(is_array($this->_comp->getSubProtocols()));
+ }
+
+ public function testGetSubProtocolsGetFromApp() {
+ $this->_app->protocols = array('hello', 'world');
+
+ $this->assertGreaterThanOrEqual(3, count($this->_comp->getSubProtocols()));
+ }
+
+ public function testWampOnMessageApp() {
+ $app = $this->getMock('\\Ratchet\\Wamp\\WampServerInterface');
+ $wamp = new ServerProtocol($app);
+
+ $this->assertContains('wamp', $wamp->getSubProtocols());
+ }
+
+ public function badFormatProvider() {
+ return array(
+ array(json_encode(true))
+ , array('{"valid":"json", "invalid": "message"}')
+ , array('{"0": "fail", "hello": "world"}')
+ );
+ }
+
+ /**
+ * @dataProvider badFormatProvider
+ */
+ public function testValidJsonButInvalidProtocol($message) {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = $this->newConn();
+ $this->_comp->onOpen($conn);
+ $this->_comp->onMessage($conn, $message);
+ }
+
+ public function testBadClientInputFromNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([5, ['hells', 'nope']]));
+ }
+
+ public function testBadPrefixWithNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([1, ['hells', 'nope'], ['bad', 'input']]));
+ }
+
+ public function testBadPublishWithNonStringTopic() {
+ $this->setExpectedException('\Ratchet\Wamp\Exception');
+
+ $conn = new WampConnection($this->newConn());
+ $this->_comp->onOpen($conn);
+
+ $this->_comp->onMessage($conn, json_encode([7, ['bad', 'input'], 'Hider']));
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php
new file mode 100644
index 0000000..b21b6bc
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicManagerTest.php
@@ -0,0 +1,226 @@
+conn = $this->getMock('\Ratchet\ConnectionInterface');
+ $this->mock = $this->getMock('\Ratchet\Wamp\WampServerInterface');
+ $this->mngr = new TopicManager($this->mock);
+
+ $this->conn->WAMP = new \StdClass;
+ $this->mngr->onOpen($this->conn);
+ }
+
+ public function testGetTopicReturnsTopicObject() {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array('The Topic'));
+
+ $this->assertInstanceOf('Ratchet\Wamp\Topic', $topic);
+ }
+
+ public function testGetTopicCreatesTopicWithSameName() {
+ $name = 'The Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->assertEquals($name, $topic->getId());
+ }
+
+ public function testGetTopicReturnsSameObject() {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array('No copy'));
+ $again = $method->invokeArgs($this->mngr, array('No copy'));
+
+ $this->assertSame($topic, $again);
+ }
+
+ public function testOnOpen() {
+ $this->mock->expects($this->once())->method('onOpen');
+ $this->mngr->onOpen($this->conn);
+ }
+
+ public function testOnCall() {
+ $id = uniqid();
+
+ $this->mock->expects($this->once())->method('onCall')->with(
+ $this->conn
+ , $id
+ , $this->isInstanceOf('Ratchet\Wamp\Topic')
+ , array()
+ );
+
+ $this->mngr->onCall($this->conn, $id, 'new topic', array());
+ }
+
+ public function testOnSubscribeCreatesTopicObject() {
+ $this->mock->expects($this->once())->method('onSubscribe')->with(
+ $this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
+ );
+
+ $this->mngr->onSubscribe($this->conn, 'new topic');
+ }
+
+ public function testTopicIsInConnectionOnSubscribe() {
+ $name = 'New Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+
+ $this->assertTrue($this->conn->WAMP->subscriptions->contains($topic));
+ }
+
+ public function testDoubleSubscriptionFiresOnce() {
+ $this->mock->expects($this->exactly(1))->method('onSubscribe');
+
+ $this->mngr->onSubscribe($this->conn, 'same topic');
+ $this->mngr->onSubscribe($this->conn, 'same topic');
+ }
+
+ public function testUnsubscribeEvent() {
+ $name = 'in and out';
+ $this->mock->expects($this->once())->method('onUnsubscribe')->with(
+ $this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
+ );
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ }
+
+ public function testUnsubscribeFiresOnce() {
+ $name = 'getting sleepy';
+ $this->mock->expects($this->exactly(1))->method('onUnsubscribe');
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+ }
+
+ public function testUnsubscribeRemovesTopicFromConnection() {
+ $name = 'Bye Bye Topic';
+
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onUnsubscribe($this->conn, $name);
+
+ $this->assertFalse($this->conn->WAMP->subscriptions->contains($topic));
+ }
+
+ public function testOnPublishBubbles() {
+ $msg = 'Cover all the code!';
+
+ $this->mock->expects($this->once())->method('onPublish')->with(
+ $this->conn
+ , $this->isInstanceOf('Ratchet\Wamp\Topic')
+ , $msg
+ , $this->isType('array')
+ , $this->isType('array')
+ );
+
+ $this->mngr->onPublish($this->conn, 'topic coverage', $msg, array(), array());
+ }
+
+ public function testOnCloseBubbles() {
+ $this->mock->expects($this->once())->method('onClose')->with($this->conn);
+ $this->mngr->onClose($this->conn);
+ }
+
+ protected function topicProvider($name) {
+ $class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
+ $method = $class->getMethod('getTopic');
+ $method->setAccessible(true);
+
+ $attribute = $class->getProperty('topicLookup');
+ $attribute->setAccessible(true);
+
+ $topic = $method->invokeArgs($this->mngr, array($name));
+
+ return array($topic, $attribute);
+ }
+
+ public function testConnIsRemovedFromTopicOnClose() {
+ $name = 'State Testing';
+ list($topic, $attribute) = $this->topicProvider($name);
+
+ $this->assertCount(1, $attribute->getValue($this->mngr));
+
+ $this->mngr->onSubscribe($this->conn, $name);
+ $this->mngr->onClose($this->conn);
+
+ $this->assertFalse($topic->has($this->conn));
+ }
+
+ public static function topicConnExpectationProvider() {
+ return [
+ [ 'onClose', 0]
+ , ['onUnsubscribe', 0]
+ ];
+ }
+
+ /**
+ * @dataProvider topicConnExpectationProvider
+ */
+ public function testTopicRetentionFromLeavingConnections($methodCall, $expectation) {
+ $topicName = 'checkTopic';
+ list($topic, $attribute) = $this->topicProvider($topicName);
+
+ $this->mngr->onSubscribe($this->conn, $topicName);
+ call_user_func_array(array($this->mngr, $methodCall), array($this->conn, $topicName));
+
+ $this->assertCount($expectation, $attribute->getValue($this->mngr));
+ }
+
+ public function testOnErrorBubbles() {
+ $e = new \Exception('All work and no play makes Chris a dull boy');
+ $this->mock->expects($this->once())->method('onError')->with($this->conn, $e);
+
+ $this->mngr->onError($this->conn, $e);
+ }
+
+ public function testGetSubProtocolsReturnsArray() {
+ $this->assertInternalType('array', $this->mngr->getSubProtocols());
+ }
+
+ public function testGetSubProtocolsBubbles() {
+ $subs = array('hello', 'world');
+ $app = $this->getMock('Ratchet\Wamp\Stub\WsWampServerInterface');
+ $app->expects($this->once())->method('getSubProtocols')->will($this->returnValue($subs));
+ $mngr = new TopicManager($app);
+
+ $this->assertEquals($subs, $mngr->getSubProtocols());
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php
new file mode 100644
index 0000000..b8685b7
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/TopicTest.php
@@ -0,0 +1,164 @@
+assertEquals($id, $topic->getId());
+ }
+
+ public function testAddAndCount() {
+ $topic = new Topic('merp');
+
+ $topic->add($this->newConn());
+ $topic->add($this->newConn());
+ $topic->add($this->newConn());
+
+ $this->assertEquals(3, count($topic));
+ }
+
+ public function testRemove() {
+ $topic = new Topic('boop');
+ $tracked = $this->newConn();
+
+ $topic->add($this->newConn());
+ $topic->add($tracked);
+ $topic->add($this->newConn());
+
+ $topic->remove($tracked);
+
+ $this->assertEquals(2, count($topic));
+ }
+
+ public function testBroadcast() {
+ $msg = 'Hello World!';
+ $name = 'Batman';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+
+ $topic->broadcast($msg);
+ }
+
+ public function testBroadcastWithExclude() {
+ $msg = 'Hello odd numbers';
+ $name = 'Excluding';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->never())->method('send');
+
+ $third->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+ $topic->add($third);
+
+ $topic->broadcast($msg, array($second->WAMP->sessionId));
+ }
+
+ public function testBroadcastWithEligible() {
+ $msg = 'Hello white list';
+ $name = 'Eligible';
+ $protocol = json_encode(array(8, $name, $msg));
+
+ $first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+ $third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
+
+ $first->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $second->expects($this->never())->method('send');
+
+ $third->expects($this->once())
+ ->method('send')
+ ->with($this->equalTo($protocol));
+
+ $topic = new Topic($name);
+ $topic->add($first);
+ $topic->add($second);
+ $topic->add($third);
+
+ $topic->broadcast($msg, array(), array($first->WAMP->sessionId, $third->WAMP->sessionId));
+ }
+
+ public function testIterator() {
+ $first = $this->newConn();
+ $second = $this->newConn();
+ $third = $this->newConn();
+
+ $topic = new Topic('Joker');
+ $topic->add($first)->add($second)->add($third);
+
+ $check = array($first, $second, $third);
+
+ foreach ($topic as $mock) {
+ $this->assertNotSame(false, array_search($mock, $check));
+ }
+ }
+
+ public function testToString() {
+ $name = 'Bane';
+ $topic = new Topic($name);
+
+ $this->assertEquals($name, (string)$topic);
+ }
+
+ public function testDoesHave() {
+ $conn = $this->newConn();
+ $topic = new Topic('Two Face');
+ $topic->add($conn);
+
+ $this->assertTrue($topic->has($conn));
+ }
+
+ public function testDoesNotHave() {
+ $conn = $this->newConn();
+ $topic = new Topic('Alfred');
+
+ $this->assertFalse($topic->has($conn));
+ }
+
+ public function testDoesNotHaveAfterRemove() {
+ $conn = $this->newConn();
+ $topic = new Topic('Ras');
+
+ $topic->add($conn)->remove($conn);
+
+ $this->assertFalse($topic->has($conn));
+ }
+
+ protected function newConn() {
+ return new WampConnection($this->getMock('\\Ratchet\\ConnectionInterface'));
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php
new file mode 100644
index 0000000..adf59d5
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampConnectionTest.php
@@ -0,0 +1,77 @@
+mock = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $this->conn = new WampConnection($this->mock);
+ }
+
+ public function testCallResult() {
+ $callId = uniqid();
+ $data = array('hello' => 'world', 'herp' => 'derp');
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(3, $callId, $data)));
+
+ $this->conn->callResult($callId, $data);
+ }
+
+ public function testCallError() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
+
+ $this->conn->callError($callId, $uri);
+ }
+
+ public function testCallErrorWithTopic() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
+
+ $this->conn->callError($callId, new Topic($uri));
+ }
+
+ public function testDetailedCallError() {
+ $callId = uniqid();
+ $uri = 'http://example.com/end/point';
+ $desc = 'beep boop beep';
+ $detail = 'Error: Too much awesome';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, $desc, $detail)));
+
+ $this->conn->callError($callId, $uri, $desc, $detail);
+ }
+
+ public function testPrefix() {
+ $shortOut = 'outgoing';
+ $longOut = 'http://example.com/outgoing';
+
+ $this->mock->expects($this->once())->method('send')->with(json_encode(array(1, $shortOut, $longOut)));
+
+ $this->conn->prefix($shortOut, $longOut);
+ }
+
+ public function testGetUriWhenNoCurieGiven() {
+ $uri = 'http://example.com/noshort';
+
+ $this->assertEquals($uri, $this->conn->getUri($uri));
+ }
+
+ public function testClose() {
+ $mock = $this->getMock('\\Ratchet\\ConnectionInterface');
+ $conn = new WampConnection($mock);
+
+ $mock->expects($this->once())->method('close');
+
+ $conn->close();
+ }
+}
diff --git a/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php
new file mode 100644
index 0000000..626b1ce
--- /dev/null
+++ b/assets/php/vendor/cboden/ratchet/tests/unit/Wamp/WampServerTest.php
@@ -0,0 +1,49 @@
+_app->expects($this->once())->method('onPublish')->with(
+ $this->isExpectedConnection()
+ , new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\Wamp\Topic')
+ , $published
+ , array()
+ , array()
+ );
+
+ $this->_serv->onMessage($this->_conn, json_encode(array(7, 'topic', $published)));
+ }
+
+ public function testGetSubProtocols() {
+ // todo: could expand on this
+ $this->assertInternalType('array', $this->_serv->getSubProtocols());
+ }
+
+ public function testConnectionClosesOnInvalidJson() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onMessage($this->_conn, 'invalid json');
+ }
+
+ public function testConnectionClosesOnProtocolError() {
+ $this->_conn->expects($this->once())->method('close');
+ $this->_serv->onMessage($this->_conn, json_encode(array('valid' => 'json', 'invalid' => 'protocol')));
+ }
+}
--
cgit v1.2.3