Commit inicial con archivos existentes

This commit is contained in:
2026-01-17 16:14:00 -06:00
parent 48671dc88e
commit 4c48c279de
2539 changed files with 2412708 additions and 0 deletions

19
vendor/ratchet/pawl/LICENSE vendored Executable file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2014 Chris Boden
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

84
vendor/ratchet/pawl/README.md vendored Executable file
View File

@@ -0,0 +1,84 @@
# Pawl
[![Autobahn Testsuite](https://img.shields.io/badge/Autobahn-passing-brightgreen.svg)](http://socketo.me/reports/pawl/index.html)
[![CI status](https://github.com/ratchetphp/Pawl/workflows/CI/badge.svg)](https://github.com/ratchetphp/Pawl/actions)
An asynchronous WebSocket client in PHP
#### Install via composer:
composer require ratchet/pawl
#### Usage
Pawl as a standalone app: Connect to an echo server, send a message, display output, close connection:
```php
<?php
require __DIR__ . '/vendor/autoload.php';
\Ratchet\Client\connect('wss://echo.websocket.org:443')->then(function($conn) {
$conn->on('message', function($msg) use ($conn) {
echo "Received: {$msg}\n";
$conn->close();
});
$conn->send('Hello World!');
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
```
#### Classes
There are 3 primary classes to be aware of and use in Pawl:
##### Connector:
Makes HTTP requests to servers returning a promise that, if successful, will resolve to a WebSocket object.
A connector is configured via its constructor and a request is made by invoking the class. Multiple connections can be established through a single connector. The invoke mehtod has 3 parameters:
* **$url**: String; A valid uri string (starting with ws:// or wss://) to connect to (also accepts PSR-7 Uri object)
* **$subProtocols**: Array; An optional indexed array of WebSocket sub-protocols to negotiate to the server with. The connection will fail if the client and server can not agree on one if any are provided
* **$headers**: Array; An optional associative array of additional headers requests to use when initiating the handshake. A common header to set is `Origin`
##### WebSocket:
This is the object used to interact with a WebSocket server. It has two methods: `send` and `close`.
It has two public properties: `request` and `response` which are PSR-7 objects representing the client and server side HTTP handshake headers used to establish the WebSocket connection.
##### Message:
This is the object received from a WebSocket server. It has a `__toString` method which is how most times you will want to access the data received.
If you need to do binary messaging you will most likely need to use methods on the object.
#### Example
A more in-depth example using explicit interfaces: Requesting sub-protocols, and sending custom headers while using a specific React Event Loop:
```php
<?php
require __DIR__ . '/vendor/autoload.php';
$reactConnector = new \React\Socket\Connector([
'dns' => '8.8.8.8',
'timeout' => 10
]);
$loop = \React\EventLoop\Loop::get();
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);
$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
->then(function(\Ratchet\Client\WebSocket $conn) {
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
echo "Received: {$msg}\n";
$conn->close();
});
$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";
});
$conn->send('Hello World!');
}, function(\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});
```

25
vendor/ratchet/pawl/composer.json vendored Executable file
View File

@@ -0,0 +1,25 @@
{
"name": "ratchet/pawl"
, "description": "Asynchronous WebSocket client"
, "keywords": ["WebSocket", "client", "Ratchet", "async", "websocket client"]
, "license": "MIT"
, "autoload": {
"psr-4": {
"Ratchet\\Client\\": "src"
}
, "files": ["src/functions_include.php"]
}
, "require": {
"php": ">=7.4"
, "evenement/evenement": "^3.0 || ^2.0"
, "guzzlehttp/psr7": "^2.0"
, "ratchet/rfc6455": "^0.3.1 || ^0.4.0"
, "react/socket": "^1.9"
}
, "require-dev": {
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8"
}
, "suggest": {
"reactivex/rxphp": "~2.0"
}
}

158
vendor/ratchet/pawl/src/Connector.php vendored Executable file
View File

@@ -0,0 +1,158 @@
<?php
namespace Ratchet\Client;
use Ratchet\RFC6455\Handshake\ClientNegotiator;
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\Socket\ConnectionInterface;
use React\Socket\ConnectorInterface;
use React\Promise\Deferred;
use function React\Promise\reject;
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Psr7 as gPsr;
class Connector {
protected $_loop;
protected $_connector;
protected $_negotiator;
public function __construct(?LoopInterface $loop = null, ?ConnectorInterface $connector = null) {
$this->_loop = $loop ?: Loop::get();
if (null === $connector) {
$connector = new \React\Socket\Connector([
'timeout' => 20
], $this->_loop);
}
$this->_connector = $connector;
$this->_negotiator = new ClientNegotiator(new gPsr\HttpFactory());
}
/**
* @param string $url
* @param array $subProtocols
* @param array $headers
* @return \React\Promise\PromiseInterface
*/
public function __invoke($url, array $subProtocols = [], array $headers = []) {
try {
$request = $this->generateRequest($url, $subProtocols, $headers);
$uri = $request->getUri();
} catch (\Exception $e) {
return reject($e);
}
$secure = 'wss' === substr($url, 0, 3);
$connector = $this->_connector;
$port = $uri->getPort() ?: ($secure ? 443 : 80);
$scheme = $secure ? 'tls' : 'tcp';
$uriString = $scheme . '://' . $uri->getHost() . ':' . $port;
$connecting = $connector->connect($uriString);
$futureWsConn = new Deferred(function ($_, $reject) use ($url, $connecting) {
$reject(new \RuntimeException(
'Connection to ' . $url . ' cancelled during handshake'
));
// either close active connection or cancel pending connection attempt
$connecting->then(function (ConnectionInterface $connection) {
$connection->close();
});
$connecting->cancel();
});
$connecting->then(function(ConnectionInterface $conn) use ($request, $subProtocols, $futureWsConn) {
$earlyClose = function() use ($futureWsConn) {
$futureWsConn->reject(new \RuntimeException('Connection closed before handshake'));
};
$stream = $conn;
$stream->on('close', $earlyClose);
$futureWsConn->promise()->then(function() use ($stream, $earlyClose) {
$stream->removeListener('close', $earlyClose);
}, function (\Exception $exception) use ($futureWsConn) {
$futureWsConn->reject($exception);
});
$buffer = '';
$headerParser = function($data) use ($stream, &$headerParser, &$buffer, $futureWsConn, $request, $subProtocols) {
$buffer .= $data;
if (false == strpos($buffer, "\r\n\r\n")) {
return;
}
$stream->removeListener('data', $headerParser);
$response = gPsr\Message::parseResponse($buffer);
if (!$this->_negotiator->validateResponse($request, $response)) {
$futureWsConn->reject(new \DomainException(gPsr\Message::toString($response)));
$stream->close();
return;
}
$acceptedProtocol = $response->getHeader('Sec-WebSocket-Protocol');
if ((count($subProtocols) > 0) && 1 !== count(array_intersect($subProtocols, $acceptedProtocol))) {
$futureWsConn->reject(new \DomainException('Server did not respond with an expected Sec-WebSocket-Protocol'));
$stream->close();
return;
}
$futureWsConn->resolve(new WebSocket($stream, $response, $request));
$futureWsConn->promise()->then(function(WebSocket $conn) use ($stream) {
$stream->emit('data', [$conn->response->getBody()->getContents(), $stream]);
});
};
$stream->on('data', $headerParser);
$stream->write(gPsr\Message::toString($request));
}, array($futureWsConn, 'reject'));
return $futureWsConn->promise();
}
/**
* @param string $url
* @param array $subProtocols
* @param array $headers
* @throws \InvalidArgumentException
* @return \Psr\Http\Message\RequestInterface
*/
protected function generateRequest($url, array $subProtocols, array $headers) {
$uri = gPsr\Utils::uriFor($url);
$scheme = $uri->getScheme();
if (!in_array($scheme, ['ws', 'wss'])) {
throw new \InvalidArgumentException(sprintf('Cannot connect to invalid URL (%s)', $url));
}
$uri = $uri->withScheme('wss' === $scheme ? 'HTTPS' : 'HTTP');
$headers += ['User-Agent' => 'Ratchet-Pawl/0.4.1'];
$request = array_reduce(array_keys($headers), function(RequestInterface $request, $header) use ($headers) {
return $request->withHeader($header, $headers[$header]);
}, $this->_negotiator->generateRequest($uri));
if (!$request->getHeader('Origin')) {
$request = $request->withHeader('Origin', str_replace('ws', 'http', $scheme) . '://' . $uri->getHost());
}
if (count($subProtocols) > 0) {
$protocols = implode(',', $subProtocols);
if ($protocols != "") {
$request = $request->withHeader('Sec-WebSocket-Protocol', $protocols);
}
}
return $request;
}
}

157
vendor/ratchet/pawl/src/WebSocket.php vendored Executable file
View File

@@ -0,0 +1,157 @@
<?php
namespace Ratchet\Client;
use Evenement\EventEmitterTrait;
use Evenement\EventEmitterInterface;
use React\Socket\ConnectionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Ratchet\RFC6455\Messaging\MessageBuffer;
use Ratchet\RFC6455\Messaging\CloseFrameChecker;
use Ratchet\RFC6455\Messaging\MessageInterface;
use Ratchet\RFC6455\Messaging\FrameInterface;
use Ratchet\RFC6455\Messaging\Frame;
class WebSocket implements EventEmitterInterface {
use EventEmitterTrait;
/**
* The request headers sent to establish the connection
* @var \Psr\Http\Message\RequestInterface
*/
public $request;
/**
* The response headers received from the server to establish the connection
* @var \Psr\Http\Message\ResponseInterface
*/
public $response;
/**
* @var \React\Socket\ConnectionInterface
*/
protected $_stream;
/**
* @var \Closure
*/
protected $_close;
/**
* WebSocket constructor.
* @param \React\Socket\ConnectionInterface $stream
* @param \Psr\Http\Message\ResponseInterface $response
* @param \Psr\Http\Message\RequestInterface $request
* @event message
* @event ping
* @event pong
* @event close
* @event error
*/
public function __construct(ConnectionInterface $stream, ResponseInterface $response, RequestInterface $request) {
$this->_stream = $stream;
$this->response = $response;
$this->request = $request;
$self = $this;
$this->_close = function($code = null, $reason = null) use ($self) {
static $sent = false;
if ($sent) {
return;
}
$sent = true;
$self->emit('close', [$code, $reason, $self]);
};
$reusableUAException = new \UnderflowException;
$streamer = new MessageBuffer(
new CloseFrameChecker,
function(MessageInterface $msg) {
$this->emit('message', [$msg, $this]);
},
function(FrameInterface $frame) use (&$streamer) {
switch ($frame->getOpcode()) {
case Frame::OP_CLOSE:
$frameContents = $frame->getPayload();
$reason = '';
$code = unpack('n', substr($frameContents, 0, 2));
$code = reset($code);
if (($frameLen = strlen($frameContents)) > 2) {
$reason = substr($frameContents, 2, $frameLen);
}
$closeFn = $this->_close;
$closeFn($code, $reason);
return $this->_stream->end($streamer->newFrame($frame->getPayload(), true, Frame::OP_CLOSE)->maskPayload()->getContents());
case Frame::OP_PING:
$this->emit('ping', [$frame, $this]);
return $this->send($streamer->newFrame($frame->getPayload(), true, Frame::OP_PONG));
case Frame::OP_PONG:
return $this->emit('pong', [$frame, $this]);
default:
return $this->close(Frame::CLOSE_PROTOCOL);
}
},
false,
function() use ($reusableUAException) {
return $reusableUAException;
}
);
$stream->on('data', [$streamer, 'onData']);
$stream->on('close', function () {
$close = $this->_close;
$close(Frame::CLOSE_ABNORMAL, 'Underlying connection closed');
});
$stream->on('error', function($error) {
$this->emit('error', [$error, $this]);
});
$stream->on('drain', function () {
$this->emit('drain');
});
}
public function send($msg) {
if ($msg instanceof MessageInterface) {
foreach ($msg as $frame) {
$frame->maskPayload();
}
} else {
if (!($msg instanceof Frame)) {
$msg = new Frame($msg);
}
$msg->maskPayload();
}
return $this->_stream->write($msg->getContents());
}
public function close($code = 1000, $reason = '') {
$frame = new Frame(pack('n', $code) . $reason, true, Frame::OP_CLOSE);
$frame->maskPayload();
$this->_stream->write($frame->getContents());
$closeFn = $this->_close;
$closeFn($code, $reason);
$this->_stream->end();
}
public function pause()
{
$this->_stream->pause();
}
public function resume()
{
$this->_stream->resume();
}
}

17
vendor/ratchet/pawl/src/functions.php vendored Executable file
View File

@@ -0,0 +1,17 @@
<?php
namespace Ratchet\Client;
use React\EventLoop\LoopInterface;
/**
* @param string $url
* @param array $subProtocols
* @param array $headers
* @param LoopInterface|null $loop
* @return \React\Promise\PromiseInterface<\Ratchet\Client\WebSocket>
*/
function connect($url, array $subProtocols = [], $headers = [], ?LoopInterface $loop = null) {
$connector = new Connector($loop);
$connection = $connector($url, $subProtocols, $headers);
return $connection;
}

View File

@@ -0,0 +1,5 @@
<?php
if (!function_exists('Ratchet\Client\connect')) {
require __DIR__ . '/functions.php';
}