代码同步
This commit is contained in:
21
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
21
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Use this if you believe there is a bug in this repo
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
Please provide a clear and concise description of the suspected issue.
|
||||
|
||||
**How to reproduce**
|
||||
If possible, provide information - possibly including code snippets - on how to reproduce the issue.
|
||||
|
||||
**Logs**
|
||||
If possible, provide logs that indicate the issue. See https://github.com/Textalk/websocket-php/blob/master/docs/Examples.md#echo-logger on how to use the EchoLog.
|
||||
|
||||
**Versions**
|
||||
* Version of this library
|
||||
* PHP version
|
||||
14
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this library
|
||||
title: ''
|
||||
labels: feature request
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is it within the scope of this library?**
|
||||
Consider and describe why the feature would be beneficial in this library, and not implemented as a separate project using this as a dependency.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
10
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/other-issue.md
vendored
Normal file
10
Server/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/other-issue.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Other issue
|
||||
about: Use this for other issues
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe your issue**
|
||||
113
Server/vendor/textalk/websocket/.github/workflows/acceptance.yml
vendored
Normal file
113
Server/vendor/textalk/websocket/.github/workflows/acceptance.yml
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
name: Acceptance
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test-7-2:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test PHP 7.2
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 7.2
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '7.2'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
test-7-3:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test PHP 7.3
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 7.3
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '7.3'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
test-7-4:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test PHP 7.4
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 7.4
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '7.4'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
test-8-0:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test PHP 8.0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 8.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
test-8-1:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test PHP 8.1
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 8.1
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
|
||||
cs-check:
|
||||
runs-on: ubuntu-latest
|
||||
name: Code standard
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 8.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Code standard
|
||||
run: make cs-check
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
name: Code coverage
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up PHP 8.0
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
extensions: xdebug
|
||||
- name: Composer
|
||||
run: make install
|
||||
- name: Code coverage
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: make coverage
|
||||
6
Server/vendor/textalk/websocket/.gitignore
vendored
Normal file
6
Server/vendor/textalk/websocket/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.DS_Store
|
||||
.phpunit.result.cache
|
||||
build/
|
||||
composer.lock
|
||||
composer.phar
|
||||
vendor/
|
||||
16
Server/vendor/textalk/websocket/COPYING.md
vendored
Normal file
16
Server/vendor/textalk/websocket/COPYING.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Websocket: License
|
||||
|
||||
Websocket PHP is free software released under the following license:
|
||||
|
||||
[ISC License](http://en.wikipedia.org/wiki/ISC_license)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without
|
||||
fee is hereby granted, provided that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
32
Server/vendor/textalk/websocket/Makefile
vendored
Normal file
32
Server/vendor/textalk/websocket/Makefile
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
install: composer.phar
|
||||
./composer.phar install
|
||||
|
||||
update: composer.phar
|
||||
./composer.phar self-update
|
||||
./composer.phar update
|
||||
|
||||
test: composer.lock
|
||||
./vendor/bin/phpunit
|
||||
|
||||
cs-check: composer.lock
|
||||
./vendor/bin/phpcs --standard=codestandard.xml lib tests examples
|
||||
|
||||
coverage: composer.lock build
|
||||
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
||||
./vendor/bin/php-coveralls -v
|
||||
|
||||
composer.phar:
|
||||
curl -s http://getcomposer.org/installer | php
|
||||
|
||||
composer.lock: composer.phar
|
||||
./composer.phar --no-interaction install
|
||||
|
||||
vendor/bin/phpunit: install
|
||||
|
||||
build:
|
||||
mkdir build
|
||||
|
||||
clean:
|
||||
rm composer.phar
|
||||
rm -r vendor
|
||||
rm -r build
|
||||
67
Server/vendor/textalk/websocket/README.md
vendored
Normal file
67
Server/vendor/textalk/websocket/README.md
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# Websocket Client and Server for PHP
|
||||
|
||||
[](https://github.com/Textalk/websocket-php/actions)
|
||||
[](https://coveralls.io/github/Textalk/websocket-php)
|
||||
|
||||
This library contains WebSocket client and server for PHP.
|
||||
|
||||
The client and server provides methods for reading and writing to WebSocket streams.
|
||||
It does not include convenience operations such as listeners and implicit error handling.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Client](docs/Client.md)
|
||||
- [Server](docs/Server.md)
|
||||
- [Message](docs/Message.md)
|
||||
- [Examples](docs/Examples.md)
|
||||
- [Changelog](docs/Changelog.md)
|
||||
- [Contributing](docs/Contributing.md)
|
||||
|
||||
## Installing
|
||||
|
||||
Preferred way to install is with [Composer](https://getcomposer.org/).
|
||||
```
|
||||
composer require textalk/websocket
|
||||
```
|
||||
|
||||
* Current version support PHP versions `^7.2|^8.0`.
|
||||
* For PHP `7.1` support use version [`1.4`](https://github.com/Textalk/websocket-php/tree/1.4.0).
|
||||
* For PHP `^5.4` and `7.0` support use version [`1.3`](https://github.com/Textalk/websocket-php/tree/1.3.0).
|
||||
|
||||
## Client
|
||||
|
||||
The [client](docs/Client.md) can read and write on a WebSocket stream.
|
||||
It internally supports Upgrade handshake and implicit close and ping/pong operations.
|
||||
|
||||
```php
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/");
|
||||
$client->text("Hello WebSocket.org!");
|
||||
echo $client->receive();
|
||||
$client->close();
|
||||
```
|
||||
|
||||
## Server
|
||||
|
||||
The library contains a rudimentary single stream/single thread [server](docs/Server.md).
|
||||
It internally supports Upgrade handshake and implicit close and ping/pong operations.
|
||||
|
||||
Note that it does **not** support threading or automatic association ot continuous client requests.
|
||||
If you require this kind of server behavior, you need to build it on top of provided server implementation.
|
||||
|
||||
```php
|
||||
$server = new WebSocket\Server();
|
||||
$server->accept();
|
||||
$message = $server->receive();
|
||||
$server->text($message);
|
||||
$server->close();
|
||||
```
|
||||
|
||||
### License and Contributors
|
||||
|
||||
[ISC License](COPYING.md)
|
||||
|
||||
Fredrik Liljegren, Armen Baghumian Sankbarani, Ruslan Bekenev,
|
||||
Joshua Thijssen, Simon Lipp, Quentin Bellus, Patrick McCarren, swmcdonnell,
|
||||
Ignas Bernotas, Mark Herhold, Andreas Palm, Sören Jensen, pmaasz, Alexey Stavrov,
|
||||
Michael Slezak, Pierre Seznec, rmeisler, Nickolay V. Shmyrev, Christoph Kempen,
|
||||
Marc Roberts, Antonio Mora, Simon Podlipsky.
|
||||
10
Server/vendor/textalk/websocket/codestandard.xml
vendored
Normal file
10
Server/vendor/textalk/websocket/codestandard.xml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<ruleset name="PSR with exception">
|
||||
<arg name="encoding" value="UTF-8"/>
|
||||
<arg name="report" value="full"/>
|
||||
<arg name="colors"/>
|
||||
|
||||
<rule ref="PSR1"/>
|
||||
<rule ref="PSR12"/>
|
||||
</ruleset>
|
||||
34
Server/vendor/textalk/websocket/composer.json
vendored
Normal file
34
Server/vendor/textalk/websocket/composer.json
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
"description": "WebSocket client and server",
|
||||
"license": "ISC",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fredrik Liljegren"
|
||||
},
|
||||
{
|
||||
"name": "Sören Jensen",
|
||||
"email": "soren@abicart.se"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"WebSocket\\": "lib"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"WebSocket\\": "tests/mock"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 | ^8.0",
|
||||
"psr/log": "^1 | ^2 | ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0|^9.0",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
}
|
||||
}
|
||||
143
Server/vendor/textalk/websocket/docs/Changelog.md
vendored
Normal file
143
Server/vendor/textalk/websocket/docs/Changelog.md
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
[Client](Client.md) • [Server](Server.md) • [Message](Message.md) • [Examples](Examples.md) • Changelog • [Contributing](Contributing.md)
|
||||
|
||||
# Websocket: Changelog
|
||||
|
||||
## `v1.5`
|
||||
|
||||
> PHP version `^7.2|^8.0`
|
||||
|
||||
### `1.5.8`
|
||||
|
||||
* Handle read error during handshake (@sirn-se)
|
||||
|
||||
### `1.5.7`
|
||||
|
||||
* Large header block fix (@sirn-se)
|
||||
|
||||
### `1.5.6`
|
||||
|
||||
* Add test for PHP 8.1 (@sirn-se)
|
||||
* Code standard (@sirn-se)
|
||||
|
||||
### `1.5.5`
|
||||
|
||||
* Support for psr/log v2 and v3 (@simPod)
|
||||
* GitHub Actions replaces Travis (@sirn-se)
|
||||
|
||||
### `1.5.4`
|
||||
|
||||
* Keep open connection on read timeout (@marcroberts)
|
||||
|
||||
### `1.5.3`
|
||||
|
||||
* Fix for persistent connection (@sirn-se)
|
||||
|
||||
### `1.5.2`
|
||||
|
||||
* Fix for getName() method (@sirn-se)
|
||||
|
||||
### `1.5.1`
|
||||
|
||||
* Fix for persistent connections (@rmeisler)
|
||||
|
||||
### `1.5.0`
|
||||
|
||||
* Convenience send methods; text(), binary(), ping(), pong() (@sirn-se)
|
||||
* Optional Message instance as receive() method return (@sirn-se)
|
||||
* Opcode filter for receive() method (@sirn-se)
|
||||
* Added PHP `8.0` support (@webpatser)
|
||||
* Dropped PHP `7.1` support (@sirn-se)
|
||||
* Fix for unordered fragmented messages (@sirn-se)
|
||||
* Improved error handling on stream calls (@sirn-se)
|
||||
* Various code re-write (@sirn-se)
|
||||
|
||||
## `v1.4`
|
||||
|
||||
> PHP version `^7.1`
|
||||
|
||||
#### `1.4.3`
|
||||
|
||||
* Solve stream closure/get meta conflict (@sirn-se)
|
||||
* Examples and documentation overhaul (@sirn-se)
|
||||
|
||||
#### `1.4.2`
|
||||
|
||||
* Force stream close on read error (@sirn-se)
|
||||
* Authorization headers line feed (@sirn-se)
|
||||
* Documentation (@matias-pool, @sirn-se)
|
||||
|
||||
#### `1.4.1`
|
||||
|
||||
* Ping/Pong, handled internally to avoid breaking fragmented messages (@nshmyrev, @sirn-se)
|
||||
* Fix for persistent connections (@rmeisler)
|
||||
* Fix opcode bitmask (@peterjah)
|
||||
|
||||
#### `1.4.0`
|
||||
|
||||
* Dropped support of old PHP versions (@sirn-se)
|
||||
* Added PSR-3 Logging support (@sirn-se)
|
||||
* Persistent connection option (@slezakattack)
|
||||
* TimeoutException on connection time out (@slezakattack)
|
||||
|
||||
## `v1.3`
|
||||
|
||||
> PHP version `^5.4` and `^7.0`
|
||||
|
||||
#### `1.3.1`
|
||||
|
||||
* Allow control messages without payload (@Logioniz)
|
||||
* Error code in ConnectionException (@sirn-se)
|
||||
|
||||
#### `1.3.0`
|
||||
|
||||
* Implements ping/pong frames (@pmccarren @Logioniz)
|
||||
* Close behaviour (@sirn-se)
|
||||
* Various fixes concerning connection handling (@sirn-se)
|
||||
* Overhaul of Composer, Travis and Coveralls setup, PSR code standard and unit tests (@sirn-se)
|
||||
|
||||
## `v1.2`
|
||||
|
||||
> PHP version `^5.4` and `^7.0`
|
||||
|
||||
#### `1.2.0`
|
||||
|
||||
* Adding stream context options (to set e.g. SSL `allow_self_signed`).
|
||||
|
||||
## `v1.1`
|
||||
|
||||
> PHP version `^5.4` and `^7.0`
|
||||
|
||||
#### `1.1.2`
|
||||
|
||||
* Fixed error message on broken frame.
|
||||
|
||||
#### `1.1.1`
|
||||
|
||||
* Adding license information.
|
||||
|
||||
#### `1.1.0`
|
||||
|
||||
* Supporting huge payloads.
|
||||
|
||||
## `v1.0`
|
||||
|
||||
> PHP version `^5.4` and `^7.0`
|
||||
|
||||
#### `1.0.3`
|
||||
|
||||
* Bugfix: Correcting address in error-message
|
||||
|
||||
#### `1.0.2`
|
||||
|
||||
* Bugfix: Add port in request-header.
|
||||
|
||||
#### `1.0.1`
|
||||
|
||||
* Fixing a bug from empty payloads.
|
||||
|
||||
#### `1.0.0`
|
||||
|
||||
* Release as production ready.
|
||||
* Adding option to set/override headers.
|
||||
* Supporting basic authentication from user:pass in URL.
|
||||
|
||||
137
Server/vendor/textalk/websocket/docs/Client.md
vendored
Normal file
137
Server/vendor/textalk/websocket/docs/Client.md
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
Client • [Server](Server.md) • [Message](Message.md) • [Examples](Examples.md) • [Changelog](Changelog.md) • [Contributing](Contributing.md)
|
||||
|
||||
# Websocket: Client
|
||||
|
||||
The client can read and write on a WebSocket stream.
|
||||
It internally supports Upgrade handshake and implicit close and ping/pong operations.
|
||||
|
||||
## Class synopsis
|
||||
|
||||
```php
|
||||
WebSocket\Client {
|
||||
|
||||
public __construct(string $uri, array $options = [])
|
||||
public __destruct()
|
||||
public __toString() : string
|
||||
|
||||
public text(string $payload) : void
|
||||
public binary(string $payload) : void
|
||||
public ping(string $payload = '') : void
|
||||
public pong(string $payload = '') : void
|
||||
public send(mixed $payload, string $opcode = 'text', bool $masked = true) : void
|
||||
public receive() : mixed
|
||||
public close(int $status = 1000, mixed $message = 'ttfn') : mixed
|
||||
|
||||
public getName() : string|null
|
||||
public getPier() : string|null
|
||||
public getLastOpcode() : string
|
||||
public getCloseStatus() : int
|
||||
public isConnected() : bool
|
||||
public setTimeout(int $seconds) : void
|
||||
public setFragmentSize(int $fragment_size) : self
|
||||
public getFragmentSize() : int
|
||||
public setLogger(Psr\Log\LoggerInterface $logger = null) : void
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple send-receive operation
|
||||
|
||||
This example send a single message to a server, and output the response.
|
||||
|
||||
```php
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/");
|
||||
$client->text("Hello WebSocket.org!");
|
||||
echo $client->receive();
|
||||
$client->close();
|
||||
```
|
||||
|
||||
### Listening to a server
|
||||
|
||||
To continuously listen to incoming messages, you need to put the receive operation within a loop.
|
||||
Note that these functions **always** throw exception on any failure, including recoverable failures such as connection time out.
|
||||
By consuming exceptions, the code will re-connect the socket in next loop iteration.
|
||||
|
||||
```php
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/");
|
||||
while (true) {
|
||||
try {
|
||||
$message = $client->receive();
|
||||
// Act on received message
|
||||
// Break while loop to stop listening
|
||||
} catch (\WebSocket\ConnectionException $e) {
|
||||
// Possibly log errors
|
||||
}
|
||||
}
|
||||
$client->close();
|
||||
```
|
||||
|
||||
### Filtering received messages
|
||||
|
||||
By default the `receive()` method return messages of 'text' and 'binary' opcode.
|
||||
The filter option allows you to specify which message types to return.
|
||||
|
||||
```php
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/", ['filter' => ['text']]);
|
||||
$client->receive(); // Only return 'text' messages
|
||||
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/", ['filter' => ['text', 'binary', 'ping', 'pong', 'close']]);
|
||||
$client->receive(); // Return all messages
|
||||
```
|
||||
|
||||
### Sending messages
|
||||
|
||||
There are convenience methods to send messages with different opcodes.
|
||||
```php
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/");
|
||||
|
||||
// Convenience methods
|
||||
$client->text('A plain text message'); // Send an opcode=text message
|
||||
$client->binary($binary_string); // Send an opcode=binary message
|
||||
$client->ping(); // Send an opcode=ping frame
|
||||
$client->pong(); // Send an unsolicited opcode=pong frame
|
||||
|
||||
// Generic send method
|
||||
$client->send($payload); // Sent as masked opcode=text
|
||||
$client->send($payload, 'binary'); // Sent as masked opcode=binary
|
||||
$client->send($payload, 'binary', false); // Sent as unmasked opcode=binary
|
||||
```
|
||||
|
||||
## Constructor options
|
||||
|
||||
The `$options` parameter in constructor accepts an associative array of options.
|
||||
|
||||
* `context` - A stream context created using [stream_context_create](https://www.php.net/manual/en/function.stream-context-create).
|
||||
* `filter` - Array of opcodes to return on receive, default `['text', 'binary']`
|
||||
* `fragment_size` - Maximum payload size. Default 4096 chars.
|
||||
* `headers` - Additional headers as associative array name => content.
|
||||
* `logger` - A [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger.
|
||||
* `persistent` - Connection is re-used between requests until time out is reached. Default false.
|
||||
* `return_obj` - Return a [Message](Message.md) instance on receive, default false
|
||||
* `timeout` - Time out in seconds. Default 5 seconds.
|
||||
|
||||
```php
|
||||
$context = stream_context_create();
|
||||
stream_context_set_option($context, 'ssl', 'verify_peer', false);
|
||||
stream_context_set_option($context, 'ssl', 'verify_peer_name', false);
|
||||
|
||||
$client = new WebSocket\Client("ws://echo.websocket.org/", [
|
||||
'context' => $context, // Attach stream context created above
|
||||
'filter' => ['text', 'binary', 'ping'], // Specify message types for receive() to return
|
||||
'headers' => [ // Additional headers, used to specify subprotocol
|
||||
'Sec-WebSocket-Protocol' => 'soap',
|
||||
'origin' => 'localhost',
|
||||
],
|
||||
'logger' => $my_psr3_logger, // Attach a PSR3 compatible logger
|
||||
'return_obj' => true, // Return Message instance rather than just text
|
||||
'timeout' => 60, // 1 minute time out
|
||||
]);
|
||||
```
|
||||
|
||||
## Exceptions
|
||||
|
||||
* `WebSocket\BadOpcodeException` - Thrown if provided opcode is invalid.
|
||||
* `WebSocket\BadUriException` - Thrown if provided URI is invalid.
|
||||
* `WebSocket\ConnectionException` - Thrown on any socket I/O failure.
|
||||
* `WebSocket\TimeoutException` - Thrown when the socket experiences a time out.
|
||||
44
Server/vendor/textalk/websocket/docs/Contributing.md
vendored
Normal file
44
Server/vendor/textalk/websocket/docs/Contributing.md
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
[Client](Client.md) • [Server](Server.md) • [Message](Message.md) • [Examples](Examples.md) • [Changelog](Changelog.md) • Contributing
|
||||
|
||||
# Websocket: Contributing
|
||||
|
||||
Everyone is welcome to help out!
|
||||
But to keep this project sustainable, please ensure your contribution respects the requirements below.
|
||||
|
||||
## PR Requirements
|
||||
|
||||
Requirements on pull requests;
|
||||
* All tests **MUST** pass.
|
||||
* Code coverage **MUST** remain at 100%.
|
||||
* Code **MUST** adhere to PSR-1 and PSR-12 code standards.
|
||||
|
||||
## Dependency management
|
||||
|
||||
Install or update dependencies using [Composer](https://getcomposer.org/).
|
||||
|
||||
```
|
||||
# Install dependencies
|
||||
make install
|
||||
|
||||
# Update dependencies
|
||||
make update
|
||||
```
|
||||
|
||||
## Code standard
|
||||
|
||||
This project uses [PSR-1](https://www.php-fig.org/psr/psr-1/) and [PSR-12](https://www.php-fig.org/psr/psr-12/) code standards.
|
||||
```
|
||||
# Check code standard adherence
|
||||
make cs-check
|
||||
```
|
||||
|
||||
## Unit testing
|
||||
|
||||
Unit tests with [PHPUnit](https://phpunit.readthedocs.io/), coverage with [Coveralls](https://github.com/php-coveralls/php-coveralls)
|
||||
```
|
||||
# Run unit tests
|
||||
make test
|
||||
|
||||
# Create coverage
|
||||
make coverage
|
||||
```
|
||||
98
Server/vendor/textalk/websocket/docs/Examples.md
vendored
Normal file
98
Server/vendor/textalk/websocket/docs/Examples.md
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
[Client](Client.md) • [Server](Server.md) • [Message](Message.md) • Examples • [Changelog](Changelog.md) • [Contributing](Contributing.md)
|
||||
|
||||
# Websocket: Examples
|
||||
|
||||
Here are some examples on how to use the WebSocket library.
|
||||
|
||||
## Echo logger
|
||||
|
||||
In dev environment (as in having run composer to include dev dependencies) you have
|
||||
access to a simple echo logger that print out information synchronously.
|
||||
|
||||
This is usable for debugging. For production, use a proper logger.
|
||||
|
||||
```php
|
||||
namespace WebSocket;
|
||||
|
||||
$logger = new EchoLogger();
|
||||
|
||||
$client = new Client('ws://echo.websocket.org/');
|
||||
$client->setLogger($logger);
|
||||
|
||||
$server = new Server();
|
||||
$server->setLogger($logger);
|
||||
```
|
||||
|
||||
An example of server output;
|
||||
```
|
||||
info | Server listening to port 8000 []
|
||||
debug | Wrote 129 of 129 bytes. []
|
||||
info | Server connected to port 8000 []
|
||||
info | Received 'text' message []
|
||||
debug | Wrote 9 of 9 bytes. []
|
||||
info | Sent 'text' message []
|
||||
debug | Received 'close', status: 1000. []
|
||||
debug | Wrote 32 of 32 bytes. []
|
||||
info | Sent 'close' message []
|
||||
info | Received 'close' message []
|
||||
```
|
||||
|
||||
## The `send` client
|
||||
|
||||
Source: [examples/send.php](../examples/send.php)
|
||||
|
||||
A simple, single send/receive client.
|
||||
|
||||
Example use:
|
||||
```
|
||||
php examples/send.php --opcode text "A text message" // Send a text message to localhost
|
||||
php examples/send.php --opcode ping "ping it" // Send a ping message to localhost
|
||||
php examples/send.php --uri ws://echo.websocket.org "A text message" // Send a text message to echo.websocket.org
|
||||
php examples/send.php --opcode text --debug "A text message" // Use runtime debugging
|
||||
```
|
||||
|
||||
## The `echoserver` server
|
||||
|
||||
Source: [examples/echoserver.php](../examples/echoserver.php)
|
||||
|
||||
A simple server that responds to recevied commands.
|
||||
|
||||
Example use:
|
||||
```
|
||||
php examples/echoserver.php // Run with default settings
|
||||
php examples/echoserver.php --port 8080 // Listen on port 8080
|
||||
php examples/echoserver.php --debug // Use runtime debugging
|
||||
```
|
||||
|
||||
These strings can be sent as message to trigger server to perform actions;
|
||||
* `exit` - Server will initiate close procedure
|
||||
* `ping` - Server will send a ping message
|
||||
* `headers` - Server will respond with all headers provided by client
|
||||
* `auth` - Server will respond with auth header if provided by client
|
||||
* For other sent strings, server will respond with the same strings
|
||||
|
||||
## The `random` client
|
||||
|
||||
Source: [examples/random_client.php](../examples/random_client.php)
|
||||
|
||||
The random client will use random options and continuously send/receive random messages.
|
||||
|
||||
Example use:
|
||||
```
|
||||
php examples/random_client.php --uri ws://echo.websocket.org // Connect to echo.websocket.org
|
||||
php examples/random_client.php --timeout 5 --fragment_size 16 // Specify settings
|
||||
php examples/random_client.php --debug // Use runtime debugging
|
||||
```
|
||||
|
||||
## The `random` server
|
||||
|
||||
Source: [examples/random_server.php](../examples/random_server.php)
|
||||
|
||||
The random server will use random options and continuously send/receive random messages.
|
||||
|
||||
Example use:
|
||||
```
|
||||
php examples/random_server.php --port 8080 // // Listen on port 8080
|
||||
php examples/random_server.php --timeout 5 --fragment_size 16 // Specify settings
|
||||
php examples/random_server.php --debug // Use runtime debugging
|
||||
```
|
||||
60
Server/vendor/textalk/websocket/docs/Message.md
vendored
Normal file
60
Server/vendor/textalk/websocket/docs/Message.md
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
[Client](Client.md) • [Server](Server.md) • Message • [Examples](Examples.md) • [Changelog](Changelog.md) • [Contributing](Contributing.md)
|
||||
|
||||
# Websocket: Messages
|
||||
|
||||
If option `return_obj` is set to `true` on [client](Client.md) or [server](Server.md),
|
||||
the `receive()` method will return a Message instance instead of a string.
|
||||
|
||||
Available classes correspond to opcode;
|
||||
* WebSocket\Message\Text
|
||||
* WebSocket\Message\Binary
|
||||
* WebSocket\Message\Ping
|
||||
* WebSocket\Message\Pong
|
||||
* WebSocket\Message\Close
|
||||
|
||||
Additionally;
|
||||
* WebSocket\Message\Message - abstract base class for all messages above
|
||||
* WebSocket\Message\Factory - Factory class to create Msssage instances
|
||||
|
||||
## Message abstract class synopsis
|
||||
|
||||
```php
|
||||
WebSocket\Message\Message {
|
||||
|
||||
public __construct(string $payload = '')
|
||||
public __toString() : string
|
||||
|
||||
public getOpcode() : string
|
||||
public getLength() : int
|
||||
public getTimestamp() : DateTime
|
||||
public getContent() : string
|
||||
public setContent(string $payload = '') : void
|
||||
public hasContent() : bool
|
||||
}
|
||||
```
|
||||
|
||||
## Factory class synopsis
|
||||
|
||||
```php
|
||||
WebSocket\Message\Factory {
|
||||
|
||||
public create(string $opcode, string $payload = '') : Message
|
||||
}
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Receving a Message and echo some methods.
|
||||
|
||||
```php
|
||||
$client = new WebSocket\Client('ws://echo.websocket.org/', ['return_obj' => true]);
|
||||
$client->text('Hello WebSocket.org!');
|
||||
// Echo return same message as sent
|
||||
$message = $client->receive();
|
||||
echo $message->getOpcode(); // -> "text"
|
||||
echo $message->getLength(); // -> 20
|
||||
echo $message->getContent(); // -> "Hello WebSocket.org!"
|
||||
echo $message->hasContent(); // -> true
|
||||
echo $message->getTimestamp()->format('H:i:s'); // -> 19:37:18
|
||||
$client->close();
|
||||
```
|
||||
136
Server/vendor/textalk/websocket/docs/Server.md
vendored
Normal file
136
Server/vendor/textalk/websocket/docs/Server.md
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
[Client](Client.md) • Server • [Message](Message.md) • [Examples](Examples.md) • [Changelog](Changelog.md) • [Contributing](Contributing.md)
|
||||
|
||||
# Websocket: Server
|
||||
|
||||
The library contains a rudimentary single stream/single thread server.
|
||||
It internally supports Upgrade handshake and implicit close and ping/pong operations.
|
||||
|
||||
Note that it does **not** support threading or automatic association ot continuous client requests.
|
||||
If you require this kind of server behavior, you need to build it on top of provided server implementation.
|
||||
|
||||
## Class synopsis
|
||||
|
||||
```php
|
||||
WebSocket\Server {
|
||||
|
||||
public __construct(array $options = [])
|
||||
public __destruct()
|
||||
public __toString() : string
|
||||
|
||||
public accept() : bool
|
||||
public text(string $payload) : void
|
||||
public binary(string $payload) : void
|
||||
public ping(string $payload = '') : void
|
||||
public pong(string $payload = '') : void
|
||||
public send(mixed $payload, string $opcode = 'text', bool $masked = true) : void
|
||||
public receive() : mixed
|
||||
public close(int $status = 1000, mixed $message = 'ttfn') : mixed
|
||||
|
||||
public getPort() : int
|
||||
public getPath() : string
|
||||
public getRequest() : array
|
||||
public getHeader(string $header_name) : string|null
|
||||
|
||||
public getName() : string|null
|
||||
public getPier() : string|null
|
||||
public getLastOpcode() : string
|
||||
public getCloseStatus() : int
|
||||
public isConnected() : bool
|
||||
public setTimeout(int $seconds) : void
|
||||
public setFragmentSize(int $fragment_size) : self
|
||||
public getFragmentSize() : int
|
||||
public setLogger(Psr\Log\LoggerInterface $logger = null) : void
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple receive-send operation
|
||||
|
||||
This example reads a single message from a client, and respond with the same message.
|
||||
|
||||
```php
|
||||
$server = new WebSocket\Server();
|
||||
$server->accept();
|
||||
$message = $server->receive();
|
||||
$server->text($message);
|
||||
$server->close();
|
||||
```
|
||||
|
||||
### Listening to clients
|
||||
|
||||
To continuously listen to incoming messages, you need to put the receive operation within a loop.
|
||||
Note that these functions **always** throw exception on any failure, including recoverable failures such as connection time out.
|
||||
By consuming exceptions, the code will re-connect the socket in next loop iteration.
|
||||
|
||||
```php
|
||||
$server = new WebSocket\Server();
|
||||
while ($server->accept()) {
|
||||
try {
|
||||
$message = $server->receive();
|
||||
// Act on received message
|
||||
// Break while loop to stop listening
|
||||
} catch (\WebSocket\ConnectionException $e) {
|
||||
// Possibly log errors
|
||||
}
|
||||
}
|
||||
$server->close();
|
||||
```
|
||||
|
||||
### Filtering received messages
|
||||
|
||||
By default the `receive()` method return messages of 'text' and 'binary' opcode.
|
||||
The filter option allows you to specify which message types to return.
|
||||
|
||||
```php
|
||||
$server = new WebSocket\Server(['filter' => ['text']]);
|
||||
$server->receive(); // only return 'text' messages
|
||||
|
||||
$server = new WebSocket\Server(['filter' => ['text', 'binary', 'ping', 'pong', 'close']]);
|
||||
$server->receive(); // return all messages
|
||||
```
|
||||
|
||||
### Sending messages
|
||||
|
||||
There are convenience methods to send messages with different opcodes.
|
||||
```php
|
||||
$server = new WebSocket\Server();
|
||||
|
||||
// Convenience methods
|
||||
$server->text('A plain text message'); // Send an opcode=text message
|
||||
$server->binary($binary_string); // Send an opcode=binary message
|
||||
$server->ping(); // Send an opcode=ping frame
|
||||
$server->pong(); // Send an unsolicited opcode=pong frame
|
||||
|
||||
// Generic send method
|
||||
$server->send($payload); // Sent as masked opcode=text
|
||||
$server->send($payload, 'binary'); // Sent as masked opcode=binary
|
||||
$server->send($payload, 'binary', false); // Sent as unmasked opcode=binary
|
||||
```
|
||||
|
||||
## Constructor options
|
||||
|
||||
The `$options` parameter in constructor accepts an associative array of options.
|
||||
|
||||
* `filter` - Array of opcodes to return on receive, default `['text', 'binary']`
|
||||
* `fragment_size` - Maximum payload size. Default 4096 chars.
|
||||
* `logger` - A [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger.
|
||||
* `port` - The server port to listen to. Default 8000.
|
||||
* `return_obj` - Return a [Message](Message.md) instance on receive, default false
|
||||
* `timeout` - Time out in seconds. Default 5 seconds.
|
||||
|
||||
```php
|
||||
$server = new WebSocket\Server([
|
||||
'filter' => ['text', 'binary', 'ping'], // Specify message types for receive() to return
|
||||
'logger' => $my_psr3_logger, // Attach a PSR3 compatible logger
|
||||
'port' => 9000, // Listening port
|
||||
'return_obj' => true, // Return Message insatnce rather than just text
|
||||
'timeout' => 60, // 1 minute time out
|
||||
]);
|
||||
```
|
||||
|
||||
## Exceptions
|
||||
|
||||
* `WebSocket\BadOpcodeException` - Thrown if provided opcode is invalid.
|
||||
* `WebSocket\ConnectionException` - Thrown on any socket I/O failure.
|
||||
* `WebSocket\TimeoutException` - Thrown when the socket experiences a time out.
|
||||
87
Server/vendor/textalk/websocket/examples/echoserver.php
vendored
Normal file
87
Server/vendor/textalk/websocket/examples/echoserver.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is used for the tests, but can also serve as an example of a WebSocket\Server.
|
||||
* Run in console: php examples/echoserver.php
|
||||
*
|
||||
* Console options:
|
||||
* --port <int> : The port to listen to, default 8000
|
||||
* --timeout <int> : Timeout in seconds, default 200 seconds
|
||||
* --debug : Output log data (if logger is available)
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
echo "> Random server\n";
|
||||
|
||||
// Server options specified or random
|
||||
$options = array_merge([
|
||||
'port' => 8000,
|
||||
'timeout' => 200,
|
||||
'filter' => ['text', 'binary', 'ping', 'pong'],
|
||||
], getopt('', ['port:', 'timeout:', 'debug']));
|
||||
|
||||
// If debug mode and logger is available
|
||||
if (isset($options['debug']) && class_exists('WebSocket\EchoLog')) {
|
||||
$logger = new EchoLog();
|
||||
$options['logger'] = $logger;
|
||||
echo "> Using logger\n";
|
||||
}
|
||||
|
||||
// Setting timeout to 200 seconds to make time for all tests and manual runs.
|
||||
try {
|
||||
$server = new Server($options);
|
||||
} catch (ConnectionException $e) {
|
||||
echo "> ERROR: {$e->getMessage()}\n";
|
||||
die();
|
||||
}
|
||||
|
||||
echo "> Listening to port {$server->getPort()}\n";
|
||||
|
||||
// Force quit to close server
|
||||
while (true) {
|
||||
try {
|
||||
while ($server->accept()) {
|
||||
echo "> Accepted on port {$server->getPort()}\n";
|
||||
while (true) {
|
||||
$message = $server->receive();
|
||||
$opcode = $server->getLastOpcode();
|
||||
if (is_null($message)) {
|
||||
echo "> Closing connection\n";
|
||||
continue 2;
|
||||
}
|
||||
echo "> Got '{$message}' [opcode: {$opcode}]\n";
|
||||
if (in_array($opcode, ['ping', 'pong'])) {
|
||||
$server->send($message);
|
||||
continue;
|
||||
}
|
||||
// Allow certain string to trigger server action
|
||||
switch ($message) {
|
||||
case 'exit':
|
||||
echo "> Client told me to quit. Bye bye.\n";
|
||||
$server->close();
|
||||
echo "> Close status: {$server->getCloseStatus()}\n";
|
||||
exit;
|
||||
case 'headers':
|
||||
$server->text(implode("\r\n", $server->getRequest()));
|
||||
break;
|
||||
case 'ping':
|
||||
$server->ping($message);
|
||||
break;
|
||||
case 'auth':
|
||||
$auth = $server->getHeader('Authorization');
|
||||
$server->text("{$auth} - {$message}");
|
||||
break;
|
||||
default:
|
||||
$server->text($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ConnectionException $e) {
|
||||
echo "> ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
94
Server/vendor/textalk/websocket/examples/random_client.php
vendored
Normal file
94
Server/vendor/textalk/websocket/examples/random_client.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Websocket client that read/write random data.
|
||||
* Run in console: php examples/random_client.php
|
||||
*
|
||||
* Console options:
|
||||
* --uri <uri> : The URI to connect to, default ws://localhost:8000
|
||||
* --timeout <int> : Timeout in seconds, random default
|
||||
* --fragment_size <int> : Fragment size as bytes, random default
|
||||
* --debug : Output log data (if logger is available)
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
$randStr = function (int $maxlength = 4096) {
|
||||
$string = '';
|
||||
$length = rand(1, $maxlength);
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= chr(rand(33, 126));
|
||||
}
|
||||
return $string;
|
||||
};
|
||||
|
||||
echo "> Random client\n";
|
||||
|
||||
// Server options specified or random
|
||||
$options = array_merge([
|
||||
'uri' => 'ws://localhost:8000',
|
||||
'timeout' => rand(1, 60),
|
||||
'fragment_size' => rand(1, 4096) * 8,
|
||||
], getopt('', ['uri:', 'timeout:', 'fragment_size:', 'debug']));
|
||||
|
||||
// If debug mode and logger is available
|
||||
if (isset($options['debug']) && class_exists('WebSocket\EchoLog')) {
|
||||
$logger = new EchoLog();
|
||||
$options['logger'] = $logger;
|
||||
echo "> Using logger\n";
|
||||
}
|
||||
|
||||
// Main loop
|
||||
while (true) {
|
||||
try {
|
||||
$client = new Client($options['uri'], $options);
|
||||
$info = json_encode([
|
||||
'uri' => $options['uri'],
|
||||
'timeout' => $options['timeout'],
|
||||
'framgemt_size' => $client->getFragmentSize(),
|
||||
]);
|
||||
echo "> Creating client {$info}\n";
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
// Random actions
|
||||
switch (rand(1, 10)) {
|
||||
case 1:
|
||||
echo "> Sending text\n";
|
||||
$client->text("Text message {$randStr()}");
|
||||
break;
|
||||
case 2:
|
||||
echo "> Sending binary\n";
|
||||
$client->binary("Binary message {$randStr()}");
|
||||
break;
|
||||
case 3:
|
||||
echo "> Sending close\n";
|
||||
$client->close(rand(1000, 2000), "Close message {$randStr(8)}");
|
||||
break;
|
||||
case 4:
|
||||
echo "> Sending ping\n";
|
||||
$client->ping("Ping message {$randStr(8)}");
|
||||
break;
|
||||
case 5:
|
||||
echo "> Sending pong\n";
|
||||
$client->pong("Pong message {$randStr(8)}");
|
||||
break;
|
||||
default:
|
||||
echo "> Receiving\n";
|
||||
$received = $client->receive();
|
||||
echo "> Received {$client->getLastOpcode()}: {$received}\n";
|
||||
}
|
||||
sleep(rand(1, 5));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "ERROR I/O: {$e->getMessage()} [{$e->getCode()}]\n";
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "ERROR: {$e->getMessage()} [{$e->getCode()}]\n";
|
||||
}
|
||||
sleep(rand(1, 5));
|
||||
}
|
||||
93
Server/vendor/textalk/websocket/examples/random_server.php
vendored
Normal file
93
Server/vendor/textalk/websocket/examples/random_server.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Websocket server that read/write random data.
|
||||
* Run in console: php examples/random_server.php
|
||||
*
|
||||
* Console options:
|
||||
* --port <int> : The port to listen to, default 8000
|
||||
* --timeout <int> : Timeout in seconds, random default
|
||||
* --fragment_size <int> : Fragment size as bytes, random default
|
||||
* --debug : Output log data (if logger is available)
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
$randStr = function (int $maxlength = 4096) {
|
||||
$string = '';
|
||||
$length = rand(1, $maxlength);
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= chr(rand(33, 126));
|
||||
}
|
||||
return $string;
|
||||
};
|
||||
|
||||
echo "> Random server\n";
|
||||
|
||||
// Server options specified or random
|
||||
$options = array_merge([
|
||||
'port' => 8000,
|
||||
'timeout' => rand(1, 60),
|
||||
'fragment_size' => rand(1, 4096) * 8,
|
||||
], getopt('', ['port:', 'timeout:', 'fragment_size:', 'debug']));
|
||||
|
||||
// If debug mode and logger is available
|
||||
if (isset($options['debug']) && class_exists('WebSocket\EchoLog')) {
|
||||
$logger = new EchoLog();
|
||||
$options['logger'] = $logger;
|
||||
echo "> Using logger\n";
|
||||
}
|
||||
|
||||
// Force quit to close server
|
||||
while (true) {
|
||||
try {
|
||||
// Setup server
|
||||
$server = new Server($options);
|
||||
$info = json_encode([
|
||||
'port' => $server->getPort(),
|
||||
'timeout' => $options['timeout'],
|
||||
'framgemt_size' => $server->getFragmentSize(),
|
||||
]);
|
||||
echo "> Creating server {$info}\n";
|
||||
|
||||
while ($server->accept()) {
|
||||
while (true) {
|
||||
// Random actions
|
||||
switch (rand(1, 10)) {
|
||||
case 1:
|
||||
echo "> Sending text\n";
|
||||
$server->text("Text message {$randStr()}");
|
||||
break;
|
||||
case 2:
|
||||
echo "> Sending binary\n";
|
||||
$server->binary("Binary message {$randStr()}");
|
||||
break;
|
||||
case 3:
|
||||
echo "> Sending close\n";
|
||||
$server->close(rand(1000, 2000), "Close message {$randStr(8)}");
|
||||
break;
|
||||
case 4:
|
||||
echo "> Sending ping\n";
|
||||
$server->ping("Ping message {$randStr(8)}");
|
||||
break;
|
||||
case 5:
|
||||
echo "> Sending pong\n";
|
||||
$server->pong("Pong message {$randStr(8)}");
|
||||
break;
|
||||
default:
|
||||
echo "> Receiving\n";
|
||||
$received = $server->receive();
|
||||
echo "> Received {$server->getLastOpcode()}: {$received}\n";
|
||||
}
|
||||
sleep(rand(1, 5));
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
echo "ERROR: {$e->getMessage()} [{$e->getCode()}]\n";
|
||||
}
|
||||
sleep(rand(1, 5));
|
||||
}
|
||||
51
Server/vendor/textalk/websocket/examples/send.php
vendored
Normal file
51
Server/vendor/textalk/websocket/examples/send.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Simple send & receive client for test purpose.
|
||||
* Run in console: php examples/send.php <options> <message>
|
||||
*
|
||||
* Console options:
|
||||
* --uri <uri> : The URI to connect to, default ws://localhost:8000
|
||||
* --opcode <string> : Opcode to send, default 'text'
|
||||
* --debug : Output log data (if logger is available)
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
echo "> Send client\n";
|
||||
|
||||
// Server options specified or random
|
||||
$options = array_merge([
|
||||
'uri' => 'ws://localhost:8000',
|
||||
'opcode' => 'text',
|
||||
], getopt('', ['uri:', 'opcode:', 'debug']));
|
||||
$message = array_pop($argv);
|
||||
|
||||
// If debug mode and logger is available
|
||||
if (isset($options['debug']) && class_exists('WebSocket\EchoLog')) {
|
||||
$logger = new EchoLog();
|
||||
$options['logger'] = $logger;
|
||||
echo "> Using logger\n";
|
||||
}
|
||||
|
||||
try {
|
||||
// Create client, send and recevie
|
||||
$client = new Client($options['uri'], $options);
|
||||
$client->send($message, $options['opcode']);
|
||||
echo "> Sent '{$message}' [opcode: {$options['opcode']}]\n";
|
||||
if (in_array($options['opcode'], ['text', 'binary'])) {
|
||||
$message = $client->receive();
|
||||
$opcode = $client->getLastOpcode();
|
||||
if (!is_null($message)) {
|
||||
echo "> Got '{$message}' [opcode: {$opcode}]\n";
|
||||
}
|
||||
}
|
||||
$client->close();
|
||||
echo "> Closing client\n";
|
||||
} catch (\Throwable $e) {
|
||||
echo "ERROR: {$e->getMessage()} [{$e->getCode()}]\n";
|
||||
}
|
||||
7
Server/vendor/textalk/websocket/lib/BadOpcodeException.php
vendored
Normal file
7
Server/vendor/textalk/websocket/lib/BadOpcodeException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class BadOpcodeException extends Exception
|
||||
{
|
||||
}
|
||||
7
Server/vendor/textalk/websocket/lib/BadUriException.php
vendored
Normal file
7
Server/vendor/textalk/websocket/lib/BadUriException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class BadUriException extends Exception
|
||||
{
|
||||
}
|
||||
486
Server/vendor/textalk/websocket/lib/Base.php
vendored
Normal file
486
Server/vendor/textalk/websocket/lib/Base.php
vendored
Normal file
@@ -0,0 +1,486 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2014-2020 Textalk/Abicart and contributors.
|
||||
*
|
||||
* This file is part of Websocket PHP and is free software under the ISC License.
|
||||
* License text: https://raw.githubusercontent.com/Textalk/websocket-php/master/COPYING
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use Psr\Log\{LoggerAwareInterface, LoggerInterface, NullLogger};
|
||||
use WebSocket\Message\Factory;
|
||||
|
||||
class Base implements LoggerAwareInterface
|
||||
{
|
||||
protected $socket;
|
||||
protected $options = [];
|
||||
protected $is_closing = false;
|
||||
protected $last_opcode = null;
|
||||
protected $close_status = null;
|
||||
protected $logger;
|
||||
private $read_buffer;
|
||||
|
||||
protected static $opcodes = [
|
||||
'continuation' => 0,
|
||||
'text' => 1,
|
||||
'binary' => 2,
|
||||
'close' => 8,
|
||||
'ping' => 9,
|
||||
'pong' => 10,
|
||||
];
|
||||
|
||||
public function getLastOpcode(): ?string
|
||||
{
|
||||
return $this->last_opcode;
|
||||
}
|
||||
|
||||
public function getCloseStatus(): ?int
|
||||
{
|
||||
return $this->close_status;
|
||||
}
|
||||
|
||||
public function isConnected(): bool
|
||||
{
|
||||
return $this->socket &&
|
||||
(get_resource_type($this->socket) == 'stream' ||
|
||||
get_resource_type($this->socket) == 'persistent stream');
|
||||
}
|
||||
|
||||
public function setTimeout(int $timeout): void
|
||||
{
|
||||
$this->options['timeout'] = $timeout;
|
||||
|
||||
if ($this->isConnected()) {
|
||||
stream_set_timeout($this->socket, $timeout);
|
||||
}
|
||||
}
|
||||
|
||||
public function setFragmentSize(int $fragment_size): self
|
||||
{
|
||||
$this->options['fragment_size'] = $fragment_size;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFragmentSize(): int
|
||||
{
|
||||
return $this->options['fragment_size'];
|
||||
}
|
||||
|
||||
public function setLogger(LoggerInterface $logger = null): void
|
||||
{
|
||||
$this->logger = $logger ?: new NullLogger();
|
||||
}
|
||||
|
||||
public function send(string $payload, string $opcode = 'text', bool $masked = true): void
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if (!in_array($opcode, array_keys(self::$opcodes))) {
|
||||
$warning = "Bad opcode '{$opcode}'. Try 'text' or 'binary'.";
|
||||
$this->logger->warning($warning);
|
||||
throw new BadOpcodeException($warning);
|
||||
}
|
||||
|
||||
$payload_chunks = str_split($payload, $this->options['fragment_size']);
|
||||
$frame_opcode = $opcode;
|
||||
|
||||
for ($index = 0; $index < count($payload_chunks); ++$index) {
|
||||
$chunk = $payload_chunks[$index];
|
||||
$final = $index == count($payload_chunks) - 1;
|
||||
|
||||
$this->sendFragment($final, $chunk, $frame_opcode, $masked);
|
||||
|
||||
// all fragments after the first will be marked a continuation
|
||||
$frame_opcode = 'continuation';
|
||||
}
|
||||
|
||||
$this->logger->info("Sent '{$opcode}' message", [
|
||||
'opcode' => $opcode,
|
||||
'content-length' => strlen($payload),
|
||||
'frames' => count($payload_chunks),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to send text message
|
||||
* @param string $payload Content as string
|
||||
*/
|
||||
public function text(string $payload): void
|
||||
{
|
||||
$this->send($payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to send binary message
|
||||
* @param string $payload Content as binary string
|
||||
*/
|
||||
public function binary(string $payload): void
|
||||
{
|
||||
$this->send($payload, 'binary');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to send ping
|
||||
* @param string $payload Optional text as string
|
||||
*/
|
||||
public function ping(string $payload = ''): void
|
||||
{
|
||||
$this->send($payload, 'ping');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to send unsolicited pong
|
||||
* @param string $payload Optional text as string
|
||||
*/
|
||||
public function pong(string $payload = ''): void
|
||||
{
|
||||
$this->send($payload, 'pong');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of local socket, or null if not connected
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->isConnected() ? stream_socket_get_name($this->socket, false) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of remote socket, or null if not connected
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPier(): ?string
|
||||
{
|
||||
return $this->isConnected() ? stream_socket_get_name($this->socket, true) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation of instance
|
||||
* @return string String representation
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
"%s(%s)",
|
||||
get_class($this),
|
||||
$this->getName() ?: 'closed'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive one message.
|
||||
* Will continue reading until read message match filter settings.
|
||||
* Return Message instance or string according to settings.
|
||||
*/
|
||||
protected function sendFragment(bool $final, string $payload, string $opcode, bool $masked): void
|
||||
{
|
||||
$data = '';
|
||||
|
||||
$byte_1 = $final ? 0b10000000 : 0b00000000; // Final fragment marker.
|
||||
$byte_1 |= self::$opcodes[$opcode]; // Set opcode.
|
||||
$data .= pack('C', $byte_1);
|
||||
|
||||
$byte_2 = $masked ? 0b10000000 : 0b00000000; // Masking bit marker.
|
||||
|
||||
// 7 bits of payload length...
|
||||
$payload_length = strlen($payload);
|
||||
if ($payload_length > 65535) {
|
||||
$data .= pack('C', $byte_2 | 0b01111111);
|
||||
$data .= pack('J', $payload_length);
|
||||
} elseif ($payload_length > 125) {
|
||||
$data .= pack('C', $byte_2 | 0b01111110);
|
||||
$data .= pack('n', $payload_length);
|
||||
} else {
|
||||
$data .= pack('C', $byte_2 | $payload_length);
|
||||
}
|
||||
|
||||
// Handle masking
|
||||
if ($masked) {
|
||||
// generate a random mask:
|
||||
$mask = '';
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$mask .= chr(rand(0, 255));
|
||||
}
|
||||
$data .= $mask;
|
||||
|
||||
// Append payload to frame:
|
||||
for ($i = 0; $i < $payload_length; $i++) {
|
||||
$data .= $payload[$i] ^ $mask[$i % 4];
|
||||
}
|
||||
} else {
|
||||
$data .= $payload;
|
||||
}
|
||||
|
||||
$this->write($data);
|
||||
$this->logger->debug("Sent '{$opcode}' frame", [
|
||||
'opcode' => $opcode,
|
||||
'final' => $final,
|
||||
'content-length' => strlen($payload),
|
||||
]);
|
||||
}
|
||||
|
||||
public function receive()
|
||||
{
|
||||
$filter = $this->options['filter'];
|
||||
if (!$this->isConnected()) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
do {
|
||||
$response = $this->receiveFragment();
|
||||
list ($payload, $final, $opcode) = $response;
|
||||
|
||||
// Continuation and factual opcode
|
||||
$continuation = ($opcode == 'continuation');
|
||||
$payload_opcode = $continuation ? $this->read_buffer['opcode'] : $opcode;
|
||||
|
||||
// Filter frames
|
||||
if (!in_array($payload_opcode, $filter)) {
|
||||
if ($payload_opcode == 'close') {
|
||||
return null; // Always abort receive on close
|
||||
}
|
||||
$final = false;
|
||||
continue; // Continue reading
|
||||
}
|
||||
|
||||
// First continuation frame, create buffer
|
||||
if (!$final && !$continuation) {
|
||||
$this->read_buffer = ['opcode' => $opcode, 'payload' => $payload, 'frames' => 1];
|
||||
continue; // Continue reading
|
||||
}
|
||||
|
||||
// Subsequent continuation frames, add to buffer
|
||||
if ($continuation) {
|
||||
$this->read_buffer['payload'] .= $payload;
|
||||
$this->read_buffer['frames']++;
|
||||
}
|
||||
} while (!$final);
|
||||
|
||||
// Final, return payload
|
||||
$frames = 1;
|
||||
if ($continuation) {
|
||||
$payload = $this->read_buffer['payload'];
|
||||
$frames = $this->read_buffer['frames'];
|
||||
$this->read_buffer = null;
|
||||
}
|
||||
$this->logger->info("Received '{opcode}' message", [
|
||||
'opcode' => $payload_opcode,
|
||||
'content-length' => strlen($payload),
|
||||
'frames' => $frames,
|
||||
]);
|
||||
|
||||
$this->last_opcode = $payload_opcode;
|
||||
$factory = new Factory();
|
||||
return $this->options['return_obj']
|
||||
? $factory->create($payload_opcode, $payload)
|
||||
: $payload;
|
||||
}
|
||||
|
||||
protected function receiveFragment(): array
|
||||
{
|
||||
// Read the fragment "header" first, two bytes.
|
||||
$data = $this->read(2);
|
||||
list ($byte_1, $byte_2) = array_values(unpack('C*', $data));
|
||||
|
||||
$final = (bool)($byte_1 & 0b10000000); // Final fragment marker.
|
||||
$rsv = $byte_1 & 0b01110000; // Unused bits, ignore
|
||||
|
||||
// Parse opcode
|
||||
$opcode_int = $byte_1 & 0b00001111;
|
||||
$opcode_ints = array_flip(self::$opcodes);
|
||||
if (!array_key_exists($opcode_int, $opcode_ints)) {
|
||||
$warning = "Bad opcode in websocket frame: {$opcode_int}";
|
||||
$this->logger->warning($warning);
|
||||
throw new ConnectionException($warning, ConnectionException::BAD_OPCODE);
|
||||
}
|
||||
$opcode = $opcode_ints[$opcode_int];
|
||||
|
||||
// Masking bit
|
||||
$mask = (bool)($byte_2 & 0b10000000);
|
||||
|
||||
$payload = '';
|
||||
|
||||
// Payload length
|
||||
$payload_length = $byte_2 & 0b01111111;
|
||||
|
||||
if ($payload_length > 125) {
|
||||
if ($payload_length === 126) {
|
||||
$data = $this->read(2); // 126: Payload is a 16-bit unsigned int
|
||||
$payload_length = current(unpack('n', $data));
|
||||
} else {
|
||||
$data = $this->read(8); // 127: Payload is a 64-bit unsigned int
|
||||
$payload_length = current(unpack('J', $data));
|
||||
}
|
||||
}
|
||||
|
||||
// Get masking key.
|
||||
if ($mask) {
|
||||
$masking_key = $this->read(4);
|
||||
}
|
||||
|
||||
// Get the actual payload, if any (might not be for e.g. close frames.
|
||||
if ($payload_length > 0) {
|
||||
$data = $this->read($payload_length);
|
||||
|
||||
if ($mask) {
|
||||
// Unmask payload.
|
||||
for ($i = 0; $i < $payload_length; $i++) {
|
||||
$payload .= ($data[$i] ^ $masking_key[$i % 4]);
|
||||
}
|
||||
} else {
|
||||
$payload = $data;
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->debug("Read '{opcode}' frame", [
|
||||
'opcode' => $opcode,
|
||||
'final' => $final,
|
||||
'content-length' => strlen($payload),
|
||||
]);
|
||||
|
||||
// if we received a ping, send a pong and wait for the next message
|
||||
if ($opcode === 'ping') {
|
||||
$this->logger->debug("Received 'ping', sending 'pong'.");
|
||||
$this->send($payload, 'pong', true);
|
||||
return [$payload, true, $opcode];
|
||||
}
|
||||
|
||||
// if we received a pong, wait for the next message
|
||||
if ($opcode === 'pong') {
|
||||
$this->logger->debug("Received 'pong'.");
|
||||
return [$payload, true, $opcode];
|
||||
}
|
||||
|
||||
if ($opcode === 'close') {
|
||||
$status_bin = '';
|
||||
$status = '';
|
||||
// Get the close status.
|
||||
$status_bin = '';
|
||||
$status = '';
|
||||
if ($payload_length > 0) {
|
||||
$status_bin = $payload[0] . $payload[1];
|
||||
$status = current(unpack('n', $payload));
|
||||
$this->close_status = $status;
|
||||
}
|
||||
// Get additional close message
|
||||
if ($payload_length >= 2) {
|
||||
$payload = substr($payload, 2);
|
||||
}
|
||||
|
||||
$this->logger->debug("Received 'close', status: {$this->close_status}.");
|
||||
|
||||
if ($this->is_closing) {
|
||||
$this->is_closing = false; // A close response, all done.
|
||||
} else {
|
||||
$this->send($status_bin . 'Close acknowledged: ' . $status, 'close', true); // Respond.
|
||||
}
|
||||
|
||||
// Close the socket.
|
||||
fclose($this->socket);
|
||||
|
||||
// Closing should not return message.
|
||||
return [$payload, true, $opcode];
|
||||
}
|
||||
|
||||
return [$payload, $final, $opcode];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the socket to close.
|
||||
*
|
||||
* @param integer $status http://tools.ietf.org/html/rfc6455#section-7.4
|
||||
* @param string $message A closing message, max 125 bytes.
|
||||
*/
|
||||
public function close(int $status = 1000, string $message = 'ttfn'): void
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
return;
|
||||
}
|
||||
$status_binstr = sprintf('%016b', $status);
|
||||
$status_str = '';
|
||||
foreach (str_split($status_binstr, 8) as $binstr) {
|
||||
$status_str .= chr(bindec($binstr));
|
||||
}
|
||||
$this->send($status_str . $message, 'close', true);
|
||||
$this->logger->debug("Closing with status: {$status_str}.");
|
||||
|
||||
$this->is_closing = true;
|
||||
$this->receive(); // Receiving a close frame will close the socket now.
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from client/server.
|
||||
*/
|
||||
public function disconnect(): void
|
||||
{
|
||||
if ($this->isConnected()) {
|
||||
fclose($this->socket);
|
||||
$this->socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function write(string $data): void
|
||||
{
|
||||
$length = strlen($data);
|
||||
$written = @fwrite($this->socket, $data);
|
||||
if ($written === false) {
|
||||
$this->throwException("Failed to write {$length} bytes.");
|
||||
}
|
||||
if ($written < strlen($data)) {
|
||||
$this->throwException("Could only write {$written} out of {$length} bytes.");
|
||||
}
|
||||
$this->logger->debug("Wrote {$written} of {$length} bytes.");
|
||||
}
|
||||
|
||||
protected function read(string $length): string
|
||||
{
|
||||
$data = '';
|
||||
while (strlen($data) < $length) {
|
||||
$buffer = @fread($this->socket, $length - strlen($data));
|
||||
|
||||
if (!$buffer) {
|
||||
$meta = stream_get_meta_data($this->socket);
|
||||
if (!empty($meta['timed_out'])) {
|
||||
$message = 'Client read timeout';
|
||||
$this->logger->error($message, $meta);
|
||||
throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta);
|
||||
}
|
||||
}
|
||||
if ($buffer === false) {
|
||||
$read = strlen($data);
|
||||
$this->throwException("Broken frame, read {$read} of stated {$length} bytes.");
|
||||
}
|
||||
if ($buffer === '') {
|
||||
$this->throwException("Empty read; connection dead?");
|
||||
}
|
||||
$data .= $buffer;
|
||||
$read = strlen($data);
|
||||
$this->logger->debug("Read {$read} of {$length} bytes.");
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function throwException(string $message, int $code = 0): void
|
||||
{
|
||||
$meta = ['closed' => true];
|
||||
if ($this->isConnected()) {
|
||||
$meta = stream_get_meta_data($this->socket);
|
||||
fclose($this->socket);
|
||||
$this->socket = null;
|
||||
}
|
||||
if (!empty($meta['timed_out'])) {
|
||||
$this->logger->error($message, $meta);
|
||||
throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta);
|
||||
}
|
||||
if (!empty($meta['eof'])) {
|
||||
$code = ConnectionException::EOF;
|
||||
}
|
||||
$this->logger->error($message, $meta);
|
||||
throw new ConnectionException($message, $code, $meta);
|
||||
}
|
||||
}
|
||||
226
Server/vendor/textalk/websocket/lib/Client.php
vendored
Normal file
226
Server/vendor/textalk/websocket/lib/Client.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2014-2020 Textalk/Abicart and contributors.
|
||||
*
|
||||
* This file is part of Websocket PHP and is free software under the ISC License.
|
||||
* License text: https://raw.githubusercontent.com/Textalk/websocket-php/master/COPYING
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class Client extends Base
|
||||
{
|
||||
// Default options
|
||||
protected static $default_options = [
|
||||
'context' => null,
|
||||
'filter' => ['text', 'binary'],
|
||||
'fragment_size' => 4096,
|
||||
'headers' => null,
|
||||
'logger' => null,
|
||||
'origin' => null, // @deprecated
|
||||
'persistent' => false,
|
||||
'return_obj' => false,
|
||||
'timeout' => 5,
|
||||
];
|
||||
|
||||
protected $socket_uri;
|
||||
|
||||
/**
|
||||
* @param string $uri A ws/wss-URI
|
||||
* @param array $options
|
||||
* Associative array containing:
|
||||
* - context: Set the stream context. Default: empty context
|
||||
* - timeout: Set the socket timeout in seconds. Default: 5
|
||||
* - fragment_size: Set framgemnt size. Default: 4096
|
||||
* - headers: Associative array of headers to set/override.
|
||||
*/
|
||||
public function __construct(string $uri, array $options = [])
|
||||
{
|
||||
$this->options = array_merge(self::$default_options, $options);
|
||||
$this->socket_uri = $uri;
|
||||
$this->setLogger($this->options['logger']);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->isConnected() && get_resource_type($this->socket) !== 'persistent stream') {
|
||||
fclose($this->socket);
|
||||
}
|
||||
$this->socket = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform WebSocket handshake
|
||||
*/
|
||||
protected function connect(): void
|
||||
{
|
||||
$url_parts = parse_url($this->socket_uri);
|
||||
if (empty($url_parts) || empty($url_parts['scheme']) || empty($url_parts['host'])) {
|
||||
$error = "Invalid url '{$this->socket_uri}' provided.";
|
||||
$this->logger->error($error);
|
||||
throw new BadUriException($error);
|
||||
}
|
||||
$scheme = $url_parts['scheme'];
|
||||
$host = $url_parts['host'];
|
||||
$user = isset($url_parts['user']) ? $url_parts['user'] : '';
|
||||
$pass = isset($url_parts['pass']) ? $url_parts['pass'] : '';
|
||||
$port = isset($url_parts['port']) ? $url_parts['port'] : ($scheme === 'wss' ? 443 : 80);
|
||||
$path = isset($url_parts['path']) ? $url_parts['path'] : '/';
|
||||
$query = isset($url_parts['query']) ? $url_parts['query'] : '';
|
||||
$fragment = isset($url_parts['fragment']) ? $url_parts['fragment'] : '';
|
||||
|
||||
$path_with_query = $path;
|
||||
if (!empty($query)) {
|
||||
$path_with_query .= '?' . $query;
|
||||
}
|
||||
if (!empty($fragment)) {
|
||||
$path_with_query .= '#' . $fragment;
|
||||
}
|
||||
|
||||
if (!in_array($scheme, ['ws', 'wss'])) {
|
||||
$error = "Url should have scheme ws or wss, not '{$scheme}' from URI '{$this->socket_uri}'.";
|
||||
$this->logger->error($error);
|
||||
throw new BadUriException($error);
|
||||
}
|
||||
|
||||
$host_uri = ($scheme === 'wss' ? 'ssl' : 'tcp') . '://' . $host;
|
||||
|
||||
// Set the stream context options if they're already set in the config
|
||||
if (isset($this->options['context'])) {
|
||||
// Suppress the error since we'll catch it below
|
||||
if (@get_resource_type($this->options['context']) === 'stream-context') {
|
||||
$context = $this->options['context'];
|
||||
} else {
|
||||
$error = "Stream context in \$options['context'] isn't a valid context.";
|
||||
$this->logger->error($error);
|
||||
throw new \InvalidArgumentException($error);
|
||||
}
|
||||
} else {
|
||||
$context = stream_context_create();
|
||||
}
|
||||
|
||||
$persistent = $this->options['persistent'] === true;
|
||||
$flags = STREAM_CLIENT_CONNECT;
|
||||
$flags = $persistent ? $flags | STREAM_CLIENT_PERSISTENT : $flags;
|
||||
|
||||
$error = $errno = $errstr = null;
|
||||
set_error_handler(function (int $severity, string $message, string $file, int $line) use (&$error) {
|
||||
$this->logger->warning($message, ['severity' => $severity]);
|
||||
$error = $message;
|
||||
}, E_ALL);
|
||||
|
||||
// Open the socket.
|
||||
$this->socket = stream_socket_client(
|
||||
"{$host_uri}:{$port}",
|
||||
$errno,
|
||||
$errstr,
|
||||
$this->options['timeout'],
|
||||
$flags,
|
||||
$context
|
||||
);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if (!$this->isConnected()) {
|
||||
$error = "Could not open socket to \"{$host}:{$port}\": {$errstr} ({$errno}) {$error}.";
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error);
|
||||
}
|
||||
|
||||
$address = "{$scheme}://{$host}{$path_with_query}";
|
||||
|
||||
if (!$persistent || ftell($this->socket) == 0) {
|
||||
// Set timeout on the stream as well.
|
||||
stream_set_timeout($this->socket, $this->options['timeout']);
|
||||
|
||||
// Generate the WebSocket key.
|
||||
$key = self::generateKey();
|
||||
|
||||
// Default headers
|
||||
$headers = [
|
||||
'Host' => $host . ":" . $port,
|
||||
'User-Agent' => 'websocket-client-php',
|
||||
'Connection' => 'Upgrade',
|
||||
'Upgrade' => 'websocket',
|
||||
'Sec-WebSocket-Key' => $key,
|
||||
'Sec-WebSocket-Version' => '13',
|
||||
];
|
||||
|
||||
// Handle basic authentication.
|
||||
if ($user || $pass) {
|
||||
$headers['authorization'] = 'Basic ' . base64_encode($user . ':' . $pass);
|
||||
}
|
||||
|
||||
// Deprecated way of adding origin (use headers instead).
|
||||
if (isset($this->options['origin'])) {
|
||||
$headers['origin'] = $this->options['origin'];
|
||||
}
|
||||
|
||||
// Add and override with headers from options.
|
||||
if (isset($this->options['headers'])) {
|
||||
$headers = array_merge($headers, $this->options['headers']);
|
||||
}
|
||||
|
||||
$header = "GET " . $path_with_query . " HTTP/1.1\r\n" . implode(
|
||||
"\r\n",
|
||||
array_map(
|
||||
function ($key, $value) {
|
||||
return "$key: $value";
|
||||
},
|
||||
array_keys($headers),
|
||||
$headers
|
||||
)
|
||||
) . "\r\n\r\n";
|
||||
|
||||
// Send headers.
|
||||
$this->write($header);
|
||||
|
||||
// Get server response header (terminated with double CR+LF).
|
||||
$response = '';
|
||||
do {
|
||||
$buffer = fgets($this->socket, 1024);
|
||||
if ($buffer === false) {
|
||||
$meta = stream_get_meta_data($this->socket);
|
||||
$message = 'Client handshake error';
|
||||
$this->logger->error($message, $meta);
|
||||
throw new ConnectionException($message);
|
||||
}
|
||||
$response .= $buffer;
|
||||
} while (substr_count($response, "\r\n\r\n") == 0);
|
||||
|
||||
// Validate response.
|
||||
if (!preg_match('#Sec-WebSocket-Accept:\s(.*)$#mUi', $response, $matches)) {
|
||||
$error = "Connection to '{$address}' failed: Server sent invalid upgrade response: {$response}";
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error);
|
||||
}
|
||||
|
||||
$keyAccept = trim($matches[1]);
|
||||
$expectedResonse
|
||||
= base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
|
||||
|
||||
if ($keyAccept !== $expectedResonse) {
|
||||
$error = 'Server sent bad upgrade response.';
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error);
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info("Client connected to {$address}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random string for WebSocket key.
|
||||
*
|
||||
* @return string Random string
|
||||
*/
|
||||
protected static function generateKey(): string
|
||||
{
|
||||
$key = '';
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$key .= chr(rand(33, 126));
|
||||
}
|
||||
return base64_encode($key);
|
||||
}
|
||||
}
|
||||
26
Server/vendor/textalk/websocket/lib/ConnectionException.php
vendored
Normal file
26
Server/vendor/textalk/websocket/lib/ConnectionException.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use Throwable;
|
||||
|
||||
class ConnectionException extends Exception
|
||||
{
|
||||
// Native codes in interval 0-106
|
||||
public const TIMED_OUT = 1024;
|
||||
public const EOF = 1025;
|
||||
public const BAD_OPCODE = 1026;
|
||||
|
||||
private $data;
|
||||
|
||||
public function __construct(string $message, int $code = 0, array $data = [], Throwable $prev = null)
|
||||
{
|
||||
parent::__construct($message, $code, $prev);
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
7
Server/vendor/textalk/websocket/lib/Exception.php
vendored
Normal file
7
Server/vendor/textalk/websocket/lib/Exception.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
8
Server/vendor/textalk/websocket/lib/Message/Binary.php
vendored
Normal file
8
Server/vendor/textalk/websocket/lib/Message/Binary.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
class Binary extends Message
|
||||
{
|
||||
protected $opcode = 'binary';
|
||||
}
|
||||
8
Server/vendor/textalk/websocket/lib/Message/Close.php
vendored
Normal file
8
Server/vendor/textalk/websocket/lib/Message/Close.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
class Close extends Message
|
||||
{
|
||||
protected $opcode = 'close';
|
||||
}
|
||||
25
Server/vendor/textalk/websocket/lib/Message/Factory.php
vendored
Normal file
25
Server/vendor/textalk/websocket/lib/Message/Factory.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
use WebSocket\BadOpcodeException;
|
||||
|
||||
class Factory
|
||||
{
|
||||
public function create(string $opcode, string $payload = ''): Message
|
||||
{
|
||||
switch ($opcode) {
|
||||
case 'text':
|
||||
return new Text($payload);
|
||||
case 'binary':
|
||||
return new Binary($payload);
|
||||
case 'ping':
|
||||
return new Ping($payload);
|
||||
case 'pong':
|
||||
return new Pong($payload);
|
||||
case 'close':
|
||||
return new Close($payload);
|
||||
}
|
||||
throw new BadOpcodeException("Invalid opcode '{$opcode}' provided");
|
||||
}
|
||||
}
|
||||
53
Server/vendor/textalk/websocket/lib/Message/Message.php
vendored
Normal file
53
Server/vendor/textalk/websocket/lib/Message/Message.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
use DateTime;
|
||||
|
||||
abstract class Message
|
||||
{
|
||||
protected $opcode;
|
||||
protected $payload;
|
||||
protected $timestamp;
|
||||
|
||||
public function __construct(string $payload = '')
|
||||
{
|
||||
$this->payload = $payload;
|
||||
$this->timestamp = new DateTime();
|
||||
}
|
||||
|
||||
public function getOpcode(): string
|
||||
{
|
||||
return $this->opcode;
|
||||
}
|
||||
|
||||
public function getLength(): int
|
||||
{
|
||||
return strlen($this->payload);
|
||||
}
|
||||
|
||||
public function getTimestamp(): DateTime
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
|
||||
public function setContent(string $payload = ''): void
|
||||
{
|
||||
$this->payload = $payload;
|
||||
}
|
||||
|
||||
public function hasContent(): bool
|
||||
{
|
||||
return $this->payload != '';
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
}
|
||||
8
Server/vendor/textalk/websocket/lib/Message/Ping.php
vendored
Normal file
8
Server/vendor/textalk/websocket/lib/Message/Ping.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
class Ping extends Message
|
||||
{
|
||||
protected $opcode = 'ping';
|
||||
}
|
||||
8
Server/vendor/textalk/websocket/lib/Message/Pong.php
vendored
Normal file
8
Server/vendor/textalk/websocket/lib/Message/Pong.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
class Pong extends Message
|
||||
{
|
||||
protected $opcode = 'pong';
|
||||
}
|
||||
8
Server/vendor/textalk/websocket/lib/Message/Text.php
vendored
Normal file
8
Server/vendor/textalk/websocket/lib/Message/Text.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket\Message;
|
||||
|
||||
class Text extends Message
|
||||
{
|
||||
protected $opcode = 'text';
|
||||
}
|
||||
176
Server/vendor/textalk/websocket/lib/Server.php
vendored
Normal file
176
Server/vendor/textalk/websocket/lib/Server.php
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2014-2020 Textalk/Abicart and contributors.
|
||||
*
|
||||
* This file is part of Websocket PHP and is free software under the ISC License.
|
||||
* License text: https://raw.githubusercontent.com/Textalk/websocket-php/master/COPYING
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class Server extends Base
|
||||
{
|
||||
// Default options
|
||||
protected static $default_options = [
|
||||
'filter' => ['text', 'binary'],
|
||||
'fragment_size' => 4096,
|
||||
'logger' => null,
|
||||
'port' => 8000,
|
||||
'return_obj' => false,
|
||||
'timeout' => null,
|
||||
];
|
||||
|
||||
protected $addr;
|
||||
protected $port;
|
||||
protected $listening;
|
||||
protected $request;
|
||||
protected $request_path;
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* Associative array containing:
|
||||
* - timeout: Set the socket timeout in seconds.
|
||||
* - fragment_size: Set framgemnt size. Default: 4096
|
||||
* - port: Chose port for listening. Default 8000.
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = array_merge(self::$default_options, $options);
|
||||
$this->port = $this->options['port'];
|
||||
$this->setLogger($this->options['logger']);
|
||||
|
||||
$error = $errno = $errstr = null;
|
||||
set_error_handler(function (int $severity, string $message, string $file, int $line) use (&$error) {
|
||||
$this->logger->warning($message, ['severity' => $severity]);
|
||||
$error = $message;
|
||||
}, E_ALL);
|
||||
|
||||
do {
|
||||
$this->listening = stream_socket_server("tcp://0.0.0.0:$this->port", $errno, $errstr);
|
||||
} while ($this->listening === false && $this->port++ < 10000);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if (!$this->listening) {
|
||||
$error = "Could not open listening socket: {$errstr} ({$errno}) {$error}";
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error, (int)$errno);
|
||||
}
|
||||
|
||||
$this->logger->info("Server listening to port {$this->port}");
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->isConnected()) {
|
||||
fclose($this->socket);
|
||||
}
|
||||
$this->socket = null;
|
||||
}
|
||||
|
||||
public function getPort(): int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->request_path;
|
||||
}
|
||||
|
||||
public function getRequest(): array
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function getHeader($header): ?string
|
||||
{
|
||||
foreach ($this->request as $row) {
|
||||
if (stripos($row, $header) !== false) {
|
||||
list($headername, $headervalue) = explode(":", $row);
|
||||
return trim($headervalue);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function accept(): bool
|
||||
{
|
||||
$this->socket = null;
|
||||
return (bool)$this->listening;
|
||||
}
|
||||
|
||||
protected function connect(): void
|
||||
{
|
||||
|
||||
$error = null;
|
||||
set_error_handler(function (int $severity, string $message, string $file, int $line) use (&$error) {
|
||||
$this->logger->warning($message, ['severity' => $severity]);
|
||||
$error = $message;
|
||||
}, E_ALL);
|
||||
|
||||
if (isset($this->options['timeout'])) {
|
||||
$this->socket = stream_socket_accept($this->listening, $this->options['timeout']);
|
||||
} else {
|
||||
$this->socket = stream_socket_accept($this->listening);
|
||||
}
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if (!$this->socket) {
|
||||
$this->throwException("Server failed to connect. {$error}");
|
||||
}
|
||||
if (isset($this->options['timeout'])) {
|
||||
stream_set_timeout($this->socket, $this->options['timeout']);
|
||||
}
|
||||
|
||||
$this->logger->info("Client has connected to port {port}", [
|
||||
'port' => $this->port,
|
||||
'pier' => stream_socket_get_name($this->socket, true),
|
||||
]);
|
||||
$this->performHandshake();
|
||||
}
|
||||
|
||||
protected function performHandshake(): void
|
||||
{
|
||||
$request = '';
|
||||
do {
|
||||
$buffer = stream_get_line($this->socket, 1024, "\r\n");
|
||||
$request .= $buffer . "\n";
|
||||
$metadata = stream_get_meta_data($this->socket);
|
||||
} while (!feof($this->socket) && $metadata['unread_bytes'] > 0);
|
||||
|
||||
if (!preg_match('/GET (.*) HTTP\//mUi', $request, $matches)) {
|
||||
$error = "No GET in request: {$request}";
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error);
|
||||
}
|
||||
$get_uri = trim($matches[1]);
|
||||
$uri_parts = parse_url($get_uri);
|
||||
|
||||
$this->request = explode("\n", $request);
|
||||
$this->request_path = $uri_parts['path'];
|
||||
/// @todo Get query and fragment as well.
|
||||
|
||||
if (!preg_match('#Sec-WebSocket-Key:\s(.*)$#mUi', $request, $matches)) {
|
||||
$error = "Client had no Key in upgrade request: {$request}";
|
||||
$this->logger->error($error);
|
||||
throw new ConnectionException($error);
|
||||
}
|
||||
|
||||
$key = trim($matches[1]);
|
||||
|
||||
/// @todo Validate key length and base 64...
|
||||
$response_key = base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
|
||||
|
||||
$header = "HTTP/1.1 101 Switching Protocols\r\n"
|
||||
. "Upgrade: websocket\r\n"
|
||||
. "Connection: Upgrade\r\n"
|
||||
. "Sec-WebSocket-Accept: $response_key\r\n"
|
||||
. "\r\n";
|
||||
|
||||
$this->write($header);
|
||||
$this->logger->debug("Handshake on {$get_uri}");
|
||||
}
|
||||
}
|
||||
7
Server/vendor/textalk/websocket/lib/TimeoutException.php
vendored
Normal file
7
Server/vendor/textalk/websocket/lib/TimeoutException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class TimeoutException extends ConnectionException
|
||||
{
|
||||
}
|
||||
14
Server/vendor/textalk/websocket/phpunit.xml.dist
vendored
Normal file
14
Server/vendor/textalk/websocket/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="Unit tests">
|
||||
<directory suffix=".php">tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">lib/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
458
Server/vendor/textalk/websocket/tests/ClientTest.php
vendored
Normal file
458
Server/vendor/textalk/websocket/tests/ClientTest.php
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test case for Client.
|
||||
* Note that this test is performed by mocking socket/stream calls.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ClientTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
public function testClientMasked(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertEquals(4096, $client->getFragmentSize());
|
||||
|
||||
MockSocket::initialize('send-receive', $this);
|
||||
$client->send('Sending a message');
|
||||
$message = $client->receive();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertEquals('text', $client->getLastOpcode());
|
||||
|
||||
MockSocket::initialize('client.close', $this);
|
||||
$this->assertTrue($client->isConnected());
|
||||
$this->assertNull($client->getCloseStatus());
|
||||
|
||||
$client->close();
|
||||
$this->assertFalse($client->isConnected());
|
||||
$this->assertEquals(1000, $client->getCloseStatus());
|
||||
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testDestruct(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('client.destruct', $this);
|
||||
}
|
||||
|
||||
public function testClienExtendedUrl(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-extended', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path?my_query=yes#my_fragment');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testClientWithTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-timeout', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path', ['timeout' => 300]);
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testClientWithContext(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-context', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path', ['context' => '@mock-stream-context']);
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testClientAuthed(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-authed', $this);
|
||||
$client = new Client('wss://usename:password@localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testWithHeaders(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-headers', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path', [
|
||||
'origin' => 'Origin header',
|
||||
'headers' => ['Generic header' => 'Generic content'],
|
||||
]);
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPayload128(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
$payload = file_get_contents(__DIR__ . '/mock/payload.128.txt');
|
||||
|
||||
MockSocket::initialize('send-receive-128', $this);
|
||||
$client->send($payload, 'text', false);
|
||||
$message = $client->receive();
|
||||
$this->assertEquals($payload, $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPayload65536(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
$payload = file_get_contents(__DIR__ . '/mock/payload.65536.txt');
|
||||
$client->setFragmentSize(65540);
|
||||
|
||||
MockSocket::initialize('send-receive-65536', $this);
|
||||
$client->send($payload, 'text', false);
|
||||
$message = $client->receive();
|
||||
$this->assertEquals($payload, $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertEquals(65540, $client->getFragmentSize());
|
||||
}
|
||||
|
||||
public function testMultiFragment(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('send-receive-multi-fragment', $this);
|
||||
$client->setFragmentSize(8);
|
||||
$client->send('Multi fragment test');
|
||||
$message = $client->receive();
|
||||
$this->assertEquals('Multi fragment test', $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertEquals(8, $client->getFragmentSize());
|
||||
}
|
||||
|
||||
public function testPingPong(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('ping-pong', $this);
|
||||
$client->send('Server ping', 'ping');
|
||||
$client->send('', 'ping');
|
||||
$message = $client->receive();
|
||||
$this->assertEquals('Receiving a message', $message);
|
||||
$this->assertEquals('text', $client->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testRemoteClose(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
|
||||
$message = $client->receive();
|
||||
$this->assertNull($message);
|
||||
|
||||
$this->assertFalse($client->isConnected());
|
||||
$this->assertEquals(17260, $client->getCloseStatus());
|
||||
$this->assertNull($client->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testSetTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('config-timeout', $this);
|
||||
$client->setTimeout(300);
|
||||
$this->assertTrue($client->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testReconnect(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('client.close', $this);
|
||||
$this->assertTrue($client->isConnected());
|
||||
$this->assertNull($client->getCloseStatus());
|
||||
$client->close();
|
||||
$this->assertFalse($client->isConnected());
|
||||
$this->assertEquals(1000, $client->getCloseStatus());
|
||||
$this->assertNull($client->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('client.reconnect', $this);
|
||||
$message = $client->receive();
|
||||
$this->assertTrue($client->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPersistentConnection(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-persistent', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path', ['persistent' => true]);
|
||||
$client->send('Connect');
|
||||
$client->disconnect();
|
||||
$this->assertFalse($client->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testBadScheme(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('bad://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\BadUriException');
|
||||
$this->expectExceptionMessage('Url should have scheme ws or wss');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testBadUrl(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('this is not an url');
|
||||
$this->expectException('WebSocket\BadUriException');
|
||||
$this->expectExceptionMessage('Invalid url \'this is not an url\' provided.');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testBadStreamContext(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-bad-context', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path', ['context' => 'BAD']);
|
||||
$this->expectException('InvalidArgumentException');
|
||||
$this->expectExceptionMessage('Stream context in $options[\'context\'] isn\'t a valid context');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedConnection(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-failed', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Could not open socket to "localhost:8000"');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedConnectionWithError(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-error', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Could not open socket to "localhost:8000"');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testInvalidUpgrade(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-invalid-upgrade', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Connection to \'ws://localhost/my/mock/path\' failed');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testInvalidKey(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-invalid-key', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Server sent bad upgrade response');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testSendBadOpcode(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
|
||||
MockSocket::initialize('send-bad-opcode', $this);
|
||||
$this->expectException('WebSocket\BadOpcodeException');
|
||||
$this->expectExceptionMessage('Bad opcode \'bad\'. Try \'text\' or \'binary\'.');
|
||||
$client->send('Bad Opcode', 'bad');
|
||||
}
|
||||
|
||||
public function testRecieveBadOpcode(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-bad-opcode', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1026);
|
||||
$this->expectExceptionMessage('Bad opcode in websocket frame: 12');
|
||||
$message = $client->receive();
|
||||
}
|
||||
|
||||
public function testBrokenWrite(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('send-broken-write', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1025);
|
||||
$this->expectExceptionMessage('Could only write 18 out of 22 bytes.');
|
||||
$client->send('Failing to write');
|
||||
}
|
||||
|
||||
public function testFailedWrite(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('send-failed-write', $this);
|
||||
$this->expectException('WebSocket\TimeoutException');
|
||||
$this->expectExceptionCode(1024);
|
||||
$this->expectExceptionMessage('Failed to write 22 bytes.');
|
||||
$client->send('Failing to write');
|
||||
}
|
||||
|
||||
public function testBrokenRead(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-broken-read', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1025);
|
||||
$this->expectExceptionMessage('Broken frame, read 0 of stated 2 bytes.');
|
||||
$client->receive();
|
||||
}
|
||||
|
||||
public function testHandshakeError(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect-handshake-error', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Client handshake error');
|
||||
$client->send('Connect');
|
||||
}
|
||||
|
||||
public function testReadTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-client-timeout', $this);
|
||||
$this->expectException('WebSocket\TimeoutException');
|
||||
$this->expectExceptionCode(1024);
|
||||
$this->expectExceptionMessage('Client read timeout');
|
||||
$client->receive();
|
||||
}
|
||||
|
||||
public function testEmptyRead(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-empty-read', $this);
|
||||
$this->expectException('WebSocket\TimeoutException');
|
||||
$this->expectExceptionCode(1024);
|
||||
$this->expectExceptionMessage('Empty read; connection dead?');
|
||||
$client->receive();
|
||||
}
|
||||
|
||||
public function testFrameFragmentation(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client(
|
||||
'ws://localhost:8000/my/mock/path',
|
||||
['filter' => ['text', 'binary', 'pong', 'close']]
|
||||
);
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-fragmentation', $this);
|
||||
$message = $client->receive();
|
||||
$this->assertEquals('Server ping', $message);
|
||||
$this->assertEquals('pong', $client->getLastOpcode());
|
||||
$message = $client->receive();
|
||||
$this->assertEquals('Multi fragment test', $message);
|
||||
$this->assertEquals('text', $client->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
$message = $client->receive();
|
||||
$this->assertEquals('Closing', $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertFalse($client->isConnected());
|
||||
$this->assertEquals(17260, $client->getCloseStatus());
|
||||
$this->assertEquals('close', $client->getLastOpcode());
|
||||
}
|
||||
|
||||
public function testMessageFragmentation(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client(
|
||||
'ws://localhost:8000/my/mock/path',
|
||||
['filter' => ['text', 'binary', 'pong', 'close'], 'return_obj' => true]
|
||||
);
|
||||
$client->send('Connect');
|
||||
MockSocket::initialize('receive-fragmentation', $this);
|
||||
$message = $client->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Pong', $message);
|
||||
$this->assertEquals('Server ping', $message->getContent());
|
||||
$this->assertEquals('pong', $message->getOpcode());
|
||||
$message = $client->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Text', $message);
|
||||
$this->assertEquals('Multi fragment test', $message->getContent());
|
||||
$this->assertEquals('text', $message->getOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
$message = $client->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Close', $message);
|
||||
$this->assertEquals('Closing', $message->getContent());
|
||||
$this->assertEquals('close', $message->getOpcode());
|
||||
}
|
||||
|
||||
public function testConvenicanceMethods(): void
|
||||
{
|
||||
MockSocket::initialize('client.connect', $this);
|
||||
$client = new Client('ws://localhost:8000/my/mock/path');
|
||||
$this->assertNull($client->getName());
|
||||
$this->assertNull($client->getPier());
|
||||
$this->assertEquals('WebSocket\Client(closed)', "{$client}");
|
||||
$client->text('Connect');
|
||||
MockSocket::initialize('send-convenicance', $this);
|
||||
$client->binary(base64_encode('Binary content'));
|
||||
$client->ping();
|
||||
$client->pong();
|
||||
$this->assertEquals('127.0.0.1:12345', $client->getName());
|
||||
$this->assertEquals('127.0.0.1:8000', $client->getPier());
|
||||
$this->assertEquals('WebSocket\Client(127.0.0.1:12345)', "{$client}");
|
||||
}
|
||||
}
|
||||
51
Server/vendor/textalk/websocket/tests/ExceptionTest.php
vendored
Normal file
51
Server/vendor/textalk/websocket/tests/ExceptionTest.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test case for Exceptions.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Throwable;
|
||||
|
||||
class ExceptionTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
public function testConnectionException(): void
|
||||
{
|
||||
try {
|
||||
throw new ConnectionException(
|
||||
'An error message',
|
||||
ConnectionException::EOF,
|
||||
['test' => 'with data'],
|
||||
new TimeoutException(
|
||||
'Nested exception',
|
||||
ConnectionException::TIMED_OUT
|
||||
)
|
||||
);
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
|
||||
$this->assertInstanceOf('WebSocket\ConnectionException', $e);
|
||||
$this->assertInstanceOf('WebSocket\Exception', $e);
|
||||
$this->assertInstanceOf('Exception', $e);
|
||||
$this->assertInstanceOf('Throwable', $e);
|
||||
$this->assertEquals('An error message', $e->getMessage());
|
||||
$this->assertEquals(1025, $e->getCode());
|
||||
$this->assertEquals(['test' => 'with data'], $e->getData());
|
||||
|
||||
$p = $e->getPrevious();
|
||||
$this->assertInstanceOf('WebSocket\TimeoutException', $p);
|
||||
$this->assertInstanceOf('WebSocket\ConnectionException', $p);
|
||||
$this->assertEquals('Nested exception', $p->getMessage());
|
||||
$this->assertEquals(1024, $p->getCode());
|
||||
$this->assertEquals([], $p->getData());
|
||||
}
|
||||
}
|
||||
60
Server/vendor/textalk/websocket/tests/MessageTest.php
vendored
Normal file
60
Server/vendor/textalk/websocket/tests/MessageTest.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test case for Message subsection.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WebSocket\Message\Factory;
|
||||
use WebSocket\Message\Text;
|
||||
|
||||
class MessageTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
public function testFactory(): void
|
||||
{
|
||||
$factory = new Factory();
|
||||
$message = $factory->create('text', 'Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Text', $message);
|
||||
$message = $factory->create('binary', 'Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Binary', $message);
|
||||
$message = $factory->create('ping', 'Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Ping', $message);
|
||||
$message = $factory->create('pong', 'Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Pong', $message);
|
||||
$message = $factory->create('close', 'Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Close', $message);
|
||||
}
|
||||
|
||||
public function testMessage()
|
||||
{
|
||||
$message = new Text('Some content');
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Text', $message);
|
||||
$this->assertEquals('Some content', $message->getContent());
|
||||
$this->assertEquals('text', $message->getOpcode());
|
||||
$this->assertEquals(12, $message->getLength());
|
||||
$this->assertTrue($message->hasContent());
|
||||
$this->assertInstanceOf('DateTime', $message->getTimestamp());
|
||||
$message->setContent('');
|
||||
$this->assertEquals(0, $message->getLength());
|
||||
$this->assertFalse($message->hasContent());
|
||||
$this->assertEquals('WebSocket\Message\Text', "{$message}");
|
||||
}
|
||||
|
||||
public function testBadOpcode()
|
||||
{
|
||||
$factory = new Factory();
|
||||
$this->expectException('WebSocket\BadOpcodeException');
|
||||
$this->expectExceptionMessage("Invalid opcode 'invalid' provided");
|
||||
$message = $factory->create('invalid', 'Some content');
|
||||
}
|
||||
}
|
||||
29
Server/vendor/textalk/websocket/tests/README.md
vendored
Normal file
29
Server/vendor/textalk/websocket/tests/README.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Testing
|
||||
|
||||
Unit tests with [PHPUnit](https://phpunit.readthedocs.io/).
|
||||
|
||||
|
||||
## How to run
|
||||
|
||||
To run all test, run in console.
|
||||
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
|
||||
## Continuous integration
|
||||
|
||||
GitHub Actions are run on PHP versions
|
||||
`7.2`, `7.3`, `7.4` and `8.0`.
|
||||
|
||||
Code coverage by [Coveralls](https://coveralls.io/github/Textalk/websocket-php).
|
||||
|
||||
|
||||
## Test strategy
|
||||
|
||||
Test set up overloads various stream and socket functions,
|
||||
and use "scripts" to define and mock input/output of these functions.
|
||||
|
||||
This set up negates the dependency on running servers,
|
||||
and allow testing various errors that might occur.
|
||||
447
Server/vendor/textalk/websocket/tests/ServerTest.php
vendored
Normal file
447
Server/vendor/textalk/websocket/tests/ServerTest.php
vendored
Normal file
@@ -0,0 +1,447 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test case for Server.
|
||||
* Note that this test is performed by mocking socket/stream calls.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ServerTest extends TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
public function testServerMasked(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertEquals(8000, $server->getPort());
|
||||
$this->assertEquals('/my/mock/path', $server->getPath());
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertEquals(4096, $server->getFragmentSize());
|
||||
$this->assertNull($server->getCloseStatus());
|
||||
$this->assertEquals([
|
||||
'GET /my/mock/path HTTP/1.1',
|
||||
'host: localhost:8000',
|
||||
'user-agent: websocket-client-php',
|
||||
'connection: Upgrade',
|
||||
'upgrade: websocket',
|
||||
'sec-websocket-key: cktLWXhUdDQ2OXF0ZCFqOQ==',
|
||||
'sec-websocket-version: 13',
|
||||
'',
|
||||
'',
|
||||
], $server->getRequest());
|
||||
$this->assertEquals('websocket-client-php', $server->getHeader('USER-AGENT'));
|
||||
$this->assertNull($server->getHeader('no such header'));
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('send-receive', $this);
|
||||
$server->send('Sending a message');
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Receiving a message', $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertNull($server->getCloseStatus());
|
||||
$this->assertEquals('text', $server->getLastOpcode());
|
||||
|
||||
MockSocket::initialize('server.close', $this);
|
||||
$server->close();
|
||||
$this->assertFalse($server->isConnected());
|
||||
$this->assertEquals(1000, $server->getCloseStatus());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
$server->close(); // Already closed
|
||||
}
|
||||
|
||||
public function testDestruct(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
|
||||
MockSocket::initialize('server.accept-destruct', $this);
|
||||
$server->accept();
|
||||
$message = $server->receive();
|
||||
}
|
||||
|
||||
public function testServerWithTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server(['timeout' => 300]);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept-timeout', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPayload128(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
$payload = file_get_contents(__DIR__ . '/mock/payload.128.txt');
|
||||
|
||||
MockSocket::initialize('send-receive-128', $this);
|
||||
$server->send($payload, 'text', false);
|
||||
$message = $server->receive();
|
||||
$this->assertEquals($payload, $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPayload65536(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
$payload = file_get_contents(__DIR__ . '/mock/payload.65536.txt');
|
||||
$server->setFragmentSize(65540);
|
||||
|
||||
MockSocket::initialize('send-receive-65536', $this);
|
||||
$server->send($payload, 'text', false);
|
||||
$message = $server->receive();
|
||||
$this->assertEquals($payload, $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testMultiFragment(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('send-receive-multi-fragment', $this);
|
||||
$server->setFragmentSize(8);
|
||||
$server->send('Multi fragment test');
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Multi fragment test', $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testPingPong(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('ping-pong', $this);
|
||||
$server->send('Server ping', 'ping');
|
||||
$server->send('', 'ping');
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Receiving a message', $message);
|
||||
$this->assertEquals('text', $server->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testRemoteClose(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('', $message);
|
||||
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertFalse($server->isConnected());
|
||||
$this->assertEquals(17260, $server->getCloseStatus());
|
||||
$this->assertNull($server->getLastOpcode());
|
||||
}
|
||||
|
||||
public function testSetTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
|
||||
MockSocket::initialize('config-timeout', $this);
|
||||
$server->setTimeout(300);
|
||||
$this->assertTrue($server->isConnected());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
|
||||
public function testFailedSocketServer(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct-failed-socket-server', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Could not open listening socket:');
|
||||
$server = new Server(['port' => 9999]);
|
||||
}
|
||||
|
||||
public function testFailedSocketServerWithError(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct-error-socket-server', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Could not open listening socket:');
|
||||
$server = new Server(['port' => 9999]);
|
||||
}
|
||||
|
||||
public function testFailedConnect(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
|
||||
MockSocket::initialize('server.accept-failed-connect', $this);
|
||||
$server->accept();
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Server failed to connect');
|
||||
$server->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedConnectWithError(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
|
||||
MockSocket::initialize('server.accept-error-connect', $this);
|
||||
$server->accept();
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Server failed to connect');
|
||||
$server->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedConnectTimeout(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server(['timeout' => 300]);
|
||||
|
||||
MockSocket::initialize('server.accept-failed-connect', $this);
|
||||
$server->accept();
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Server failed to connect');
|
||||
$server->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedHttp(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept-failed-http', $this);
|
||||
$server->accept();
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('No GET in request');
|
||||
$server->send('Connect');
|
||||
}
|
||||
|
||||
public function testFailedWsKey(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept-failed-ws-key', $this);
|
||||
$server->accept();
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Client had no Key in upgrade request');
|
||||
$server->send('Connect');
|
||||
}
|
||||
|
||||
public function testSendBadOpcode(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
$this->expectException('WebSocket\BadOpcodeException');
|
||||
$this->expectExceptionCode(0);
|
||||
$this->expectExceptionMessage('Bad opcode \'bad\'. Try \'text\' or \'binary\'.');
|
||||
$server->send('Bad Opcode', 'bad');
|
||||
}
|
||||
|
||||
public function testRecieveBadOpcode(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('receive-bad-opcode', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1026);
|
||||
$this->expectExceptionMessage('Bad opcode in websocket frame: 12');
|
||||
$message = $server->receive();
|
||||
}
|
||||
|
||||
public function testBrokenWrite(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('send-broken-write', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1025);
|
||||
$this->expectExceptionMessage('Could only write 18 out of 22 bytes.');
|
||||
$server->send('Failing to write');
|
||||
}
|
||||
|
||||
public function testFailedWrite(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('send-failed-write', $this);
|
||||
$this->expectException('WebSocket\TimeoutException');
|
||||
$this->expectExceptionCode(1024);
|
||||
$this->expectExceptionMessage('Failed to write 22 bytes.');
|
||||
$server->send('Failing to write');
|
||||
}
|
||||
|
||||
public function testBrokenRead(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('receive-broken-read', $this);
|
||||
$this->expectException('WebSocket\ConnectionException');
|
||||
$this->expectExceptionCode(1025);
|
||||
$this->expectExceptionMessage('Broken frame, read 0 of stated 2 bytes.');
|
||||
$server->receive();
|
||||
}
|
||||
|
||||
public function testEmptyRead(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('receive-empty-read', $this);
|
||||
$this->expectException('WebSocket\TimeoutException');
|
||||
$this->expectExceptionCode(1024);
|
||||
$this->expectExceptionMessage('Empty read; connection dead?');
|
||||
$server->receive();
|
||||
}
|
||||
|
||||
public function testFrameFragmentation(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server(['filter' => ['text', 'binary', 'pong', 'close']]);
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('receive-fragmentation', $this);
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Server ping', $message);
|
||||
$this->assertEquals('pong', $server->getLastOpcode());
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Multi fragment test', $message);
|
||||
$this->assertEquals('text', $server->getLastOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
$message = $server->receive();
|
||||
$this->assertEquals('Closing', $message);
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
$this->assertFalse($server->isConnected());
|
||||
$this->assertEquals(17260, $server->getCloseStatus());
|
||||
$this->assertEquals('close', $server->getLastOpcode());
|
||||
}
|
||||
|
||||
public function testMessageFragmentation(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server(['filter' => ['text', 'binary', 'pong', 'close'], 'return_obj' => true]);
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->send('Connect');
|
||||
MockSocket::initialize('receive-fragmentation', $this);
|
||||
$message = $server->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Pong', $message);
|
||||
$this->assertEquals('Server ping', $message->getContent());
|
||||
$this->assertEquals('pong', $message->getOpcode());
|
||||
$message = $server->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Text', $message);
|
||||
$this->assertEquals('Multi fragment test', $message->getContent());
|
||||
$this->assertEquals('text', $message->getOpcode());
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
MockSocket::initialize('close-remote', $this);
|
||||
$message = $server->receive();
|
||||
$this->assertInstanceOf('WebSocket\Message\Message', $message);
|
||||
$this->assertInstanceOf('WebSocket\Message\Close', $message);
|
||||
$this->assertEquals('Closing', $message->getContent());
|
||||
$this->assertEquals('close', $message->getOpcode());
|
||||
}
|
||||
|
||||
public function testConvenicanceMethods(): void
|
||||
{
|
||||
MockSocket::initialize('server.construct', $this);
|
||||
$server = new Server();
|
||||
$this->assertNull($server->getName());
|
||||
$this->assertNull($server->getPier());
|
||||
$this->assertEquals('WebSocket\Server(closed)', "{$server}");
|
||||
MockSocket::initialize('server.accept', $this);
|
||||
$server->accept();
|
||||
$server->text('Connect');
|
||||
MockSocket::initialize('send-convenicance', $this);
|
||||
$server->binary(base64_encode('Binary content'));
|
||||
$server->ping();
|
||||
$server->pong();
|
||||
$this->assertEquals('127.0.0.1:12345', $server->getName());
|
||||
$this->assertEquals('127.0.0.1:8000', $server->getPier());
|
||||
$this->assertEquals('WebSocket\Server(127.0.0.1:12345)', "{$server}");
|
||||
$this->assertTrue(MockSocket::isEmpty());
|
||||
}
|
||||
}
|
||||
6
Server/vendor/textalk/websocket/tests/bootstrap.php
vendored
Normal file
6
Server/vendor/textalk/websocket/tests/bootstrap.php
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require __DIR__ . '/mock/mock-socket.php';
|
||||
34
Server/vendor/textalk/websocket/tests/mock/EchoLog.php
vendored
Normal file
34
Server/vendor/textalk/websocket/tests/mock/EchoLog.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Simple echo logger (only available when running in dev environment)
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class EchoLog implements \Psr\Log\LoggerInterface
|
||||
{
|
||||
use \Psr\Log\LoggerTrait;
|
||||
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
$message = $this->interpolate($message, $context);
|
||||
$context_string = empty($context) ? '' : json_encode($context);
|
||||
echo str_pad($level, 8) . " | {$message} {$context_string}\n";
|
||||
}
|
||||
|
||||
public function interpolate($message, array $context = [])
|
||||
{
|
||||
// Build a replacement array with braces around the context keys
|
||||
$replace = [];
|
||||
foreach ($context as $key => $val) {
|
||||
// Check that the value can be cast to string
|
||||
if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
|
||||
$replace['{' . $key . '}'] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate replacement values into the message and return
|
||||
return strtr($message, $replace);
|
||||
}
|
||||
}
|
||||
78
Server/vendor/textalk/websocket/tests/mock/MockSocket.php
vendored
Normal file
78
Server/vendor/textalk/websocket/tests/mock/MockSocket.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class is used by tests to mock and track various socket/stream calls.
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
class MockSocket
|
||||
{
|
||||
private static $queue = [];
|
||||
private static $stored = [];
|
||||
private static $asserter;
|
||||
|
||||
// Handler called by function overloads in mock-socket.php
|
||||
public static function handle($function, $params = [])
|
||||
{
|
||||
$current = array_shift(self::$queue);
|
||||
if ($function == 'get_resource_type' && is_null($current)) {
|
||||
return null; // Catch destructors
|
||||
}
|
||||
self::$asserter->assertEquals($current['function'], $function);
|
||||
foreach ($current['params'] as $index => $param) {
|
||||
self::$asserter->assertEquals($param, $params[$index], json_encode([$current, $params]));
|
||||
}
|
||||
if (isset($current['error'])) {
|
||||
$map = array_merge(['msg' => 'Error', 'type' => E_USER_NOTICE], (array)$current['error']);
|
||||
trigger_error($map['msg'], $map['type']);
|
||||
}
|
||||
if (isset($current['return-op'])) {
|
||||
return self::op($current['return-op'], $params, $current['return']);
|
||||
}
|
||||
if (isset($current['return'])) {
|
||||
return $current['return'];
|
||||
}
|
||||
return call_user_func_array($function, $params);
|
||||
}
|
||||
|
||||
// Check if all expected calls are performed
|
||||
public static function isEmpty(): bool
|
||||
{
|
||||
return empty(self::$queue);
|
||||
}
|
||||
|
||||
// Initialize call queue
|
||||
public static function initialize($op_file, $asserter): void
|
||||
{
|
||||
$file = dirname(__DIR__) . "/scripts/{$op_file}.json";
|
||||
self::$queue = json_decode(file_get_contents($file), true);
|
||||
self::$asserter = $asserter;
|
||||
}
|
||||
|
||||
// Special output handling
|
||||
private static function op($op, $params, $data)
|
||||
{
|
||||
switch ($op) {
|
||||
case 'chr-array':
|
||||
// Convert int array to string
|
||||
$out = '';
|
||||
foreach ($data as $val) {
|
||||
$out .= chr($val);
|
||||
}
|
||||
return $out;
|
||||
case 'file':
|
||||
$content = file_get_contents(__DIR__ . "/{$data[0]}");
|
||||
return substr($content, $data[1], $data[2]);
|
||||
case 'key-save':
|
||||
preg_match('#Sec-WebSocket-Key:\s(.*)$#mUi', $params[1], $matches);
|
||||
self::$stored['sec-websocket-key'] = trim($matches[1]);
|
||||
return $data;
|
||||
case 'key-respond':
|
||||
$key = self::$stored['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
||||
$encoded = base64_encode(pack('H*', sha1($key)));
|
||||
return str_replace('{key}', $encoded, $data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
83
Server/vendor/textalk/websocket/tests/mock/mock-socket.php
vendored
Normal file
83
Server/vendor/textalk/websocket/tests/mock/mock-socket.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is used by tests to overload and mock various socket/stream calls.
|
||||
*/
|
||||
|
||||
namespace WebSocket;
|
||||
|
||||
function stream_socket_server($local_socket, &$errno, &$errstr)
|
||||
{
|
||||
$args = [$local_socket, $errno, $errstr];
|
||||
return MockSocket::handle('stream_socket_server', $args);
|
||||
}
|
||||
function stream_socket_accept()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_socket_accept', $args);
|
||||
}
|
||||
function stream_set_timeout()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_set_timeout', $args);
|
||||
}
|
||||
function stream_get_line()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_get_line', $args);
|
||||
}
|
||||
function stream_get_meta_data()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_get_meta_data', $args);
|
||||
}
|
||||
function feof()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('feof', $args);
|
||||
}
|
||||
function ftell()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('ftell', $args);
|
||||
}
|
||||
function fclose()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('fclose', $args);
|
||||
}
|
||||
function fwrite()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('fwrite', $args);
|
||||
}
|
||||
function fread()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('fread', $args);
|
||||
}
|
||||
function fgets()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('fgets', $args);
|
||||
}
|
||||
function stream_context_create()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_context_create', $args);
|
||||
}
|
||||
function stream_socket_client($remote_socket, &$errno, &$errstr, $timeout, $flags, $context)
|
||||
{
|
||||
$args = [$remote_socket, $errno, $errstr, $timeout, $flags, $context];
|
||||
return MockSocket::handle('stream_socket_client', $args);
|
||||
}
|
||||
function get_resource_type()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('get_resource_type', $args);
|
||||
}
|
||||
function stream_socket_get_name()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return MockSocket::handle('stream_socket_get_name', $args);
|
||||
}
|
||||
5
Server/vendor/textalk/websocket/tests/mock/payload.128.txt
vendored
Normal file
5
Server/vendor/textalk/websocket/tests/mock/payload.128.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
128-chars
|
||||
abscdefgheijklmnopqrstuvwxyz0123456789
|
||||
abscdefgheijklmnopqrstuvwxyz0123456789
|
||||
abscdefgheijklmnopqrstuvwxyz0123456789
|
||||
a
|
||||
1682
Server/vendor/textalk/websocket/tests/mock/payload.65536.txt
vendored
Normal file
1682
Server/vendor/textalk/websocket/tests/mock/payload.65536.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
76
Server/vendor/textalk/websocket/tests/scripts/client.close.json
vendored
Normal file
76
Server/vendor/textalk/websocket/tests/scripts/client.close.json
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return": 12
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return":[136, 154]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return":[98, 250, 210, 113]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
26
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [97, 18, 145, 29, 13, 137, 183, 81, 3, 153, 185, 31, 13, 141, 190, 20, 6, 157, 183, 21, 88, 218, 227, 65, 82, 202]
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return":true
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "Unknown"
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-authed.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-authed.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"ssl:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 248
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
7
Server/vendor/textalk/websocket/tests/scripts/client.connect-bad-context.json
vendored
Normal file
7
Server/vendor/textalk/websocket/tests/scripts/client.connect-bad-context.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [],
|
||||
"return": "@mock-bad-context"
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-context.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-context.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [],
|
||||
"return": "stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
23
Server/vendor/textalk/websocket/tests/scripts/client.connect-error.json
vendored
Normal file
23
Server/vendor/textalk/websocket/tests/scripts/client.connect-error.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"error": {
|
||||
"msg": "A PHP error",
|
||||
"type": 512
|
||||
},
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-extended.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-extended.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 224
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
19
Server/vendor/textalk/websocket/tests/scripts/client.connect-failed.json
vendored
Normal file
19
Server/vendor/textalk/websocket/tests/scripts/client.connect-failed.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
65
Server/vendor/textalk/websocket/tests/scripts/client.connect-handshake-error.json
vendored
Normal file
65
Server/vendor/textalk/websocket/tests/scripts/client.connect-handshake-error.json
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": true,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
}
|
||||
]
|
||||
67
Server/vendor/textalk/websocket/tests/scripts/client.connect-headers.json
vendored
Normal file
67
Server/vendor/textalk/websocket/tests/scripts/client.connect-headers.json
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 255
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\nX-Very-Long_Header: This is added to provoke split reads of headers in client 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "Next234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
49
Server/vendor/textalk/websocket/tests/scripts/client.connect-invalid-key.json
vendored
Normal file
49
Server/vendor/textalk/websocket/tests/scripts/client.connect-invalid-key.json
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: BAD\r\n\r\n"
|
||||
}
|
||||
]
|
||||
49
Server/vendor/textalk/websocket/tests/scripts/client.connect-invalid-upgrade.json
vendored
Normal file
49
Server/vendor/textalk/websocket/tests/scripts/client.connect-invalid-upgrade.json
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return": "Invalid upgrade response\r\n\r\n"
|
||||
}
|
||||
]
|
||||
94
Server/vendor/textalk/websocket/tests/scripts/client.connect-persistent.json
vendored
Normal file
94
Server/vendor/textalk/websocket/tests/scripts/client.connect-persistent.json
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
5,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "persistent stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "persistent stream"
|
||||
},
|
||||
{
|
||||
"function": "ftell",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 0
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 248
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "persistent stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "persistent stream"
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return":true
|
||||
}
|
||||
]
|
||||
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-timeout.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/client.connect-timeout.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
300,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
300
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/client.connect.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/client.connect.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
23
Server/vendor/textalk/websocket/tests/scripts/client.destruct.json
vendored
Normal file
23
Server/vendor/textalk/websocket/tests/scripts/client.destruct.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
99
Server/vendor/textalk/websocket/tests/scripts/client.reconnect.json
vendored
Normal file
99
Server/vendor/textalk/websocket/tests/scripts/client.reconnect.json
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "Unknown"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_context_create",
|
||||
"params": [],
|
||||
"return": "@mock-stream-context"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_client",
|
||||
"params": [
|
||||
"tcp:\/\/localhost:8000",
|
||||
null,
|
||||
null,
|
||||
5,
|
||||
4,
|
||||
"@mock-stream-context"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
5
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return-op": "key-save",
|
||||
"return": 199
|
||||
},
|
||||
{
|
||||
"function": "fgets",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024
|
||||
],
|
||||
"return-op": "key-respond",
|
||||
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}\r\n\r\n"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 147]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [33, 111, 149, 174]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
19
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [115, 10, 246, 203, 72, 25, 252, 192, 70, 79, 244, 142, 76, 10, 230, 221, 64, 8, 240]
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
}
|
||||
]
|
||||
55
Server/vendor/textalk/websocket/tests/scripts/close-remote.json
vendored
Normal file
55
Server/vendor/textalk/websocket/tests/scripts/close-remote.json
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [136, 137]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [54, 79, 233, 244]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
9
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [117, 35, 170, 152, 89, 60, 128, 154, 81]
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return": 33
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
24
Server/vendor/textalk/websocket/tests/scripts/config-timeout.json
vendored
Normal file
24
Server/vendor/textalk/websocket/tests/scripts/config-timeout.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
300
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
}
|
||||
]
|
||||
150
Server/vendor/textalk/websocket/tests/scripts/ping-pong.json
vendored
Normal file
150
Server/vendor/textalk/websocket/tests/scripts/ping-pong.json
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 17
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 6
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [138, 139]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [1, 1, 1, 1]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
11
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [82, 100, 115, 119, 100, 115, 33, 113, 104, 111, 102]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [138, 128]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [1, 1, 1, 1]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [137, 139]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [180, 77, 192, 201]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
11
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [247, 33, 169, 172, 218, 57, 224, 185, 221, 35, 167]
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 17
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 147]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [33, 111, 149, 174]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
19
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [115, 10, 246, 203, 72, 25, 252, 192, 70, 79, 244, 142, 76, 10, 230, 221, 64, 8, 240]
|
||||
}
|
||||
]
|
||||
18
Server/vendor/textalk/websocket/tests/scripts/receive-bad-opcode.json
vendored
Normal file
18
Server/vendor/textalk/websocket/tests/scripts/receive-bad-opcode.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [140, 115]
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/receive-broken-read.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/receive-broken-read.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": true,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": true,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return":true
|
||||
}
|
||||
]
|
||||
50
Server/vendor/textalk/websocket/tests/scripts/receive-client-timeout.json
vendored
Normal file
50
Server/vendor/textalk/websocket/tests/scripts/receive-client-timeout.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": true,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return":true
|
||||
}
|
||||
]
|
||||
58
Server/vendor/textalk/websocket/tests/scripts/receive-empty-read.json
vendored
Normal file
58
Server/vendor/textalk/websocket/tests/scripts/receive-empty-read.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": true,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return":true
|
||||
}
|
||||
]
|
||||
126
Server/vendor/textalk/websocket/tests/scripts/receive-fragmentation.json
vendored
Normal file
126
Server/vendor/textalk/websocket/tests/scripts/receive-fragmentation.json
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [1, 136]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [105, 29, 187, 18]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [36, 104, 215, 102, 0, 61, 221, 96]
|
||||
},
|
||||
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [138, 139]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [1, 1, 1, 1]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
11
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [82, 100, 115, 119, 100, 115, 33, 113, 104, 111, 102]
|
||||
},
|
||||
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [0, 136]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [221, 240, 46, 69]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [188, 151, 67, 32, 179, 132, 14, 49]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [128, 131]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [9, 60, 117, 193]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
3
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [108, 79, 1]
|
||||
}
|
||||
]
|
||||
9
Server/vendor/textalk/websocket/tests/scripts/send-bad-opcode.json
vendored
Normal file
9
Server/vendor/textalk/websocket/tests/scripts/send-bad-opcode.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
}
|
||||
]
|
||||
43
Server/vendor/textalk/websocket/tests/scripts/send-broken-write.json
vendored
Normal file
43
Server/vendor/textalk/websocket/tests/scripts/send-broken-write.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 18
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": true,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
86
Server/vendor/textalk/websocket/tests/scripts/send-convenicance.json
vendored
Normal file
86
Server/vendor/textalk/websocket/tests/scripts/send-convenicance.json
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 26
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 6
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 6
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:8000"
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
}
|
||||
]
|
||||
43
Server/vendor/textalk/websocket/tests/scripts/send-failed-write.json
vendored
Normal file
43
Server/vendor/textalk/websocket/tests/scripts/send-failed-write.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": true,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
50
Server/vendor/textalk/websocket/tests/scripts/send-receive-128.json
vendored
Normal file
50
Server/vendor/textalk/websocket/tests/scripts/send-receive-128.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 132
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 126]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [0, 128]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
128
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.128.txt", 0, 132]
|
||||
}
|
||||
]
|
||||
113
Server/vendor/textalk/websocket/tests/scripts/send-receive-65536.json
vendored
Normal file
113
Server/vendor/textalk/websocket/tests/scripts/send-receive-65536.json
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 65546
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 127]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [0, 0, 0, 0, 0, 1, 0, 0]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
65536
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 0, 16374]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
49162
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 16374, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
40970
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 24566, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
32778
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 32758, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
24586
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 40950, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
16394
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 49142, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8202
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 57334, 8192]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
10
|
||||
],
|
||||
"return-op": "file",
|
||||
"return": ["payload.65536.txt", 65526, 10]
|
||||
}
|
||||
]
|
||||
112
Server/vendor/textalk/websocket/tests/scripts/send-receive-multi-fragment.json
vendored
Normal file
112
Server/vendor/textalk/websocket/tests/scripts/send-receive-multi-fragment.json
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return": 14
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return": 14
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return": 9
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [1, 136]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [105, 29, 187, 18]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [36, 104, 215, 102, 0, 61, 221, 96]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [0, 136]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [221, 240, 46, 69]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
8
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [188, 151, 67, 32, 179, 132, 14, 49]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [128, 131]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [9, 60, 117, 193]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
3
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [108, 79, 1]
|
||||
}
|
||||
]
|
||||
50
Server/vendor/textalk/websocket/tests/scripts/send-receive.json
vendored
Normal file
50
Server/vendor/textalk/websocket/tests/scripts/send-receive.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 23
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 147]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [33, 111, 149, 174]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
19
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [115, 10, 246, 203, 72, 25, 252, 192, 70, 79, 244, 142, 76, 10, 230, 221, 64, 8, 240]
|
||||
}
|
||||
]
|
||||
315
Server/vendor/textalk/websocket/tests/scripts/server.accept-destruct.json
vendored
Normal file
315
Server/vendor/textalk/websocket/tests/scripts/server.accept-destruct.json
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [
|
||||
"@mock-socket"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "GET \/my\/mock\/path HTTP\/1.1"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 171,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "host: localhost:8000"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 149,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "user-agent: websocket-client-php"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 115,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "connection: Upgrade"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 94,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "upgrade: websocket"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 74,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-key: cktLWXhUdDQ2OXF0ZCFqOQ=="
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 29,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-version: 13"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
,
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
"HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: YmysboNHNoWzWVeQpduY7xELjgU=\r\n\r\n"
|
||||
],
|
||||
"return": 129
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [129, 147]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [33, 111, 149, 174]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
19
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [115, 10, 246, 203, 72, 25, 252, 192, 70, 79, 244, 142, 76, 10, 230, 221, 64, 8, 240]
|
||||
},
|
||||
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
18
Server/vendor/textalk/websocket/tests/scripts/server.accept-error-connect.json
vendored
Normal file
18
Server/vendor/textalk/websocket/tests/scripts/server.accept-error-connect.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [],
|
||||
"error": {
|
||||
"msg": "A PHP error",
|
||||
"type": 512
|
||||
},
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
false
|
||||
],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
14
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-connect.json
vendored
Normal file
14
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-connect.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
false
|
||||
],
|
||||
"return": true
|
||||
}
|
||||
]
|
||||
265
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-http.json
vendored
Normal file
265
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-http.json
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [
|
||||
"@mock-socket"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "missing http header"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 171,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "host: localhost:8000"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 149,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "user-agent: websocket-client-php"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 115,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "connection: Upgrade"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 94,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "upgrade: websocket"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 74,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "no key in upgrade request"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 29,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-version: 13"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
,
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
265
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-ws-key.json
vendored
Normal file
265
Server/vendor/textalk/websocket/tests/scripts/server.accept-failed-ws-key.json
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [
|
||||
"@mock-socket"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "GET \/my\/mock\/path HTTP\/1.1"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 171,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "host: localhost:8000"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 149,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "user-agent: websocket-client-php"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 115,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "connection: Upgrade"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 94,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "upgrade: websocket"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 74,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "no key in upgrade request"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 29,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-version: 13"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
,
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
289
Server/vendor/textalk/websocket/tests/scripts/server.accept-timeout.json
vendored
Normal file
289
Server/vendor/textalk/websocket/tests/scripts/server.accept-timeout.json
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [
|
||||
"@mock-socket",
|
||||
300
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_set_timeout",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
300
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "GET \/my\/mock\/path HTTP\/1.1"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 171,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "host: localhost:8000"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 149,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "user-agent: websocket-client-php"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 115,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "connection: Upgrade"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 94,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "upgrade: websocket"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 74,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-key: cktLWXhUdDQ2OXF0ZCFqOQ=="
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 29,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-version: 13"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
,
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
"HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: YmysboNHNoWzWVeQpduY7xELjgU=\r\n\r\n"
|
||||
],
|
||||
"return": 129
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
}
|
||||
]
|
||||
287
Server/vendor/textalk/websocket/tests/scripts/server.accept.json
vendored
Normal file
287
Server/vendor/textalk/websocket/tests/scripts/server.accept.json
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_accept",
|
||||
"params": [
|
||||
"@mock-socket"
|
||||
],
|
||||
"return": "@mock-stream"
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_get_name",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "127.0.0.1:12345"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "GET \/my\/mock\/path HTTP\/1.1"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 171,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "host: localhost:8000"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 149,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "user-agent: websocket-client-php"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 115,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "connection: Upgrade"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 94,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "upgrade: websocket"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 74,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-key: cktLWXhUdDQ2OXF0ZCFqOQ=="
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 29,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": "sec-websocket-version: 13"
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 2,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
,
|
||||
{
|
||||
"function": "stream_get_line",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
1024,
|
||||
"\r\n"
|
||||
],
|
||||
"return": ""
|
||||
},
|
||||
{
|
||||
"function": "stream_get_meta_data",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": {
|
||||
"timed_out": false,
|
||||
"blocked": true,
|
||||
"eof": false,
|
||||
"stream_type": "tcp_socket\/ssl",
|
||||
"mode": "r+",
|
||||
"unread_bytes": 0,
|
||||
"seekable": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "feof",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
"HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: YmysboNHNoWzWVeQpduY7xELjgU=\r\n\r\n"
|
||||
],
|
||||
"return": 129
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": 13
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
}
|
||||
]
|
||||
70
Server/vendor/textalk/websocket/tests/scripts/server.close.json
vendored
Normal file
70
Server/vendor/textalk/websocket/tests/scripts/server.close.json
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
[
|
||||
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fwrite",
|
||||
"params": [],
|
||||
"return":12
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "stream"
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
2
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [136,154]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
4
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [245,55,62,8]
|
||||
},
|
||||
{
|
||||
"function": "fread",
|
||||
"params": [
|
||||
"@mock-stream",
|
||||
26
|
||||
],
|
||||
"return-op": "chr-array",
|
||||
"return": [246,223,125,100,154,68,91,40,148,84,85,102,154,64,82,109,145,80,91,108,207,23,15,56,197,7]
|
||||
},
|
||||
{
|
||||
"function": "fclose",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": true
|
||||
},
|
||||
{
|
||||
"function": "get_resource_type",
|
||||
"params": [
|
||||
"@mock-stream"
|
||||
],
|
||||
"return": "Unknown"
|
||||
}
|
||||
]
|
||||
28
Server/vendor/textalk/websocket/tests/scripts/server.construct-error-socket-server.json
vendored
Normal file
28
Server/vendor/textalk/websocket/tests/scripts/server.construct-error-socket-server.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_server",
|
||||
"params": [
|
||||
"tcp://0.0.0.0:9999",
|
||||
null,
|
||||
null
|
||||
],
|
||||
"error": {
|
||||
"msg": "A PHP error",
|
||||
"type": 512
|
||||
},
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_server",
|
||||
"params": [
|
||||
"tcp://0.0.0.0:10000",
|
||||
null,
|
||||
null
|
||||
],
|
||||
"error": {
|
||||
"msg": "A PHP error",
|
||||
"type": 512
|
||||
},
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
20
Server/vendor/textalk/websocket/tests/scripts/server.construct-failed-socket-server.json
vendored
Normal file
20
Server/vendor/textalk/websocket/tests/scripts/server.construct-failed-socket-server.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_server",
|
||||
"params": [
|
||||
"tcp://0.0.0.0:9999",
|
||||
null,
|
||||
null
|
||||
],
|
||||
"return": false
|
||||
},
|
||||
{
|
||||
"function": "stream_socket_server",
|
||||
"params": [
|
||||
"tcp://0.0.0.0:10000",
|
||||
null,
|
||||
null
|
||||
],
|
||||
"return": false
|
||||
}
|
||||
]
|
||||
11
Server/vendor/textalk/websocket/tests/scripts/server.construct.json
vendored
Normal file
11
Server/vendor/textalk/websocket/tests/scripts/server.construct.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"function": "stream_socket_server",
|
||||
"params": [
|
||||
"tcp://0.0.0.0:8000",
|
||||
null,
|
||||
null
|
||||
],
|
||||
"return": "@mock-socket"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user