mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-08-07 07:16:13 +00:00
d16b7f60f3
The WebSocket support added for TrueNAS JSON-RPC 2.0 requires the phrity/websocket library to actually be available at runtime. This repo commits the vendor/ tree (CI does not run composer install), so the dependency and composer.lock must be committed for class_exists() checks in the TrueNAS app to succeed. - composer require phrity/websocket:^3.6 (resolves to 3.7.3) with lock and vendor/ committed - Fix TrueNASWebSocketClient to catch WebSocket\Exception\Exception (phrity/websocket v3 namespace) instead of the non-existent WebSocket\ConnectionException from the old textalk/websocket v1/v2 API, so connection/call failures are logged and wrapped as intended
134 lines
4.2 KiB
PHP
134 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace Phrity\Net;
|
|
|
|
use InvalidArgumentException;
|
|
use Phrity\Util\ErrorHandler;
|
|
use Psr\Http\Message\{
|
|
StreamFactoryInterface,
|
|
UriInterface
|
|
};
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* StreamFactory class.
|
|
* @see https://www.php-fig.org/psr/psr-17/#24-streamfactoryinterface
|
|
*/
|
|
class StreamFactory implements StreamFactoryInterface
|
|
{
|
|
/** @var array<string> */
|
|
private static array $modes = ['r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+', 'e'];
|
|
|
|
private ErrorHandler $handler;
|
|
|
|
/**
|
|
* Create new stream wrapper instance.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->handler = new ErrorHandler();
|
|
}
|
|
|
|
|
|
// ---------- PSR-17 methods --------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Create a new stream from a string.
|
|
* @param string $content String content with which to populate the stream.
|
|
* @return Stream A stream instance.
|
|
*/
|
|
public function createStream(string $content = ''): Stream
|
|
{
|
|
$resource = $this->createResource('php://temp', 'r+');
|
|
fwrite($resource, $content);
|
|
return $this->createStreamFromResource($resource);
|
|
}
|
|
|
|
/**
|
|
* Create a stream from an existing file.
|
|
* @param string $filename The filename or stream URI to use as basis of stream.
|
|
* @param string $mode The mode with which to open the underlying filename/stream.
|
|
* @throws InvalidArgumentException If the mode is invalid.
|
|
* @return Stream A stream instance.
|
|
*/
|
|
public function createStreamFromFile(string $filename, string $mode = 'r'): Stream
|
|
{
|
|
if (!in_array($mode, self::$modes)) {
|
|
throw new InvalidArgumentException("Invalid mode '{$mode}'.");
|
|
}
|
|
$resource = $this->createResource($filename, $mode);
|
|
return $this->createStreamFromResource($resource);
|
|
}
|
|
|
|
/**
|
|
* Create a new stream from an existing resource.
|
|
* The stream MUST be readable and may be writable.
|
|
* @param resource $resource The PHP resource to use as the basis for the stream.
|
|
* @return Stream A stream instance.
|
|
*/
|
|
public function createStreamFromResource($resource): Stream
|
|
{
|
|
return new Stream($resource);
|
|
}
|
|
|
|
|
|
// ---------- Extensions ------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Create a new socket client.
|
|
* @param UriInterface $uri The URI to connect to.
|
|
* @return SocketClient A socket client instance.
|
|
*/
|
|
public function createSocketClient(UriInterface $uri, Context|null $context = null): SocketClient
|
|
{
|
|
return new SocketClient($uri, $context);
|
|
}
|
|
|
|
/**
|
|
* Create a new socket server.
|
|
* @param UriInterface $uri The URI to create server on.
|
|
* @return SocketServer A socket server instance.
|
|
*/
|
|
public function createSocketServer(UriInterface $uri, Context|null $context = null): SocketServer
|
|
{
|
|
return new SocketServer($uri, $context);
|
|
}
|
|
|
|
/**
|
|
* Create a new ocket stream from an existing resource.
|
|
* The stream MUST be readable and may be writable.
|
|
* @param resource $resource The PHP resource to use as the basis for the stream.
|
|
* @return SocketStream A socket stream instance.
|
|
*/
|
|
public function createSocketStreamFromResource($resource): SocketStream
|
|
{
|
|
return new SocketStream($resource);
|
|
}
|
|
|
|
/**
|
|
* Create a new stream collection.
|
|
* @return StreamCollection A stream collection.
|
|
*/
|
|
public function createStreamCollection(): StreamCollection
|
|
{
|
|
return new StreamCollection();
|
|
}
|
|
|
|
|
|
// ---------- Helpers ---------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @return resource
|
|
* @throws RuntimeException If fails to open resource
|
|
*/
|
|
private function createResource(string $filename, string $mode)
|
|
{
|
|
/** @throws RuntimeException */
|
|
return $this->handler->with(function () use ($filename, $mode) {
|
|
/** @var resource $resource */
|
|
$resource = fopen($filename, $mode);
|
|
return $resource;
|
|
}, new RuntimeException("Could not open '{$filename}'."));
|
|
}
|
|
}
|