diff --git a/composer.json b/composer.json index c1c3687..03ef782 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "A package to use Websocket API of ping0.cc to monitor the ping latency of target host [TEST ONLY]", "type": "library", "require": { - "textalk/websocket": "dev-master" + "textalk/websocket": ">=1.5" }, "license": "AGPL", "autoload": { diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index 45db919..0000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,25 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - /** @var \Closure(string):void */ - private static $includeFile; - - /** @var string|null */ - private $vendorDir; - - // PSR-4 - /** - * @var array> - */ - private $prefixLengthsPsr4 = array(); - /** - * @var array> - */ - private $prefixDirsPsr4 = array(); - /** - * @var list - */ - private $fallbackDirsPsr4 = array(); - - // PSR-0 - /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array>> - */ - private $prefixesPsr0 = array(); - /** - * @var list - */ - private $fallbackDirsPsr0 = array(); - - /** @var bool */ - private $useIncludePath = false; - - /** - * @var array - */ - private $classMap = array(); - - /** @var bool */ - private $classMapAuthoritative = false; - - /** - * @var array - */ - private $missingClasses = array(); - - /** @var string|null */ - private $apcuPrefix; - - /** - * @var array - */ - private static $registeredLoaders = array(); - - /** - * @param string|null $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - self::initializeIncludeClosure(); - } - - /** - * @return array> - */ - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - /** - * @return array> - */ - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - /** - * @return list - */ - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - /** - * @return list - */ - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - /** - * @return array Array of classname => path - */ - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - * - * @return void - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void - */ - public function add($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 base directories - * - * @return void - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - * - * @return void - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - * - * @return void - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - * - * @return void - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return true|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); - - return true; - } - - return null; - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. - * - * @return array - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } - - /** - * @return void - */ - private static function initializeIncludeClosure() - { - if (self::$includeFile !== null) { - return; - } - - /** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - */ - self::$includeFile = \Closure::bind(static function($file) { - include $file; - }, null, null); - } -} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php deleted file mode 100644 index 51e734a..0000000 --- a/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,359 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer; - -use Composer\Autoload\ClassLoader; -use Composer\Semver\VersionParser; - -/** - * This class is copied in every Composer installed project and available to all - * - * See also https://getcomposer.org/doc/07-runtime.md#installed-versions - * - * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final - */ -class InstalledVersions -{ - /** - * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null - */ - private static $installed; - - /** - * @var bool|null - */ - private static $canGetVendors; - - /** - * @var array[] - * @psalm-var array}> - */ - private static $installedByVendor = array(); - - /** - * Returns a list of all package names which are present, either by being installed, replaced or provided - * - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackages() - { - $packages = array(); - foreach (self::getInstalled() as $installed) { - $packages[] = array_keys($installed['versions']); - } - - if (1 === \count($packages)) { - return $packages[0]; - } - - return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); - } - - /** - * Returns a list of all package names with a specific type e.g. 'library' - * - * @param string $type - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackagesByType($type) - { - $packagesByType = array(); - - foreach (self::getInstalled() as $installed) { - foreach ($installed['versions'] as $name => $package) { - if (isset($package['type']) && $package['type'] === $type) { - $packagesByType[] = $name; - } - } - } - - return $packagesByType; - } - - /** - * Checks whether the given package is installed - * - * This also returns true if the package name is provided or replaced by another package - * - * @param string $packageName - * @param bool $includeDevRequirements - * @return bool - */ - public static function isInstalled($packageName, $includeDevRequirements = true) - { - foreach (self::getInstalled() as $installed) { - if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; - } - } - - return false; - } - - /** - * Checks whether the given package satisfies a version constraint - * - * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: - * - * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') - * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * @return bool - */ - public static function satisfies(VersionParser $parser, $packageName, $constraint) - { - $constraint = $parser->parseConstraints((string) $constraint); - $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - - return $provided->matches($constraint); - } - - /** - * Returns a version constraint representing all the range(s) which are installed for a given package - * - * It is easier to use this via isInstalled() with the $constraint argument if you need to check - * whether a given version of a package is installed, and not just whether it exists - * - * @param string $packageName - * @return string Version constraint usable with composer/semver - */ - public static function getVersionRanges($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - $ranges = array(); - if (isset($installed['versions'][$packageName]['pretty_version'])) { - $ranges[] = $installed['versions'][$packageName]['pretty_version']; - } - if (array_key_exists('aliases', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); - } - if (array_key_exists('replaced', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); - } - if (array_key_exists('provided', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); - } - - return implode(' || ', $ranges); - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['version'])) { - return null; - } - - return $installed['versions'][$packageName]['version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getPrettyVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['pretty_version'])) { - return null; - } - - return $installed['versions'][$packageName]['pretty_version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference - */ - public static function getReference($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['reference'])) { - return null; - } - - return $installed['versions'][$packageName]['reference']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. - */ - public static function getInstallPath($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} - */ - public static function getRootPackage() - { - $installed = self::getInstalled(); - - return $installed[0]['root']; - } - - /** - * Returns the raw installed.php data for custom implementations - * - * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. - * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} - */ - public static function getRawData() - { - @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = include __DIR__ . '/installed.php'; - } else { - self::$installed = array(); - } - } - - return self::$installed; - } - - /** - * Returns the raw data of all installed.php which are currently loaded for custom implementations - * - * @return array[] - * @psalm-return list}> - */ - public static function getAllRawData() - { - return self::getInstalled(); - } - - /** - * Lets you reload the static array from another file - * - * This is only useful for complex integrations in which a project needs to use - * this class but then also needs to execute another project's autoloader in process, - * and wants to ensure both projects have access to their version of installed.php. - * - * A typical case would be PHPUnit, where it would need to make sure it reads all - * the data it needs from this class, then call reload() with - * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure - * the project in which it runs can then also use this class safely, without - * interference between PHPUnit's dependencies and the project's dependencies. - * - * @param array[] $data A vendor/composer/installed.php data set - * @return void - * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data - */ - public static function reload($data) - { - self::$installed = $data; - self::$installedByVendor = array(); - } - - /** - * @return array[] - * @psalm-return list}> - */ - private static function getInstalled() - { - if (null === self::$canGetVendors) { - self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); - } - - $installed = array(); - - if (self::$canGetVendors) { - foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - if (isset(self::$installedByVendor[$vendorDir])) { - $installed[] = self::$installedByVendor[$vendorDir]; - } elseif (is_file($vendorDir.'/composer/installed.php')) { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; - } - } - } - } - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require __DIR__ . '/installed.php'; - self::$installed = $required; - } else { - self::$installed = array(); - } - } - - if (self::$installed !== array()) { - $installed[] = self::$installed; - } - - return $installed; - } -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index f27399a..0000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 0fb0a2c..0000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,10 +0,0 @@ - $vendorDir . '/composer/InstalledVersions.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 15a2ff3..0000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($vendorDir . '/textalk/websocket/lib'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), - 'Phrity\\Util\\' => array($vendorDir . '/phrity/util-errorhandler/src'), - 'Phrity\\Net\\' => array($vendorDir . '/phrity/net-uri/src'), - 'Laysense\\Monitor\\' => array($baseDir . '/src'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index 921d125..0000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,38 +0,0 @@ -register(true); - - return $loader; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index 3bc399e..0000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,68 +0,0 @@ - - array ( - 'WebSocket\\' => 10, - ), - 'P' => - array ( - 'Psr\\Log\\' => 8, - 'Psr\\Http\\Message\\' => 17, - 'Phrity\\Util\\' => 12, - 'Phrity\\Net\\' => 11, - ), - 'L' => - array ( - 'Laysense\\Monitor\\' => 17, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'WebSocket\\' => - array ( - 0 => __DIR__ . '/..' . '/textalk/websocket/lib', - ), - 'Psr\\Log\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/log/src', - ), - 'Psr\\Http\\Message\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/http-factory/src', - 1 => __DIR__ . '/..' . '/psr/http-message/src', - ), - 'Phrity\\Util\\' => - array ( - 0 => __DIR__ . '/..' . '/phrity/util-errorhandler/src', - ), - 'Phrity\\Net\\' => - array ( - 0 => __DIR__ . '/..' . '/phrity/net-uri/src', - ), - 'Laysense\\Monitor\\' => - array ( - 0 => __DIR__ . '/../..' . '/src', - ), - ); - - public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit7f9863daaab5193cdcf774ddaa946c8d::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit7f9863daaab5193cdcf774ddaa946c8d::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit7f9863daaab5193cdcf774ddaa946c8d::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json deleted file mode 100644 index e21dab3..0000000 --- a/vendor/composer/installed.json +++ /dev/null @@ -1,378 +0,0 @@ -{ - "packages": [ - { - "name": "phrity/net-uri", - "version": "1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sirn-se/phrity-net-uri.git", - "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/3f458e0c4d1ddc0e218d7a5b9420127c63925f43", - "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.4 | ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.0 | ^2.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^9.0 | ^10.0", - "squizlabs/php_codesniffer": "^3.0" - }, - "time": "2023-08-21T10:33:06+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Phrity\\Net\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sören Jensen", - "email": "sirn@sirn.se", - "homepage": "https://phrity.sirn.se" - } - ], - "description": "PSR-7 Uri and PSR-17 UriFactory implementation", - "homepage": "https://phrity.sirn.se/net-uri", - "keywords": [ - "psr-17", - "psr-7", - "uri", - "uri factory" - ], - "support": { - "issues": "https://github.com/sirn-se/phrity-net-uri/issues", - "source": "https://github.com/sirn-se/phrity-net-uri/tree/1.3.0" - }, - "install-path": "../phrity/net-uri" - }, - { - "name": "phrity/util-errorhandler", - "version": "1.1.1", - "version_normalized": "1.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sirn-se/phrity-util-errorhandler.git", - "reference": "483228156e06673963902b1cc1e6bd9541ab4d5e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sirn-se/phrity-util-errorhandler/zipball/483228156e06673963902b1cc1e6bd9541ab4d5e", - "reference": "483228156e06673963902b1cc1e6bd9541ab4d5e", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.4 | ^8.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "time": "2024-09-12T06:49:16+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Phrity\\Util\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sören Jensen", - "email": "sirn@sirn.se", - "homepage": "https://phrity.sirn.se" - } - ], - "description": "Inline error handler; catch and resolve errors for code block.", - "homepage": "https://phrity.sirn.se/util-errorhandler", - "keywords": [ - "error", - "warning" - ], - "support": { - "issues": "https://github.com/sirn-se/phrity-util-errorhandler/issues", - "source": "https://github.com/sirn-se/phrity-util-errorhandler/tree/1.1.1" - }, - "install-path": "../phrity/util-errorhandler" - }, - { - "name": "psr/http-factory", - "version": "dev-master", - "version_normalized": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "7037f4b0950474e9d1350e8df89b15f1842085f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/7037f4b0950474e9d1350e8df89b15f1842085f6", - "reference": "7037f4b0950474e9d1350e8df89b15f1842085f6", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-09-22T11:16:44+00:00", - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory" - }, - "install-path": "../psr/http-factory" - }, - { - "name": "psr/http-message", - "version": "1.1", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:50:52+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/1.1" - }, - "install-path": "../psr/http-message" - }, - { - "name": "psr/log", - "version": "dev-master", - "version_normalized": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": ">=8.0.0" - }, - "time": "2024-09-11T13:17:53+00:00", - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "install-path": "../psr/log" - }, - { - "name": "textalk/websocket", - "version": "dev-master", - "version_normalized": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "34b2f0efa2e1c071b046e2b98848178fddf21552" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/34b2f0efa2e1c071b046e2b98848178fddf21552", - "reference": "34b2f0efa2e1c071b046e2b98848178fddf21552", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.4 | ^8.0", - "phrity/net-uri": "^1.0", - "phrity/util-errorhandler": "^1.0", - "psr/http-message": "^1.0", - "psr/log": "^1.0 | ^2.0 | ^3.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "time": "2023-12-16T14:43:30+00:00", - "default-branch": true, - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/master" - }, - "install-path": "../textalk/websocket" - } - ], - "dev": true, - "dev-package-names": [] -} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php deleted file mode 100644 index 977ee16..0000000 --- a/vendor/composer/installed.php +++ /dev/null @@ -1,83 +0,0 @@ - array( - 'name' => 'laysense/monitor', - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => null, - 'type' => 'library', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev' => true, - ), - 'versions' => array( - 'laysense/monitor' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => null, - 'type' => 'library', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'phrity/net-uri' => array( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'reference' => '3f458e0c4d1ddc0e218d7a5b9420127c63925f43', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phrity/net-uri', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'phrity/util-errorhandler' => array( - 'pretty_version' => '1.1.1', - 'version' => '1.1.1.0', - 'reference' => '483228156e06673963902b1cc1e6bd9541ab4d5e', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phrity/util-errorhandler', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'psr/http-factory' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '7037f4b0950474e9d1350e8df89b15f1842085f6', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/http-factory', - 'aliases' => array( - 0 => '1.0.x-dev', - ), - 'dev_requirement' => false, - ), - 'psr/http-message' => array( - 'pretty_version' => '1.1', - 'version' => '1.1.0.0', - 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/http-message', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'psr/log' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/log', - 'aliases' => array( - 0 => '3.x-dev', - ), - 'dev_requirement' => false, - ), - 'textalk/websocket' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '34b2f0efa2e1c071b046e2b98848178fddf21552', - 'type' => 'library', - 'install_path' => __DIR__ . '/../textalk/websocket', - 'aliases' => array( - 0 => '9999999-dev', - ), - 'dev_requirement' => false, - ), - ), -); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php deleted file mode 100644 index adfb472..0000000 --- a/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 80000)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/vendor/phrity/net-uri/composer.json b/vendor/phrity/net-uri/composer.json deleted file mode 100644 index 8f87a3a..0000000 --- a/vendor/phrity/net-uri/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "phrity/net-uri", - "type": "library", - "description": "PSR-7 Uri and PSR-17 UriFactory implementation", - "homepage": "https://phrity.sirn.se/net-uri", - "keywords": ["uri", "uri factory", "PSR-7", "PSR-17"], - "license": "MIT", - "authors": [ - { - "name": "Sören Jensen", - "email": "sirn@sirn.se", - "homepage": "https://phrity.sirn.se" - } - ], - "autoload": { - "psr-4": { - "Phrity\\Net\\": "src/" - } - }, - "require": { - "php": "^7.4 | ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.0 | ^2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0 | ^10.0", - "php-coveralls/php-coveralls": "^2.0", - "squizlabs/php_codesniffer": "^3.0" - } -} diff --git a/vendor/phrity/net-uri/src/Uri.php b/vendor/phrity/net-uri/src/Uri.php deleted file mode 100644 index 4e0ba65..0000000 --- a/vendor/phrity/net-uri/src/Uri.php +++ /dev/null @@ -1,486 +0,0 @@ - Net > Uri - * @see https://www.rfc-editor.org/rfc/rfc3986 - * @see https://www.php-fig.org/psr/psr-7/#35-psrhttpmessageuriinterface - */ - -namespace Phrity\Net; - -use InvalidArgumentException; -use Psr\Http\Message\UriInterface; - -/** - * Net\Uri class. - */ -class Uri implements UriInterface -{ - public const REQUIRE_PORT = 1; // Always include port, explicit or default - public const ABSOLUTE_PATH = 2; // Enforce absolute path - public const NORMALIZE_PATH = 4; // Normalize path - public const IDNA = 8; // IDNA-convert host - - private const RE_MAIN = '!^(?P(?P[^:/?#]+):)?(?P//(?P[^/?#]*))?' - . '(?P[^?#]*)(?P\?(?P[^#]*))?(?P#(?P.*))?$!'; - private const RE_AUTH = '!^(?P(?P[^:/?#]+)(?P:(?P[^:/?#]+))?@)?' - . '(?P[^:/?#]*|\[[^/?#]*\])(?P:(?P[0-9]*))?$!'; - - private static $port_defaults = [ - 'acap' => 674, - 'afp' => 548, - 'dict' => 2628, - 'dns' => 53, - 'ftp' => 21, - 'git' => 9418, - 'gopher' => 70, - 'http' => 80, - 'https' => 443, - 'imap' => 143, - 'ipp' => 631, - 'ipps' => 631, - 'irc' => 194, - 'ircs' => 6697, - 'ldap' => 389, - 'ldaps' => 636, - 'mms' => 1755, - 'msrp' => 2855, - 'mtqp' => 1038, - 'nfs' => 111, - 'nntp' => 119, - 'nntps' => 563, - 'pop' => 110, - 'prospero' => 1525, - 'redis' => 6379, - 'rsync' => 873, - 'rtsp' => 554, - 'rtsps' => 322, - 'rtspu' => 5005, - 'sftp' => 22, - 'smb' => 445, - 'snmp' => 161, - 'ssh' => 22, - 'svn' => 3690, - 'telnet' => 23, - 'ventrilo' => 3784, - 'vnc' => 5900, - 'wais' => 210, - 'ws' => 80, - 'wss' => 443, - ]; - - private $scheme; - private $authority; - private $host; - private $port; - private $user; - private $pass; - private $path; - private $query; - private $fragment; - - /** - * Create new URI instance using a string - * @param string $uri_string URI as string - * @throws \InvalidArgumentException If the given URI cannot be parsed - */ - public function __construct(string $uri_string = '', int $flags = 0) - { - $this->parse($uri_string); - } - - - // ---------- PSR-7 getters --------------------------------------------------------------------------------------- - - /** - * Retrieve the scheme component of the URI. - * @return string The URI scheme - */ - public function getScheme(int $flags = 0): string - { - return $this->getComponent('scheme') ?? ''; - } - - /** - * Retrieve the authority component of the URI. - * @return string The URI authority, in "[user-info@]host[:port]" format - */ - public function getAuthority(int $flags = 0): string - { - $host = $this->formatComponent($this->getHost($flags)); - if ($this->isEmpty($host)) { - return ''; - } - $userinfo = $this->formatComponent($this->getUserInfo(), '', '@'); - $port = $this->formatComponent($this->getPort($flags), ':'); - return "{$userinfo}{$host}{$port}"; - } - - /** - * Retrieve the user information component of the URI. - * @return string The URI user information, in "username[:password]" format - */ - public function getUserInfo(int $flags = 0): string - { - $user = $this->formatComponent($this->getComponent('user')); - $pass = $this->formatComponent($this->getComponent('pass'), ':'); - return $this->isEmpty($user) ? '' : "{$user}{$pass}"; - } - - /** - * Retrieve the host component of the URI. - * @return string The URI host - */ - public function getHost(int $flags = 0): string - { - $host = $this->getComponent('host') ?? ''; - if ($flags & self::IDNA) { - $host = $this->idna($host); - } - return $host; - } - - /** - * Retrieve the port component of the URI. - * @return null|int The URI port - */ - public function getPort(int $flags = 0): ?int - { - $port = $this->getComponent('port'); - $scheme = $this->getComponent('scheme'); - $default = isset(self::$port_defaults[$scheme]) ? self::$port_defaults[$scheme] : null; - if ($flags & self::REQUIRE_PORT) { - return !$this->isEmpty($port) ? $port : $default; - } - return $this->isEmpty($port) || $port === $default ? null : $port; - } - - /** - * Retrieve the path component of the URI. - * @return string The URI path - */ - public function getPath(int $flags = 0): string - { - $path = $this->getComponent('path') ?? ''; - if ($flags & self::NORMALIZE_PATH) { - $path = $this->normalizePath($path); - } - if ($flags & self::ABSOLUTE_PATH && substr($path, 0, 1) !== '/') { - $path = "/{$path}"; - } - return $path; - } - - /** - * Retrieve the query string of the URI. - * @return string The URI query string - */ - public function getQuery(int $flags = 0): string - { - return $this->getComponent('query') ?? ''; - } - - /** - * Retrieve the fragment component of the URI. - * @return string The URI fragment - */ - public function getFragment(int $flags = 0): string - { - return $this->getComponent('fragment') ?? ''; - } - - - // ---------- PSR-7 setters --------------------------------------------------------------------------------------- - - /** - * Return an instance with the specified scheme. - * @param string $scheme The scheme to use with the new instance - * @return static A new instance with the specified scheme - * @throws \InvalidArgumentException for invalid schemes - * @throws \InvalidArgumentException for unsupported schemes - */ - public function withScheme($scheme, int $flags = 0): UriInterface - { - $clone = clone $this; - if ($flags & self::REQUIRE_PORT) { - $clone->setComponent('port', $this->getPort(self::REQUIRE_PORT)); - $default = isset(self::$port_defaults[$scheme]) ? self::$port_defaults[$scheme] : null; - } - $clone->setComponent('scheme', $scheme); - return $clone; - } - - /** - * Return an instance with the specified user information. - * @param string $user The user name to use for authority - * @param null|string $password The password associated with $user - * @return static A new instance with the specified user information - */ - public function withUserInfo($user, $password = null, int $flags = 0): UriInterface - { - $clone = clone $this; - $clone->setComponent('user', $user); - $clone->setComponent('pass', $password); - return $clone; - } - - /** - * Return an instance with the specified host. - * @param string $host The hostname to use with the new instance - * @return static A new instance with the specified host - * @throws \InvalidArgumentException for invalid hostnames - */ - public function withHost($host, int $flags = 0): UriInterface - { - $clone = clone $this; - if ($flags & self::IDNA) { - $host = $this->idna($host); - } - $clone->setComponent('host', $host); - return $clone; - } - - /** - * Return an instance with the specified port. - * @param null|int $port The port to use with the new instance - * @return static A new instance with the specified port - * @throws \InvalidArgumentException for invalid ports - */ - public function withPort($port, int $flags = 0): UriInterface - { - $clone = clone $this; - $clone->setComponent('port', $port); - return $clone; - } - - /** - * Return an instance with the specified path. - * @param string $path The path to use with the new instance - * @return static A new instance with the specified path - * @throws \InvalidArgumentException for invalid paths - */ - public function withPath($path, int $flags = 0): UriInterface - { - $clone = clone $this; - if ($flags & self::NORMALIZE_PATH) { - $path = $this->normalizePath($path); - } - if ($flags & self::ABSOLUTE_PATH && substr($path, 0, 1) !== '/') { - $path = "/{$path}"; - } - $clone->setComponent('path', $path); - return $clone; - } - - /** - * Return an instance with the specified query string. - * @param string $query The query string to use with the new instance - * @return static A new instance with the specified query string - * @throws \InvalidArgumentException for invalid query strings - */ - public function withQuery($query, int $flags = 0): UriInterface - { - $clone = clone $this; - $clone->setComponent('query', $query); - return $clone; - } - - /** - * Return an instance with the specified URI fragment. - * @param string $fragment The fragment to use with the new instance - * @return static A new instance with the specified fragment - */ - public function withFragment($fragment, int $flags = 0): UriInterface - { - $clone = clone $this; - $clone->setComponent('fragment', $fragment); - return $clone; - } - - - // ---------- PSR-7 string ---------------------------------------------------------------------------------------- - - /** - * Return the string representation as a URI reference. - * @return string - */ - public function __toString(): string - { - return $this->toString(); - } - - - // ---------- Extensions ------------------------------------------------------------------------------------------ - - /** - * Return the string representation as a URI reference. - * @return string - */ - public function toString(int $flags = 0): string - { - $scheme = $this->formatComponent($this->getComponent('scheme'), '', ':'); - $authority = $this->authority ? "//{$this->formatComponent($this->getAuthority($flags))}" : ''; - $path_flags = ($this->authority && $this->path ? self::ABSOLUTE_PATH : 0) | $flags; - $path = $this->formatComponent($this->getPath($path_flags)); - $query = $this->formatComponent($this->getComponent('query'), '?'); - $fragment = $this->formatComponent($this->getComponent('fragment'), '#'); - return "{$scheme}{$authority}{$path}{$query}{$fragment}"; - } - - - // ---------- Private helper methods ------------------------------------------------------------------------------ - - private function parse(string $uri_string = ''): void - { - if ($uri_string === '') { - return; - } - preg_match(self::RE_MAIN, $uri_string, $main); - $this->authority = !empty($main['authorityc']); - $this->setComponent('scheme', isset($main['schemec']) ? $main['scheme'] : ''); - $this->setComponent('path', isset($main['path']) ? $main['path'] : ''); - $this->setComponent('query', isset($main['queryc']) ? $main['query'] : ''); - $this->setComponent('fragment', isset($main['fragmentc']) ? $main['fragment'] : ''); - if ($this->authority) { - preg_match(self::RE_AUTH, $main['authority'], $auth); - if (empty($auth) && $main['authority'] !== '') { - throw new InvalidArgumentException("Invalid 'authority'."); - } - if ($this->isEmpty($auth['host']) && !$this->isEmpty($auth['user'])) { - throw new InvalidArgumentException("Invalid 'authority'."); - } - $this->setComponent('user', isset($auth['user']) ? $auth['user'] : ''); - $this->setComponent('pass', isset($auth['passc']) ? $auth['pass'] : ''); - $this->setComponent('host', isset($auth['host']) ? $auth['host'] : ''); - $this->setComponent('port', isset($auth['portc']) ? $auth['port'] : ''); - } - } - - private function encode(string $source, string $keep = ''): string - { - $exclude = "[^%\/:=&!\$'()*+,;@{$keep}]+"; - $exp = "/(%{$exclude})|({$exclude})/"; - return preg_replace_callback($exp, function ($matches) { - if ($e = preg_match('/^(%[0-9a-fA-F]{2})/', $matches[0], $m)) { - return substr($matches[0], 0, 3) . rawurlencode(substr($matches[0], 3)); - } else { - return rawurlencode($matches[0]); - } - }, $source); - } - - private function setComponent(string $component, $value): void - { - $value = $this->parseCompontent($component, $value); - $this->$component = $value; - } - - private function parseCompontent(string $component, $value) - { - if ($this->isEmpty($value)) { - return null; - } - switch ($component) { - case 'scheme': - $this->assertString($component, $value); - $this->assertpattern($component, $value, '/^[a-z][a-z0-9-+.]*$/i'); - return mb_strtolower($value); - case 'host': // IP-literal / IPv4address / reg-name - $this->assertString($component, $value); - $this->authority = $this->authority || !$this->isEmpty($value); - return mb_strtolower($value); - case 'port': - $this->assertInteger($component, $value); - if ($value < 0 || $value > 65535) { - throw new InvalidArgumentException("Invalid port number"); - } - return (int)$value; - case 'path': - $this->assertString($component, $value); - $value = $this->encode($value); - return $value; - case 'user': - case 'pass': - case 'query': - case 'fragment': - $this->assertString($component, $value); - $value = $this->encode($value, '?'); - return $value; - } - } - - private function getComponent(string $component) - { - return isset($this->$component) ? $this->$component : null; - } - - private function formatComponent($value, string $before = '', string $after = ''): string - { - return $this->isEmpty($value) ? '' : "{$before}{$value}{$after}"; - } - - private function isEmpty($value): bool - { - return is_null($value) || $value === ''; - } - - private function assertString(string $component, $value): void - { - if (!is_string($value)) { - throw new InvalidArgumentException("Invalid '{$component}': Should be a string"); - } - } - - private function assertInteger(string $component, $value): void - { - if (!is_numeric($value) || intval($value) != $value) { - throw new InvalidArgumentException("Invalid '{$component}': Should be an integer"); - } - } - - private function assertPattern(string $component, string $value, string $pattern): void - { - if (preg_match($pattern, $value) == 0) { - throw new InvalidArgumentException("Invalid '{$component}': Should match {$pattern}"); - } - } - - private function normalizePath(string $path): string - { - $result = []; - preg_match_all('!([^/]*/|[^/]*$)!', $path, $items); - foreach ($items[0] as $item) { - switch ($item) { - case '': - case './': - case '.': - break; // just skip - case '/': - if (empty($result)) { - array_push($result, $item); // add - } - break; - case '..': - case '../': - if (empty($result) || end($result) == '../') { - array_push($result, $item); // add - } else { - array_pop($result); // remove previous - } - break; - default: - array_push($result, $item); // add - } - } - return implode('', $result); - } - - private function idna(string $value): string - { - if ($value === '' || !is_callable('idn_to_ascii')) { - return $value; // Can't convert, but don't cause exception - } - return idn_to_ascii($value, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); - } -} diff --git a/vendor/phrity/net-uri/src/UriFactory.php b/vendor/phrity/net-uri/src/UriFactory.php deleted file mode 100644 index f100dd0..0000000 --- a/vendor/phrity/net-uri/src/UriFactory.php +++ /dev/null @@ -1,31 +0,0 @@ - Net > Uri - * @see https://www.rfc-editor.org/rfc/rfc3986 - * @see https://www.php-fig.org/psr/psr-17/#26-urifactoryinterface - */ - -namespace Phrity\Net; - -use Psr\Http\Message\{ - UriFactoryInterface, - UriInterface -}; - -/** - * Net\UriFactory class. - */ -class UriFactory implements UriFactoryInterface -{ - /** - * Create a new URI. - * @param string $uri The URI to parse. - * @throws \InvalidArgumentException If the given URI cannot be parsed - */ - public function createUri(string $uri = ''): UriInterface - { - return new Uri($uri); - } -} diff --git a/vendor/phrity/util-errorhandler/.github/workflows/acceptance.yml b/vendor/phrity/util-errorhandler/.github/workflows/acceptance.yml deleted file mode 100644 index 3eff1c1..0000000 --- a/vendor/phrity/util-errorhandler/.github/workflows/acceptance.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Acceptance - -on: [push, pull_request] - -jobs: - - test: - strategy: - matrix: - php-versions: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4"] - runs-on: ubuntu-latest - name: Unit test - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - coverage: none - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies - run: composer install --prefer-dist - - name: Test - run: vendor/bin/phpunit - - cs-check: - runs-on: ubuntu-latest - name: Code standard - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.3" - coverage: none - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies - run: composer install --prefer-dist - - name: Code standard - run: vendor/bin/phpcs --standard=PSR1,PSR12 --encoding=UTF-8 --report=full --colors src tests - - coverage: - runs-on: ubuntu-latest - name: Code coverage - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.3" - coverage: xdebug - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies - run: composer install --prefer-dist - - name: Code coverage build - run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover build/logs/clover.xml - - name: Code coverage upload - env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: vendor/bin/php-coveralls -v diff --git a/vendor/phrity/util-errorhandler/.gitignore b/vendor/phrity/util-errorhandler/.gitignore deleted file mode 100644 index 379ab4b..0000000 --- a/vendor/phrity/util-errorhandler/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store -.phpunit.result.cache -build/ -composer.lock -composer.phar -vendor/ \ No newline at end of file diff --git a/vendor/phrity/util-errorhandler/Makefile b/vendor/phrity/util-errorhandler/Makefile deleted file mode 100644 index b97dcbd..0000000 --- a/vendor/phrity/util-errorhandler/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Default -all: deps-install - - -# DEPENDENCY MANAGEMENT - -# Updates dependencies according to lock file -deps-install: composer.phar - ./composer.phar --no-interaction install - -# Updates dependencies according to json file -deps-update: composer.phar - ./composer.phar self-update - ./composer.phar --no-interaction update - - -# TESTS AND REPORTS - -# Code standard check -cs-check: composer.lock - ./vendor/bin/phpcs --standard=PSR1,PSR12 --encoding=UTF-8 --report=full --colors src tests - -# Run tests -test: composer.lock - ./vendor/bin/phpunit - -# Run tests with clover coverage report -coverage: composer.lock - XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml - ./vendor/bin/php-coveralls -v - - -# INITIAL INSTALL - -# Ensures composer is installed -composer.phar: - curl -sS https://getcomposer.org/installer | php - -# Ensures composer is installed and dependencies loaded -composer.lock: composer.phar - ./composer.phar --no-interaction install \ No newline at end of file diff --git a/vendor/phrity/util-errorhandler/README.md b/vendor/phrity/util-errorhandler/README.md deleted file mode 100644 index a634491..0000000 --- a/vendor/phrity/util-errorhandler/README.md +++ /dev/null @@ -1,147 +0,0 @@ -[![Build Status](https://github.com/sirn-se/phrity-util-errorhandler/actions/workflows/acceptance.yml/badge.svg)](https://github.com/sirn-se/phrity-util-errorhandler/actions) -[![Coverage Status](https://coveralls.io/repos/github/sirn-se/phrity-util-errorhandler/badge.svg?branch=main)](https://coveralls.io/github/sirn-se/phrity-util-errorhandler?branch=main) - -# Error Handler utility - -The PHP [error handling](https://www.php.net/manual/en/book.errorfunc.php) can be somewhat of a headache. -Typically an application uses a system level [error handler](https://www.php.net/manual/en/function.set-error-handler.php) and/or suppressing errors using the `@` prefix. -But those cases when your code need to act on triggered errors are more tricky. - -This library provides two convenience methods to handle errors on code blocks, either by throwing exceptions or running callback code when an error occurs. - -Current version supports PHP `^7.2|^8.0`. - -## Installation - -Install with [Composer](https://getcomposer.org/); -``` -composer require phrity/util-errorhandler -``` - -## The Error Handler - -The class provides two main methods; `with()` and `withAll()`. -The difference is that `with()` will act immediately on an error and abort further code execution, while `withAll()` will attempt to execute the entire code block before acting on errors that occurred. - -### Throwing ErrorException - -```php -use Phrity\Util\ErrorHandler; - -$handler = new ErrorHandler(); -$result = $handler->with(function () { - // Code to execute - return $success_result; -}); -$result = $handler->withAll(function () { - // Code to execute - return $success_result; -}); -``` -The examples above will run the callback code, but if an error occurs it will throw an [ErrorException](https://www.php.net/manual/en/class.errorexception.php). -Error message and severity will be that of the triggering error. -* `with()` will throw immediately when occured -* `withAll()` will throw when code is complete; if more than one error occurred, the first will be thrown - -### Throwing specified Throwable - -```php -use Phrity\Util\ErrorHandler; - -$handler = new ErrorHandler(); -$result = $handler->with(function () { - // Code to execute - return $success_result; -}, new RuntimeException('A specified error')); -$result = $handler->withAll(function () { - // Code to execute - return $success_result; -}, new RuntimeException('A specified error')); -``` -The examples above will run the callback code, but if an error occurs it will throw provided Throwable. -The thrown Throwable will have an [ErrorException](https://www.php.net/manual/en/class.errorexception.php) attached as `$previous`. -* `with()` will throw immediately when occured -* `withAll()` will throw when code is complete; if more than one error occurred, the first will be thrown - -### Using callback - -```php -use Phrity\Util\ErrorHandler; - -$handler = new ErrorHandler(); -$result = $handler->with(function () { - // Code to execute - return $success_result; -}, function (ErrorException $error) { - // Code to handle error - return $error_result; -}); -$result = $handler->withAll(function () { - // Code to execute - return $success_result; -}, function (array $errors, $success_result) { - // Code to handle errors - return $error_result; -}); -``` -The examples above will run the callback code, but if an error occurs it will call the error callback as well. -* `with()` will run the error callback immediately when error occured; error callback expects an ErrorException instance -* `withAll()` will run the error callback when code is complete; error callback expects an array of ErrorException and the returned result of code callback - -### Filtering error types - -Both `with()` and `withAll()` accepts error level(s) as last parameter. -```php -use Phrity\Util\ErrorHandler; - -$handler = new ErrorHandler(); -$result = $handler->with(function () { - // Code to execute - return $success_result; -}, null, E_USER_ERROR); -$result = $handler->withAll(function () { - // Code to execute - return $success_result; -}, null, E_USER_ERROR & E_USER_WARNING); -``` -Any value or combination of values accepted by [set_error_handler](https://www.php.net/manual/en/function.set-error-handler.php) is usable. -Default is `E_ALL`. [List of constants](https://www.php.net/manual/en/errorfunc.constants.php). - -### The global error handler - -The class also has global `set()` and `restore()` methods. - -```php -use Phrity\Util\ErrorHandler; - -$handler = new ErrorHandler(); -$handler->set(); // Throws ErrorException on error -$handler->set(new RuntimeException('A specified error')); // Throws provided Throwable on error -$handler->set(function (ErrorException $error) { - // Code to handle errors - return $error_result; -}); // Runs callback on error -$handler->restore(); // Restores error handler -``` - -### Class synopsis - -```php -Phrity\Util\ErrorHandler { - - /* Methods */ - public __construct() - - public with(callable $callback, mixed $handling = null, int $levels = E_ALL) : mixed - public withAll(callable $callback, mixed $handling = null, int $levels = E_ALL) : mixed - public set($handling = null, int $levels = E_ALL) : mixed - public restore() : bool -} -``` - -## Versions - -| Version | PHP | | -| --- | --- | --- | -| `1.1` | `^7.4\|^8.0` | Some improvements | -| `1.0` | `^7.2\|^8.0` | Initial version | diff --git a/vendor/phrity/util-errorhandler/composer.json b/vendor/phrity/util-errorhandler/composer.json deleted file mode 100644 index 22862b6..0000000 --- a/vendor/phrity/util-errorhandler/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "phrity/util-errorhandler", - "type": "library", - "description": "Inline error handler; catch and resolve errors for code block.", - "homepage": "https://phrity.sirn.se/util-errorhandler", - "keywords": ["error", "warning"], - "license": "MIT", - "authors": [ - { - "name": "Sören Jensen", - "email": "sirn@sirn.se", - "homepage": "https://phrity.sirn.se" - } - ], - "autoload": { - "psr-4": { - "Phrity\\Util\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Phrity\\Util\\Tests\\": "tests/" - } - }, - "require": { - "php": "^7.4 | ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0", - "php-coveralls/php-coveralls": "^2.0", - "squizlabs/php_codesniffer": "^3.5" - } -} diff --git a/vendor/phrity/util-errorhandler/phpunit.xml.dist b/vendor/phrity/util-errorhandler/phpunit.xml.dist deleted file mode 100644 index eebfbe3..0000000 --- a/vendor/phrity/util-errorhandler/phpunit.xml.dist +++ /dev/null @@ -1,13 +0,0 @@ - - - - - ./tests/ - - - - - ./src/ - - - diff --git a/vendor/phrity/util-errorhandler/src/ErrorHandler.php b/vendor/phrity/util-errorhandler/src/ErrorHandler.php deleted file mode 100644 index fa81780..0000000 --- a/vendor/phrity/util-errorhandler/src/ErrorHandler.php +++ /dev/null @@ -1,121 +0,0 @@ - Util > ErrorHandler - */ - -namespace Phrity\Util; - -use ErrorException; -use Throwable; - -/** - * ErrorHandler utility class. - * Allows catching and resolving errors inline. - */ -class ErrorHandler -{ - /* ----------------- Public methods ---------------------------------------------- */ - - /** - * Set error handler to run until removed. - * @param mixed $handling - * - If null, handler will throw ErrorException - * - If Throwable $t, throw $t with ErrorException attached as previous - * - If callable, will invoke callback with ErrorException as argument - * @param int $levels Error levels to catch, all errors by default - * @return mixed Previously registered error handler, if any - */ - public function set($handling = null, int $levels = E_ALL) - { - return set_error_handler($this->getHandler($handling), $levels); - } - - /** - * Remove error handler. - * @return bool True if removed - */ - public function restore(): bool - { - return restore_error_handler(); - } - - /** - * Run code with error handling, breaks on first encountered error. - * @param callable $callback The code to run - * @param mixed $handling - * - If null, handler will throw ErrorException - * - If Throwable $t, throw $t with ErrorException attached as previous - * - If callable, will invoke callback with ErrorException as argument - * @param int $levels Error levels to catch, all errors by default - * @return mixed Return what $callback returns, or what $handling retuns on error - */ - public function with(callable $callback, $handling = null, int $levels = E_ALL) - { - $error = null; - $result = null; - try { - $this->set(null, $levels); - $result = $callback(); - } catch (ErrorException $e) { - $error = $this->handle($handling, $e); - } finally { - $this->restore(); - } - return $error ?? $result; - } - - /** - * Run code with error handling, comletes code before handling errors - * @param callable $callback The code to run - * @param mixed $handling - * - If null, handler will throw ErrorException - * - If Throwable $t, throw $t with ErrorException attached as previous - * - If callable, will invoke callback with ErrorException as argument - * @param int $levels Error levels to catch, all errors by default - * @return mixed Return what $callback returns, or what $handling retuns on error - */ - public function withAll(callable $callback, $handling = null, int $levels = E_ALL) - { - $errors = []; - $this->set(function (ErrorException $e) use (&$errors) { - $errors[] = $e; - }, $levels); - $result = $callback(); - $this->restore(); - $error = empty($errors) ? null : $this->handle($handling, $errors, $result); - return $error ?? $result; - } - - - /* ----------------- Private helpers --------------------------------------------- */ - - // Get handler function - private function getHandler($handling) - { - return function ($severity, $message, $file, $line) use ($handling) { - $error = new ErrorException($message, 0, $severity, $file, $line); - $this->handle($handling, $error); - }; - } - - // Handle error according to $handlig type - private function handle($handling, $error, $result = null) - { - if (is_callable($handling)) { - return $handling($error, $result); - } - if (is_array($error)) { - $error = array_shift($error); - } - if ($handling instanceof Throwable) { - try { - throw $error; - } finally { - throw $handling; - } - } - throw $error; - } -} diff --git a/vendor/phrity/util-errorhandler/tests/ErrorHandlerTest.php b/vendor/phrity/util-errorhandler/tests/ErrorHandlerTest.php deleted file mode 100644 index 31e0f49..0000000 --- a/vendor/phrity/util-errorhandler/tests/ErrorHandlerTest.php +++ /dev/null @@ -1,303 +0,0 @@ - Util > ErrorHandler - */ - -declare(strict_types=1); - -namespace Phrity\Util; - -use ErrorException; -use RuntimeException; -use Phrity\Util\ErrorHandler; -use PHPUnit\Framework\TestCase; - -/** - * ErrorHandler test class. - */ -class ErrorHandlerTest extends TestCase -{ - /** - * Set up for all tests - */ - public function setUp(): void - { - error_reporting(-1); - } - - public function testSetNull(): void - { - $handler = new ErrorHandler(); - $handler->set(); - - // Verify exception - try { - trigger_error('An error'); - } catch (ErrorException $e) { - $this->assertEquals('An error', $e->getMessage()); - $this->assertEquals(0, $e->getCode()); - $this->assertEquals(E_USER_NOTICE, $e->getSeverity()); - $this->assertNull($e->getPrevious()); - } - - // Restore handler - $this->assertTrue($handler->restore()); - } - - public function testSetThrowable(): void - { - $handler = new ErrorHandler(); - $handler->set(new RuntimeException('A provided exception', 23)); - - // Verify exception - try { - trigger_error('An error'); - } catch (RuntimeException $e) { - $this->assertEquals('A provided exception', $e->getMessage()); - $this->assertEquals(23, $e->getCode()); - $this->assertNotNull($e->getPrevious()); - $prev = $e->getPrevious(); - $this->assertEquals('An error', $prev->getMessage()); - $this->assertEquals(0, $prev->getCode()); - $this->assertEquals(E_USER_NOTICE, $prev->getSeverity()); - $this->assertNull($prev->getPrevious()); - } - - // Restore handler - $this->assertTrue($handler->restore()); - } - - public function testSetCallback(): void - { - $handler = new ErrorHandler(); - $result = null; - $handler->set(function ($error) use (&$result) { - $result = [ - 'message' => $error->getMessage(), - 'code' => $error->getCode(), - 'severity' => $error->getSeverity(), - ]; - }); - - // Verify exception - trigger_error('An error'); - $this->assertEquals([ - 'message' => 'An error', - 'code' => 0, - 'severity' => E_USER_NOTICE, - ], $result); - - // Restore handler - $this->assertTrue($handler->restore()); - } - - public function testWithNull(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No exception - $result = $handler->with(function () { - return 'Code success'; - }); - $this->assertEquals('Code success', $result); - - // Verify exception - try { - $result = $handler->with(function () use (&$check) { - trigger_error('An error'); - $check = true; - return 'Code success'; - }); - } catch (ErrorException $e) { - $this->assertEquals('An error', $e->getMessage()); - $this->assertEquals(0, $e->getCode()); - $this->assertEquals(E_USER_NOTICE, $e->getSeverity()); - $this->assertNull($e->getPrevious()); - } - $this->assertFalse($check); - - // Verify that exception is thrown - $this->expectException('ErrorException'); - $result = $handler->with(function () { - trigger_error('An error'); - return 'Code success'; - }); - } - - public function testWithThrowable(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No exception - $result = $handler->with(function () { - return 'Code success'; - }); - $this->assertEquals('Code success', $result); - - // Verify exception - try { - $result = $handler->with(function () use (&$check) { - trigger_error('An error'); - $check = true; - return 'Code success'; - }, new RuntimeException('A provided exception', 23)); - } catch (RuntimeException $e) { - $this->assertEquals('A provided exception', $e->getMessage()); - $this->assertEquals(23, $e->getCode()); - $this->assertNotNull($e->getPrevious()); - $prev = $e->getPrevious(); - $this->assertEquals('An error', $prev->getMessage()); - $this->assertEquals(0, $prev->getCode()); - $this->assertEquals(E_USER_NOTICE, $prev->getSeverity()); - $this->assertNull($prev->getPrevious()); - } - $this->assertFalse($check); - - // Verify that exception is thrown - $this->expectException('RuntimeException'); - $result = $handler->with(function () { - trigger_error('An error'); - return 'Code success'; - }, new RuntimeException('A provided exception', 23)); - } - - public function testWithCallback(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No error invoked - $result = $handler->with(function () { - return 'Code success'; - }, function ($error) { - return $error; - }); - $this->assertEquals('Code success', $result); - - // An error is invoked - $result = $handler->with(function () use (&$check) { - trigger_error('An error'); - $check = true; - return 'Code success'; - }, function ($error) { - return $error; - }); - $this->assertFalse($check); - - $this->assertEquals('An error', $result->getMessage()); - $this->assertEquals(0, $result->getCode()); - $this->assertEquals(E_USER_NOTICE, $result->getSeverity()); - $this->assertNull($result->getPrevious()); - } - - public function testWithAllNull(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No error invoked - $result = $handler->withAll(function () { - return 'Code success'; - }); - $this->assertEquals('Code success', $result); - - // Verify exception - try { - $result = $handler->withAll(function () use (&$check) { - trigger_error('An error'); - $check = true; - return 'Code success'; - }); - } catch (ErrorException $e) { - $this->assertEquals('An error', $e->getMessage()); - $this->assertEquals(0, $e->getCode()); - $this->assertEquals(E_USER_NOTICE, $e->getSeverity()); - $this->assertNull($e->getPrevious()); - } - $this->assertTrue($check); - - // Verify that exception is thrown - $this->expectException('ErrorException'); - $result = $handler->withAll(function () { - trigger_error('An error'); - return 'Code success'; - }); - } - - public function testWithAllThrowable(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No exception - $result = $handler->withAll(function () { - return 'Code success'; - }); - $this->assertEquals('Code success', $result); - - // Verify exception - try { - $result = $handler->withAll(function () use (&$check) { - trigger_error('An error'); - $check = true; - return 'Code success'; - }, new RuntimeException('A provided exception', 23)); - } catch (RuntimeException $e) { - $this->assertEquals('A provided exception', $e->getMessage()); - $this->assertEquals(23, $e->getCode()); - $this->assertNotNull($e->getPrevious()); - $prev = $e->getPrevious(); - $this->assertEquals('An error', $prev->getMessage()); - $this->assertEquals(0, $prev->getCode()); - $this->assertEquals(E_USER_NOTICE, $prev->getSeverity()); - $this->assertNull($prev->getPrevious()); - } - $this->assertTrue($check); - - // Verify that exception is thrown - $this->expectException('RuntimeException'); - $result = $handler->withAll(function () { - trigger_error('An error'); - return 'Code success'; - }, new RuntimeException('A provided exception', 23)); - } - - public function testWithAllCallback(): void - { - $handler = new ErrorHandler(); - $check = false; - - // No error invoked - $result = $handler->withAll(function () { - return 'Code success'; - }, function ($error, $result) { - return $error; - }); - $this->assertEquals('Code success', $result); - - // An error is invoked - $result = $handler->withAll(function () use (&$check) { - trigger_error('An error'); - trigger_error('Another error', E_USER_WARNING); - $check = true; - return 'Code success'; - }, function ($errors, $result) { - return ['errors' => $errors, 'result' => $result]; - }); - $this->assertTrue($check); - - $this->assertEquals('Code success', $result['result']); - $this->assertEquals('An error', $result['errors'][0]->getMessage()); - $this->assertEquals(0, $result['errors'][0]->getCode()); - $this->assertEquals(E_USER_NOTICE, $result['errors'][0]->getSeverity()); - $this->assertNull($result['errors'][0]->getPrevious()); - $this->assertEquals('Another error', $result['errors'][1]->getMessage()); - $this->assertEquals(0, $result['errors'][1]->getCode()); - $this->assertEquals(E_USER_WARNING, $result['errors'][1]->getSeverity()); - $this->assertNull($result['errors'][1]->getPrevious()); - } -} diff --git a/vendor/psr/http-factory/LICENSE b/vendor/psr/http-factory/LICENSE deleted file mode 100644 index 3f1559b..0000000 --- a/vendor/psr/http-factory/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 PHP-FIG - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/psr/http-factory/README.md b/vendor/psr/http-factory/README.md deleted file mode 100644 index bf8913b..0000000 --- a/vendor/psr/http-factory/README.md +++ /dev/null @@ -1,12 +0,0 @@ -HTTP Factories -============== - -This repository holds all interfaces related to [PSR-17 (HTTP Factories)][psr-url]. - -Note that this is not a HTTP Factory implementation of its own. It is merely interfaces that describe the components of a HTTP Factory. - -The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. - -[psr-url]: https://www.php-fig.org/psr/psr-17/ -[package-url]: https://packagist.org/packages/psr/http-factory -[implementation-url]: https://packagist.org/providers/psr/http-factory-implementation diff --git a/vendor/psr/http-factory/composer.json b/vendor/psr/http-factory/composer.json deleted file mode 100644 index e9a3967..0000000 --- a/vendor/psr/http-factory/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "psr/http-factory", - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "psr", - "psr-7", - "psr-17", - "http", - "factory", - "message", - "request", - "response" - ], - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "support": { - "source": "https://github.com/php-fig/http-factory" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/vendor/psr/http-factory/src/RequestFactoryInterface.php b/vendor/psr/http-factory/src/RequestFactoryInterface.php deleted file mode 100644 index cb39a08..0000000 --- a/vendor/psr/http-factory/src/RequestFactoryInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. -> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. - diff --git a/vendor/psr/http-message/docs/PSR7-Usage.md b/vendor/psr/http-message/docs/PSR7-Usage.md deleted file mode 100644 index b6d048a..0000000 --- a/vendor/psr/http-message/docs/PSR7-Usage.md +++ /dev/null @@ -1,159 +0,0 @@ -### PSR-7 Usage - -All PSR-7 applications comply with these interfaces -They were created to establish a standard between middleware implementations. - -> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. -> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. - - -The following examples will illustrate how basic operations are done in PSR-7. - -##### Examples - - -For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc) -All PSR-7 implementations should have the same behaviour. - -The following will be assumed: -`$request` is an object of `Psr\Http\Message\RequestInterface` and - -`$response` is an object implementing `Psr\Http\Message\RequestInterface` - - -### Working with HTTP Headers - -#### Adding headers to response: - -```php -$response->withHeader('My-Custom-Header', 'My Custom Message'); -``` - -#### Appending values to headers - -```php -$response->withAddedHeader('My-Custom-Header', 'The second message'); -``` - -#### Checking if header exists: - -```php -$request->hasHeader('My-Custom-Header'); // will return false -$response->hasHeader('My-Custom-Header'); // will return true -``` - -> Note: My-Custom-Header was only added in the Response - -#### Getting comma-separated values from a header (also applies to request) - -```php -// getting value from request headers -$request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8" -// getting value from response headers -$response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message" -``` - -#### Getting array of value from a header (also applies to request) -```php -// getting value from request headers -$request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"] -// getting value from response headers -$response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"] -``` - -#### Removing headers from HTTP Messages -```php -// removing a header from Request, removing deprecated "Content-MD5" header -$request->withoutHeader('Content-MD5'); - -// removing a header from Response -// effect: the browser won't know the size of the stream -// the browser will download the stream till it ends -$response->withoutHeader('Content-Length'); -``` - -### Working with HTTP Message Body - -When working with the PSR-7 there are two methods of implementation: -#### 1. Getting the body separately - -> This method makes the body handling easier to understand and is useful when repeatedly calling body methods. (You only call `getBody()` once). Using this method mistakes like `$response->write()` are also prevented. - -```php -$body = $response->getBody(); -// operations on body, eg. read, write, seek -// ... -// replacing the old body -$response->withBody($body); -// this last statement is optional as we working with objects -// in this case the "new" body is same with the "old" one -// the $body variable has the same value as the one in $request, only the reference is passed -``` - -#### 2. Working directly on response - -> This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required - -```php -$response->getBody()->write('hello'); -``` - -### Getting the body contents - -The following snippet gets the contents of a stream contents. -> Note: Streams must be rewinded, if content was written into streams, it will be ignored when calling `getContents()` because the stream pointer is set to the last character, which is `\0` - meaning end of stream. -```php -$body = $response->getBody(); -$body->rewind(); // or $body->seek(0); -$bodyText = $body->getContents(); -``` -> Note: If `$body->seek(1)` is called before `$body->getContents()`, the first character will be ommited as the starting pointer is set to `1`, not `0`. This is why using `$body->rewind()` is recommended. - -### Append to body - -```php -$response->getBody()->write('Hello'); // writing directly -$body = $request->getBody(); // which is a `StreamInterface` -$body->write('xxxxx'); -``` - -### Prepend to body -Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended. -The following example will explain the behaviour of streams. - -```php -// assuming our response is initially empty -$body = $repsonse->getBody(); -// writing the string "abcd" -$body->write('abcd'); - -// seeking to start of stream -$body->seek(0); -// writing 'ef' -$body->write('ef'); // at this point the stream contains "efcd" -``` - -#### Prepending by rewriting separately - -```php -// assuming our response body stream only contains: "abcd" -$body = $response->getBody(); -$body->rewind(); -$contents = $body->getContents(); // abcd -// seeking the stream to beginning -$body->rewind(); -$body->write('ef'); // stream contains "efcd" -$body->write($contents); // stream contains "efabcd" -``` - -> Note: `getContents()` seeks the stream while reading it, therefore if the second `rewind()` method call was not present the stream would have resulted in `abcdefabcd` because the `write()` method appends to stream if not preceeded by `rewind()` or `seek(0)`. - -#### Prepending by using contents as a string -```php -$body = $response->getBody(); -$body->rewind(); -$contents = $body->getContents(); // efabcd -$contents = 'ef'.$contents; -$body->rewind(); -$body->write($contents); -``` diff --git a/vendor/psr/http-message/src/MessageInterface.php b/vendor/psr/http-message/src/MessageInterface.php deleted file mode 100644 index 8cdb4ed..0000000 --- a/vendor/psr/http-message/src/MessageInterface.php +++ /dev/null @@ -1,189 +0,0 @@ -getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * // Emit headers iteratively: - * foreach ($message->getHeaders() as $name => $values) { - * foreach ($values as $value) { - * header(sprintf('%s: %s', $name, $value), false); - * } - * } - * - * While header names are not case-sensitive, getHeaders() will preserve the - * exact case in which headers were originally specified. - * - * @return string[][] Returns an associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function getHeaders(); - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Case-insensitive header field name. - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader(string $name); - - /** - * Retrieves a message header value by the given case-insensitive name. - * - * This method returns an array of all the header values of the given - * case-insensitive header name. - * - * If the header does not appear in the message, this method MUST return an - * empty array. - * - * @param string $name Case-insensitive header field name. - * @return string[] An array of string values as provided for the given - * header. If the header does not appear in the message, this method MUST - * return an empty array. - */ - public function getHeader(string $name); - - /** - * Retrieves a comma-separated string of the values for a single header. - * - * This method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. - * - * NOTE: Not all header values may be appropriately represented using - * comma concatenation. For such headers, use getHeader() instead - * and supply your own delimiter when concatenating. - * - * If the header does not appear in the message, this method MUST return - * an empty string. - * - * @param string $name Case-insensitive header field name. - * @return string A string of values as provided for the given header - * concatenated together using a comma. If the header does not appear in - * the message, this method MUST return an empty string. - */ - public function getHeaderLine(string $name); - - /** - * Return an instance with the provided value replacing the specified header. - * - * While header names are case-insensitive, the casing of the header will - * be preserved by this function, and returned from getHeaders(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new and/or updated header and value. - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader(string $name, $value); - - /** - * Return an instance with the specified header appended with the given value. - * - * Existing values for the specified header will be maintained. The new - * value(s) will be appended to the existing list. If the header did not - * exist previously, it will be added. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new header and/or value. - * - * @param string $name Case-insensitive header field name to add. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withAddedHeader(string $name, $value); - - /** - * Return an instance without the specified header. - * - * Header resolution MUST be done without case-sensitivity. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the named header. - * - * @param string $name Case-insensitive header field name to remove. - * @return static - */ - public function withoutHeader(string $name); - - /** - * Gets the body of the message. - * - * @return StreamInterface Returns the body as a stream. - */ - public function getBody(); - - /** - * Return an instance with the specified message body. - * - * The body MUST be a StreamInterface object. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * new body stream. - * - * @param StreamInterface $body Body. - * @return static - * @throws \InvalidArgumentException When the body is not valid. - */ - public function withBody(StreamInterface $body); -} diff --git a/vendor/psr/http-message/src/RequestInterface.php b/vendor/psr/http-message/src/RequestInterface.php deleted file mode 100644 index 38066df..0000000 --- a/vendor/psr/http-message/src/RequestInterface.php +++ /dev/null @@ -1,131 +0,0 @@ -getQuery()` - * or from the `QUERY_STRING` server param. - * - * @return array - */ - public function getQueryParams(); - - /** - * Return an instance with the specified query string arguments. - * - * These values SHOULD remain immutable over the course of the incoming - * request. They MAY be injected during instantiation, such as from PHP's - * $_GET superglobal, or MAY be derived from some other value such as the - * URI. In cases where the arguments are parsed from the URI, the data - * MUST be compatible with what PHP's parse_str() would return for - * purposes of how duplicate query parameters are handled, and how nested - * sets are handled. - * - * Setting query string arguments MUST NOT change the URI stored by the - * request, nor the values in the server params. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated query string arguments. - * - * @param array $query Array of query string arguments, typically from - * $_GET. - * @return static - */ - public function withQueryParams(array $query); - - /** - * Retrieve normalized file upload data. - * - * This method returns upload metadata in a normalized tree, with each leaf - * an instance of Psr\Http\Message\UploadedFileInterface. - * - * These values MAY be prepared from $_FILES or the message body during - * instantiation, or MAY be injected via withUploadedFiles(). - * - * @return array An array tree of UploadedFileInterface instances; an empty - * array MUST be returned if no data is present. - */ - public function getUploadedFiles(); - - /** - * Create a new instance with the specified uploaded files. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param array $uploadedFiles An array tree of UploadedFileInterface instances. - * @return static - * @throws \InvalidArgumentException if an invalid structure is provided. - */ - public function withUploadedFiles(array $uploadedFiles); - - /** - * Retrieve any parameters provided in the request body. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, this method MUST - * return the contents of $_POST. - * - * Otherwise, this method may return any results of deserializing - * the request body content; as parsing returns structured content, the - * potential types MUST be arrays or objects only. A null value indicates - * the absence of body content. - * - * @return null|array|object The deserialized body parameters, if any. - * These will typically be an array or object. - */ - public function getParsedBody(); - - /** - * Return an instance with the specified body parameters. - * - * These MAY be injected during instantiation. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, use this method - * ONLY to inject the contents of $_POST. - * - * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of - * deserializing the request body content. Deserialization/parsing returns - * structured data, and, as such, this method ONLY accepts arrays or objects, - * or a null value if nothing was available to parse. - * - * As an example, if content negotiation determines that the request data - * is a JSON payload, this method could be used to create a request - * instance with the deserialized parameters. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param null|array|object $data The deserialized body data. This will - * typically be in an array or object. - * @return static - * @throws \InvalidArgumentException if an unsupported argument type is - * provided. - */ - public function withParsedBody($data); - - /** - * Retrieve attributes derived from the request. - * - * The request "attributes" may be used to allow injection of any - * parameters derived from the request: e.g., the results of path - * match operations; the results of decrypting cookies; the results of - * deserializing non-form-encoded message bodies; etc. Attributes - * will be application and request specific, and CAN be mutable. - * - * @return array Attributes derived from the request. - */ - public function getAttributes(); - - /** - * Retrieve a single derived request attribute. - * - * Retrieves a single derived request attribute as described in - * getAttributes(). If the attribute has not been previously set, returns - * the default value as provided. - * - * This method obviates the need for a hasAttribute() method, as it allows - * specifying a default value to return if the attribute is not found. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $default Default value to return if the attribute does not exist. - * @return mixed - */ - public function getAttribute(string $name, $default = null); - - /** - * Return an instance with the specified derived request attribute. - * - * This method allows setting a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $value The value of the attribute. - * @return static - */ - public function withAttribute(string $name, $value); - - /** - * Return an instance that removes the specified derived request attribute. - * - * This method allows removing a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @return static - */ - public function withoutAttribute(string $name); -} diff --git a/vendor/psr/http-message/src/StreamInterface.php b/vendor/psr/http-message/src/StreamInterface.php deleted file mode 100644 index 5924663..0000000 --- a/vendor/psr/http-message/src/StreamInterface.php +++ /dev/null @@ -1,160 +0,0 @@ - - * [user-info@]host[:port] - * - * - * If the port component is not set or is the standard port for the current - * scheme, it SHOULD NOT be included. - * - * @see https://tools.ietf.org/html/rfc3986#section-3.2 - * @return string The URI authority, in "[user-info@]host[:port]" format. - */ - public function getAuthority(); - - /** - * Retrieve the user information component of the URI. - * - * If no user information is present, this method MUST return an empty - * string. - * - * If a user is present in the URI, this will return that value; - * additionally, if the password is also present, it will be appended to the - * user value, with a colon (":") separating the values. - * - * The trailing "@" character is not part of the user information and MUST - * NOT be added. - * - * @return string The URI user information, in "username[:password]" format. - */ - public function getUserInfo(); - - /** - * Retrieve the host component of the URI. - * - * If no host is present, this method MUST return an empty string. - * - * The value returned MUST be normalized to lowercase, per RFC 3986 - * Section 3.2.2. - * - * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 - * @return string The URI host. - */ - public function getHost(); - - /** - * Retrieve the port component of the URI. - * - * If a port is present, and it is non-standard for the current scheme, - * this method MUST return it as an integer. If the port is the standard port - * used with the current scheme, this method SHOULD return null. - * - * If no port is present, and no scheme is present, this method MUST return - * a null value. - * - * If no port is present, but a scheme is present, this method MAY return - * the standard port for that scheme, but SHOULD return null. - * - * @return null|int The URI port. - */ - public function getPort(); - - /** - * Retrieve the path component of the URI. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * Normally, the empty path "" and absolute path "/" are considered equal as - * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically - * do this normalization because in contexts with a trimmed base path, e.g. - * the front controller, this difference becomes significant. It's the task - * of the user to handle both "" and "/". - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.3. - * - * As an example, if the value should include a slash ("/") not intended as - * delimiter between path segments, that value MUST be passed in encoded - * form (e.g., "%2F") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.3 - * @return string The URI path. - */ - public function getPath(); - - /** - * Retrieve the query string of the URI. - * - * If no query string is present, this method MUST return an empty string. - * - * The leading "?" character is not part of the query and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.4. - * - * As an example, if a value in a key/value pair of the query string should - * include an ampersand ("&") not intended as a delimiter between values, - * that value MUST be passed in encoded form (e.g., "%26") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.4 - * @return string The URI query string. - */ - public function getQuery(); - - /** - * Retrieve the fragment component of the URI. - * - * If no fragment is present, this method MUST return an empty string. - * - * The leading "#" character is not part of the fragment and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.5. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.5 - * @return string The URI fragment. - */ - public function getFragment(); - - /** - * Return an instance with the specified scheme. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified scheme. - * - * Implementations MUST support the schemes "http" and "https" case - * insensitively, and MAY accommodate other schemes if required. - * - * An empty scheme is equivalent to removing the scheme. - * - * @param string $scheme The scheme to use with the new instance. - * @return static A new instance with the specified scheme. - * @throws \InvalidArgumentException for invalid or unsupported schemes. - */ - public function withScheme(string $scheme); - - /** - * Return an instance with the specified user information. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified user information. - * - * Password is optional, but the user information MUST include the - * user; an empty string for the user is equivalent to removing user - * information. - * - * @param string $user The user name to use for authority. - * @param null|string $password The password associated with $user. - * @return static A new instance with the specified user information. - */ - public function withUserInfo(string $user, ?string $password = null); - - /** - * Return an instance with the specified host. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified host. - * - * An empty host value is equivalent to removing the host. - * - * @param string $host The hostname to use with the new instance. - * @return static A new instance with the specified host. - * @throws \InvalidArgumentException for invalid hostnames. - */ - public function withHost(string $host); - - /** - * Return an instance with the specified port. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified port. - * - * Implementations MUST raise an exception for ports outside the - * established TCP and UDP port ranges. - * - * A null value provided for the port is equivalent to removing the port - * information. - * - * @param null|int $port The port to use with the new instance; a null value - * removes the port information. - * @return static A new instance with the specified port. - * @throws \InvalidArgumentException for invalid ports. - */ - public function withPort(?int $port); - - /** - * Return an instance with the specified path. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified path. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * If the path is intended to be domain-relative rather than path relative then - * it must begin with a slash ("/"). Paths not starting with a slash ("/") - * are assumed to be relative to some base path known to the application or - * consumer. - * - * Users can provide both encoded and decoded path characters. - * Implementations ensure the correct encoding as outlined in getPath(). - * - * @param string $path The path to use with the new instance. - * @return static A new instance with the specified path. - * @throws \InvalidArgumentException for invalid paths. - */ - public function withPath(string $path); - - /** - * Return an instance with the specified query string. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified query string. - * - * Users can provide both encoded and decoded query characters. - * Implementations ensure the correct encoding as outlined in getQuery(). - * - * An empty query string value is equivalent to removing the query string. - * - * @param string $query The query string to use with the new instance. - * @return static A new instance with the specified query string. - * @throws \InvalidArgumentException for invalid query strings. - */ - public function withQuery(string $query); - - /** - * Return an instance with the specified URI fragment. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified URI fragment. - * - * Users can provide both encoded and decoded fragment characters. - * Implementations ensure the correct encoding as outlined in getFragment(). - * - * An empty fragment value is equivalent to removing the fragment. - * - * @param string $fragment The fragment to use with the new instance. - * @return static A new instance with the specified fragment. - */ - public function withFragment(string $fragment); - - /** - * Return the string representation as a URI reference. - * - * Depending on which components of the URI are present, the resulting - * string is either a full URI or relative reference according to RFC 3986, - * Section 4.1. The method concatenates the various components of the URI, - * using the appropriate delimiters: - * - * - If a scheme is present, it MUST be suffixed by ":". - * - If an authority is present, it MUST be prefixed by "//". - * - The path can be concatenated without delimiters. But there are two - * cases where the path has to be adjusted to make the URI reference - * valid as PHP does not allow to throw an exception in __toString(): - * - If the path is rootless and an authority is present, the path MUST - * be prefixed by "/". - * - If the path is starting with more than one "/" and no authority is - * present, the starting slashes MUST be reduced to one. - * - If a query is present, it MUST be prefixed by "?". - * - If a fragment is present, it MUST be prefixed by "#". - * - * @see http://tools.ietf.org/html/rfc3986#section-4.1 - * @return string - */ - public function __toString(); -} diff --git a/vendor/psr/log/LICENSE b/vendor/psr/log/LICENSE deleted file mode 100644 index 474c952..0000000 --- a/vendor/psr/log/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 PHP Framework Interoperability Group - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md deleted file mode 100644 index a9f20c4..0000000 --- a/vendor/psr/log/README.md +++ /dev/null @@ -1,58 +0,0 @@ -PSR Log -======= - -This repository holds all interfaces/classes/traits related to -[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). - -Note that this is not a logger of its own. It is merely an interface that -describes a logger. See the specification for more details. - -Installation ------------- - -```bash -composer require psr/log -``` - -Usage ------ - -If you need a logger, you can use the interface like this: - -```php -logger = $logger; - } - - public function doSomething() - { - if ($this->logger) { - $this->logger->info('Doing work'); - } - - try { - $this->doSomethingElse(); - } catch (Exception $exception) { - $this->logger->error('Oh no!', array('exception' => $exception)); - } - - // do something useful - } -} -``` - -You can then pick one of the implementations of the interface to get a logger. - -If you want to implement the interface, you can require this package and -implement `Psr\Log\LoggerInterface` in your code. Please read the -[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) -for details. diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json deleted file mode 100644 index 879fc6f..0000000 --- a/vendor/psr/log/composer.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "psr/log", - "description": "Common interface for logging libraries", - "keywords": ["psr", "psr-3", "log"], - "homepage": "https://github.com/php-fig/log", - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "require": { - "php": ">=8.0.0" - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - } -} diff --git a/vendor/psr/log/src/AbstractLogger.php b/vendor/psr/log/src/AbstractLogger.php deleted file mode 100644 index d60a091..0000000 --- a/vendor/psr/log/src/AbstractLogger.php +++ /dev/null @@ -1,15 +0,0 @@ -logger = $logger; - } -} diff --git a/vendor/psr/log/src/LoggerInterface.php b/vendor/psr/log/src/LoggerInterface.php deleted file mode 100644 index cb4cf64..0000000 --- a/vendor/psr/log/src/LoggerInterface.php +++ /dev/null @@ -1,98 +0,0 @@ -log(LogLevel::EMERGENCY, $message, $context); - } - - /** - * Action must be taken immediately. - * - * Example: Entire website down, database unavailable, etc. This should - * trigger the SMS alerts and wake you up. - */ - public function alert(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::ALERT, $message, $context); - } - - /** - * Critical conditions. - * - * Example: Application component unavailable, unexpected exception. - */ - public function critical(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::CRITICAL, $message, $context); - } - - /** - * Runtime errors that do not require immediate action but should typically - * be logged and monitored. - */ - public function error(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::ERROR, $message, $context); - } - - /** - * Exceptional occurrences that are not errors. - * - * Example: Use of deprecated APIs, poor use of an API, undesirable things - * that are not necessarily wrong. - */ - public function warning(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::WARNING, $message, $context); - } - - /** - * Normal but significant events. - */ - public function notice(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::NOTICE, $message, $context); - } - - /** - * Interesting events. - * - * Example: User logs in, SQL logs. - */ - public function info(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::INFO, $message, $context); - } - - /** - * Detailed debug information. - */ - public function debug(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::DEBUG, $message, $context); - } - - /** - * Logs with an arbitrary level. - * - * @param mixed $level - * - * @throws \Psr\Log\InvalidArgumentException - */ - abstract public function log($level, string|\Stringable $message, array $context = []): void; -} diff --git a/vendor/psr/log/src/NullLogger.php b/vendor/psr/log/src/NullLogger.php deleted file mode 100644 index de0561e..0000000 --- a/vendor/psr/log/src/NullLogger.php +++ /dev/null @@ -1,26 +0,0 @@ -logger) { }` - * blocks. - */ -class NullLogger extends AbstractLogger -{ - /** - * Logs with an arbitrary level. - * - * @param mixed[] $context - * - * @throws \Psr\Log\InvalidArgumentException - */ - public function log($level, string|\Stringable $message, array $context = []): void - { - // noop - } -} diff --git a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/bug_report.md b/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index d402046..0000000 --- a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -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 diff --git a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/feature_request.md b/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ce777f6..0000000 --- a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -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. diff --git a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/other-issue.md b/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/other-issue.md deleted file mode 100644 index fe5cc8d..0000000 --- a/vendor/textalk/websocket/.github/ISSUE_TEMPLATE/other-issue.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Other issue -about: Use this for other issues -title: '' -labels: '' -assignees: '' - ---- - -**Describe your issue** diff --git a/vendor/textalk/websocket/.github/workflows/acceptance.yml b/vendor/textalk/websocket/.github/workflows/acceptance.yml deleted file mode 100644 index a55f2a7..0000000 --- a/vendor/textalk/websocket/.github/workflows/acceptance.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: Acceptance - -on: [push, pull_request] - -jobs: - test-7-4: - runs-on: ubuntu-latest - name: Test PHP 7.4 - steps: - - name: Checkout - uses: actions/checkout@v3 - - 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@v3 - - 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@v3 - - 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 - - test-8-2: - runs-on: ubuntu-latest - name: Test PHP 8.2 - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up PHP 8.2 - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - - 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@v3 - - 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@v3 - - 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 diff --git a/vendor/textalk/websocket/.gitignore b/vendor/textalk/websocket/.gitignore deleted file mode 100644 index 379ab4b..0000000 --- a/vendor/textalk/websocket/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store -.phpunit.result.cache -build/ -composer.lock -composer.phar -vendor/ \ No newline at end of file diff --git a/vendor/textalk/websocket/COPYING.md b/vendor/textalk/websocket/COPYING.md deleted file mode 100644 index ba96480..0000000 --- a/vendor/textalk/websocket/COPYING.md +++ /dev/null @@ -1,16 +0,0 @@ -# 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. diff --git a/vendor/textalk/websocket/Makefile b/vendor/textalk/websocket/Makefile deleted file mode 100644 index 54d507e..0000000 --- a/vendor/textalk/websocket/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -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=PSR1,PSR12 --encoding=UTF-8 --report=full --colors 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 diff --git a/vendor/textalk/websocket/README.md b/vendor/textalk/websocket/README.md deleted file mode 100644 index c787131..0000000 --- a/vendor/textalk/websocket/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Websocket Client and Server for PHP - -[![Build Status](https://github.com/Textalk/websocket-php/actions/workflows/acceptance.yml/badge.svg)](https://github.com/Textalk/websocket-php/actions) -[![Coverage Status](https://coveralls.io/repos/github/Textalk/websocket-php/badge.svg?branch=master)](https://coveralls.io/github/Textalk/websocket-php) - -## Archived project - -This project has been archived and is no longer maintained. No bug fix and no additional features will be added.
-You won't be able to submit new issues or pull requests, and no additional features will be added - -This library has been replaced by [sirn-se/websocket-php](https://github.com/sirn-se/websocket-php) - -## Websocket Client and Server for 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) -- [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.4|^8.0`. -* For PHP `7.2` and `7.3` support use version [`1.5`](https://github.com/Textalk/websocket-php/tree/1.5.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, etrinh. diff --git a/vendor/textalk/websocket/composer.json b/vendor/textalk/websocket/composer.json deleted file mode 100644 index 23018ee..0000000 --- a/vendor/textalk/websocket/composer.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "textalk/websocket", - "description": "WebSocket client and server", - "license": "ISC", - "type": "library", - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen" - } - ], - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "autoload-dev": { - "psr-4": { - "WebSocket\\": "tests/mock" - } - }, - "require": { - "php": "^7.4 | ^8.0", - "phrity/net-uri": "^1.0", - "phrity/util-errorhandler": "^1.0", - "psr/log": "^1.0 | ^2.0 | ^3.0", - "psr/http-message": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0", - "php-coveralls/php-coveralls": "^2.0", - "squizlabs/php_codesniffer": "^3.5" - } -} diff --git a/vendor/textalk/websocket/docs/Changelog.md b/vendor/textalk/websocket/docs/Changelog.md deleted file mode 100644 index 38f264e..0000000 --- a/vendor/textalk/websocket/docs/Changelog.md +++ /dev/null @@ -1,167 +0,0 @@ -[Client](Client.md) • [Server](Server.md) • [Message](Message.md) • [Examples](Examples.md) • Changelog • [Contributing](Contributing.md) - -# Websocket: Changelog - -## `v1.6` - - > PHP version `^7.4|^8.0` - -### `1.6.3` - - * Fix issue with implicit default ports (@etrinh, @sirn-se) - -### `1.6.2` - - * Fix issue where port was missing in socket uri (@sirn-se) - -### `1.6.1` - - * Fix client path for http request (@simPod, @sirn-se) - -### `1.6.0` - * Connection separate from Client and Server (@sirn-se) - * getPier() deprecated, replaced by getRemoteName() (@sirn-se) - * Client accepts `Psr\Http\Message\UriInterface` as input for URI:s (@sirn-se) - * Bad URI throws exception when Client is instanciated, previously when used (@sirn-se) - * Preparations for multiple conection and listeners (@sirn-se) - * Major internal refactoring (@sirn-se) - -## `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. - diff --git a/vendor/textalk/websocket/docs/Client.md b/vendor/textalk/websocket/docs/Client.md deleted file mode 100644 index be8d285..0000000 --- a/vendor/textalk/websocket/docs/Client.md +++ /dev/null @@ -1,137 +0,0 @@ -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(UriInterface|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(Message|string $payload, string $opcode = 'text', bool $masked = true) : void; - public close(int $status = 1000, mixed $message = 'ttfn') : void; - public receive() : Message|string|null; - - public getName() : string|null; - public getRemoteName() : 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. diff --git a/vendor/textalk/websocket/docs/Contributing.md b/vendor/textalk/websocket/docs/Contributing.md deleted file mode 100644 index c68ab83..0000000 --- a/vendor/textalk/websocket/docs/Contributing.md +++ /dev/null @@ -1,51 +0,0 @@ -[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. - -Base your patch on corresponding version branch, and target that version branch in your pull request. - -* `v1.6-master` current version -* `v1.5-master` previous version, bug fixes only -* Older versions should not be target of pull requests - - -## 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 -``` diff --git a/vendor/textalk/websocket/docs/Examples.md b/vendor/textalk/websocket/docs/Examples.md deleted file mode 100644 index 399e0cc..0000000 --- a/vendor/textalk/websocket/docs/Examples.md +++ /dev/null @@ -1,101 +0,0 @@ -[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; -* `auth` - Server will respond with auth header if provided by client -* `close` - Server will close current connection -* `exit` - Server will close all active connections -* `headers` - Server will respond with all headers provided by client -* `ping` - Server will send a ping message -* `pong` - Server will send a pong message -* `stop` - Server will stop listening -* 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 -``` diff --git a/vendor/textalk/websocket/docs/Message.md b/vendor/textalk/websocket/docs/Message.md deleted file mode 100644 index 80df04a..0000000 --- a/vendor/textalk/websocket/docs/Message.md +++ /dev/null @@ -1,60 +0,0 @@ -[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 Message 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(); -``` diff --git a/vendor/textalk/websocket/docs/Server.md b/vendor/textalk/websocket/docs/Server.md deleted file mode 100644 index 9e12e07..0000000 --- a/vendor/textalk/websocket/docs/Server.md +++ /dev/null @@ -1,136 +0,0 @@ -[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(Message|string $payload, string $opcode = 'text', bool $masked = true) : void; - public close(int $status = 1000, mixed $message = 'ttfn') : void; - public receive() : Message|string|null; - - public getPort() : int; - public getPath() : string; - public getRequest() : array; - public getHeader(string $header_name) : string|null; - - public getName() : string|null; - public getRemoteName() : 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 instance 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. diff --git a/vendor/textalk/websocket/examples/echoserver.php b/vendor/textalk/websocket/examples/echoserver.php deleted file mode 100644 index a85e564..0000000 --- a/vendor/textalk/websocket/examples/echoserver.php +++ /dev/null @@ -1,87 +0,0 @@ - : The port to listen to, default 8000 - * --timeout : 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 "> Echo server\n"; - -// Server options specified or random -$options = array_merge([ - 'port' => 8000, - 'timeout' => 200, - 'filter' => ['text', 'binary', 'ping', 'pong', 'close'], -], 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"; -} - -// Initiate server. -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"; - } -} diff --git a/vendor/textalk/websocket/examples/random_client.php b/vendor/textalk/websocket/examples/random_client.php deleted file mode 100644 index b23bd6b..0000000 --- a/vendor/textalk/websocket/examples/random_client.php +++ /dev/null @@ -1,94 +0,0 @@ - : The URI to connect to, default ws://localhost:8000 - * --timeout : Timeout in seconds, random default - * --fragment_size : 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)); -} diff --git a/vendor/textalk/websocket/examples/random_server.php b/vendor/textalk/websocket/examples/random_server.php deleted file mode 100644 index 0b0849c..0000000 --- a/vendor/textalk/websocket/examples/random_server.php +++ /dev/null @@ -1,93 +0,0 @@ - : The port to listen to, default 8000 - * --timeout : Timeout in seconds, random default - * --fragment_size : 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)); -} diff --git a/vendor/textalk/websocket/examples/send.php b/vendor/textalk/websocket/examples/send.php deleted file mode 100644 index 30e48e0..0000000 --- a/vendor/textalk/websocket/examples/send.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * Console options: - * --uri : The URI to connect to, default ws://localhost:8000 - * --opcode : 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"; -} diff --git a/vendor/textalk/websocket/lib/BadOpcodeException.php b/vendor/textalk/websocket/lib/BadOpcodeException.php deleted file mode 100644 index 260a977..0000000 --- a/vendor/textalk/websocket/lib/BadOpcodeException.php +++ /dev/null @@ -1,14 +0,0 @@ - null, - 'filter' => ['text', 'binary'], - 'fragment_size' => 4096, - 'headers' => null, - 'logger' => null, - 'origin' => null, // @deprecated - 'persistent' => false, - 'return_obj' => false, - 'timeout' => 5, - ]; - - private $socket_uri; - private $connection; - private $options = []; - private $listen = false; - private $last_opcode = null; - - - /* ---------- Magic methods ------------------------------------------------------ */ - - /** - * @param UriInterface|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($uri, array $options = []) - { - $this->socket_uri = $this->parseUri($uri); - $this->options = array_merge(self::$default_options, [ - 'logger' => new NullLogger(), - ], $options); - $this->setLogger($this->options['logger']); - } - - /** - * Get string representation of instance. - * @return string String representation. - */ - public function __toString(): string - { - return sprintf( - "%s(%s)", - get_class($this), - $this->getName() ?: 'closed' - ); - } - - - /* ---------- Client option functions -------------------------------------------- */ - - /** - * Set timeout. - * @param int $timeout Timeout in seconds. - */ - public function setTimeout(int $timeout): void - { - $this->options['timeout'] = $timeout; - if (!$this->isConnected()) { - return; - } - $this->connection->setTimeout($timeout); - $this->connection->setOptions($this->options); - } - - /** - * Set fragmentation size. - * @param int $fragment_size Fragment size in bytes. - * @return self. - */ - public function setFragmentSize(int $fragment_size): self - { - $this->options['fragment_size'] = $fragment_size; - $this->connection->setOptions($this->options); - return $this; - } - - /** - * Get fragmentation size. - * @return int $fragment_size Fragment size in bytes. - */ - public function getFragmentSize(): int - { - return $this->options['fragment_size']; - } - - - /* ---------- Connection operations ---------------------------------------------- */ - - /** - * Send text message. - * @param string $payload Content as string. - */ - public function text(string $payload): void - { - $this->send($payload); - } - - /** - * Send binary message. - * @param string $payload Content as binary string. - */ - public function binary(string $payload): void - { - $this->send($payload, 'binary'); - } - - /** - * Send ping. - * @param string $payload Optional text as string. - */ - public function ping(string $payload = ''): void - { - $this->send($payload, 'ping'); - } - - /** - * Send unsolicited pong. - * @param string $payload Optional text as string. - */ - public function pong(string $payload = ''): void - { - $this->send($payload, 'pong'); - } - - /** - * Send message. - * @param string $payload Message to send. - * @param string $opcode Opcode to use, default: 'text'. - * @param bool $masked If message should be masked default: true. - */ - 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); - } - - $factory = new Factory(); - $message = $factory->create($opcode, $payload); - $this->connection->pushMessage($message, $masked); - } - - /** - * 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; - } - $this->connection->close($status, $message); - } - - /** - * Disconnect from server. - */ - public function disconnect(): void - { - if ($this->isConnected()) { - $this->connection->disconnect(); - } - } - - /** - * Receive message. - * Note that this operation will block reading. - * @return mixed Message, text or null depending on settings. - */ - public function receive() - { - $filter = $this->options['filter']; - $return_obj = $this->options['return_obj']; - - if (!$this->isConnected()) { - $this->connect(); - } - - while (true) { - $message = $this->connection->pullMessage(); - $opcode = $message->getOpcode(); - if (in_array($opcode, $filter)) { - $this->last_opcode = $opcode; - $return = $return_obj ? $message : $message->getContent(); - break; - } elseif ($opcode == 'close') { - $this->last_opcode = null; - $return = $return_obj ? $message : null; - break; - } - } - return $return; - } - - - /* ---------- Connection functions ----------------------------------------------- */ - - /** - * Get last received opcode. - * @return string|null Opcode. - */ - public function getLastOpcode(): ?string - { - return $this->last_opcode; - } - - /** - * Get close status on connection. - * @return int|null Close status. - */ - public function getCloseStatus(): ?int - { - return $this->connection ? $this->connection->getCloseStatus() : null; - } - - /** - * If Client has active connection. - * @return bool True if active connection. - */ - public function isConnected(): bool - { - return $this->connection && $this->connection->isConnected(); - } - - /** - * Get name of local socket, or null if not connected. - * @return string|null - */ - public function getName(): ?string - { - return $this->isConnected() ? $this->connection->getName() : null; - } - - /** - * Get name of remote socket, or null if not connected. - * @return string|null - */ - public function getRemoteName(): ?string - { - return $this->isConnected() ? $this->connection->getRemoteName() : null; - } - - /** - * Get name of remote socket, or null if not connected. - * @return string|null - * @deprecated Will be removed in future version, use getPeer() instead. - */ - public function getPier(): ?string - { - trigger_error( - 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', - E_USER_DEPRECATED - ); - return $this->getRemoteName(); - } - - - /* ---------- Helper functions --------------------------------------------------- */ - - /** - * Perform WebSocket handshake - */ - protected function connect(): void - { - $this->connection = null; - - $host_uri = $this->socket_uri - ->withScheme($this->socket_uri->getScheme() == 'wss' ? 'ssl' : 'tcp') - ->withPort($this->socket_uri->getPort() ?? ($this->socket_uri->getScheme() == 'wss' ? 443 : 80)) - ->withPath('') - ->withQuery('') - ->withFragment('') - ->withUserInfo(''); - - // Path must be absolute - $http_path = $this->socket_uri->getPath(); - if ($http_path === '' || $http_path[0] !== '/') { - $http_path = "/{$http_path}"; - } - - $http_uri = (new Uri()) - ->withPath($http_path) - ->withQuery($this->socket_uri->getQuery()); - - // 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; - $socket = null; - - try { - $handler = new ErrorHandler(); - $socket = $handler->with(function () use ($host_uri, $flags, $context) { - $error = $errno = $errstr = null; - // Open the socket. - return stream_socket_client( - $host_uri, - $errno, - $errstr, - $this->options['timeout'], - $flags, - $context - ); - }); - if (!$socket) { - throw new ErrorException('No socket'); - } - } catch (ErrorException $e) { - $error = "Could not open socket to \"{$host_uri->getAuthority()}\": {$e->getMessage()} ({$e->getCode()})."; - $this->logger->error($error, ['severity' => $e->getSeverity()]); - throw new ConnectionException($error, 0, [], $e); - } - - $this->connection = new Connection($socket, $this->options); - $this->connection->setLogger($this->logger); - if (!$this->isConnected()) { - $error = "Invalid stream on \"{$host_uri->getAuthority()}\"."; - $this->logger->error($error); - throw new ConnectionException($error); - } - - if (!$persistent || $this->connection->tell() == 0) { - // Set timeout on the stream as well. - $this->connection->setTimeout($this->options['timeout']); - - // Generate the WebSocket key. - $key = self::generateKey(); - - // Default headers - $headers = [ - 'Host' => $host_uri->getAuthority(), - 'User-Agent' => 'websocket-client-php', - 'Connection' => 'Upgrade', - 'Upgrade' => 'websocket', - 'Sec-WebSocket-Key' => $key, - 'Sec-WebSocket-Version' => '13', - ]; - - // Handle basic authentication. - if ($userinfo = $this->socket_uri->getUserInfo()) { - $headers['authorization'] = 'Basic ' . base64_encode($userinfo); - } - - // 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 {$http_uri} 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->connection->write($header); - - // Get server response header (terminated with double CR+LF). - $response = ''; - try { - do { - $buffer = $this->connection->gets(1024); - $response .= $buffer; - } while (substr_count($response, "\r\n\r\n") == 0); - } catch (Exception $e) { - throw new ConnectionException('Client handshake error', $e->getCode(), $e->getData(), $e); - } - - // Validate response. - if (!preg_match('#Sec-WebSocket-Accept:\s(.*)$#mUi', $response, $matches)) { - $error = sprintf( - "Connection to '%s' failed: Server sent invalid upgrade response: %s", - (string)$this->socket_uri, - (string)$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 {$this->socket_uri}"); - } - - /** - * 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); - } - - protected function parseUri($uri): UriInterface - { - if ($uri instanceof UriInterface) { - $uri = $uri; - } elseif (is_string($uri)) { - try { - $uri = new Uri($uri); - } catch (InvalidArgumentException $e) { - throw new BadUriException("Invalid URI '{$uri}' provided.", 0, $e); - } - } else { - throw new BadUriException("Provided URI must be a UriInterface or string."); - } - if (!in_array($uri->getScheme(), ['ws', 'wss'])) { - throw new BadUriException("Invalid URI scheme, must be 'ws' or 'wss'."); - } - return $uri; - } -} diff --git a/vendor/textalk/websocket/lib/Connection.php b/vendor/textalk/websocket/lib/Connection.php deleted file mode 100644 index d5aa48b..0000000 --- a/vendor/textalk/websocket/lib/Connection.php +++ /dev/null @@ -1,518 +0,0 @@ -stream = $stream; - $this->setOptions($options); - $this->setLogger(new NullLogger()); - $this->msg_factory = new Factory(); - } - - public function __destruct() - { - if ($this->getType() === 'stream') { - fclose($this->stream); - } - } - - public function setOptions(array $options = []): void - { - $this->options = array_merge($this->options, $options); - } - - public function getCloseStatus(): ?int - { - return $this->close_status; - } - - /** - * 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)); - } - $message = $this->msg_factory->create('close', $status_str . $message); - $this->pushMessage($message, true); - - $this->logger->debug("Closing with status: {$status}."); - - $this->is_closing = true; - while (true) { - $message = $this->pullMessage(); - if ($message->getOpcode() == 'close') { - break; - } - } - } - - - /* ---------- Message methods ---------------------------------------------------- */ - - // Push a message to stream - public function pushMessage(Message $message, bool $masked = true): void - { - $frames = $message->getFrames($masked, $this->options['fragment_size']); - foreach ($frames as $frame) { - $this->pushFrame($frame); - } - $this->logger->info("[connection] Pushed {$message}", [ - 'opcode' => $message->getOpcode(), - 'content-length' => $message->getLength(), - 'frames' => count($frames), - ]); - } - - // Pull a message from stream - public function pullMessage(): Message - { - do { - $frame = $this->pullFrame(); - $frame = $this->autoRespond($frame); - list ($final, $payload, $opcode, $masked) = $frame; - - if ($opcode == 'close') { - $this->close(); - } - - // Continuation and factual opcode - $continuation = $opcode == 'continuation'; - $payload_opcode = $continuation ? $this->read_buffer['opcode'] : $opcode; - - // 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; - } - - $message = $this->msg_factory->create($payload_opcode, $payload); - - $this->logger->info("[connection] Pulled {$message}", [ - 'opcode' => $payload_opcode, - 'content-length' => strlen($payload), - 'frames' => $frames, - ]); - - return $message; - } - - - /* ---------- Frame I/O methods -------------------------------------------------- */ - - // Pull frame from stream - private function pullFrame(): 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 - $masked = (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 ($masked) { - $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 ($masked) { - // Unmask payload. - for ($i = 0; $i < $payload_length; $i++) { - $payload .= ($data[$i] ^ $masking_key[$i % 4]); - } - } else { - $payload = $data; - } - } - - $this->logger->debug("[connection] Pulled '{opcode}' frame", [ - 'opcode' => $opcode, - 'final' => $final, - 'content-length' => strlen($payload), - ]); - return [$final, $payload, $opcode, $masked]; - } - - // Push frame to stream - private function pushFrame(array $frame): void - { - list ($final, $payload, $opcode, $masked) = $frame; - $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("[connection] Pushed '{$opcode}' frame", [ - 'opcode' => $opcode, - 'final' => $final, - 'content-length' => strlen($payload), - ]); - } - - // Trigger auto response for frame - private function autoRespond(array $frame) - { - list ($final, $payload, $opcode, $masked) = $frame; - $payload_length = strlen($payload); - - switch ($opcode) { - case 'ping': - // If we received a ping, respond with a pong - $this->logger->debug("[connection] Received 'ping', sending 'pong'."); - $message = $this->msg_factory->create('pong', $payload); - $this->pushMessage($message, $masked); - return [$final, $payload, $opcode, $masked]; - case 'close': - // If we received close, possibly acknowledge and close connection - $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("[connection] Received 'close', status: {$status}."); - if (!$this->is_closing) { - $ack = "{$status_bin}Close acknowledged: {$status}"; - $message = $this->msg_factory->create('close', $ack); - $this->pushMessage($message, $masked); - } else { - $this->is_closing = false; // A close response, all done. - } - $this->disconnect(); - return [$final, $payload, $opcode, $masked]; - default: - return [$final, $payload, $opcode, $masked]; - } - } - - - /* ---------- Stream I/O methods ------------------------------------------------- */ - - /** - * Close connection stream. - * @return bool - */ - public function disconnect(): bool - { - $this->logger->debug('Closing connection'); - return fclose($this->stream); - } - - /** - * If connected to stream. - * @return bool - */ - public function isConnected(): bool - { - return in_array($this->getType(), ['stream', 'persistent stream']); - } - - /** - * Return type of connection. - * @return string|null Type of connection or null if invalid type. - */ - public function getType(): ?string - { - return get_resource_type($this->stream); - } - - /** - * Get name of local socket, or null if not connected. - * @return string|null - */ - public function getName(): ?string - { - return stream_socket_get_name($this->stream, false); - } - - /** - * Get name of remote socket, or null if not connected. - * @return string|null - */ - public function getRemoteName(): ?string - { - return stream_socket_get_name($this->stream, true); - } - - /** - * Get meta data for connection. - * @return array - */ - public function getMeta(): array - { - return stream_get_meta_data($this->stream); - } - - /** - * Returns current position of stream pointer. - * @return int - * @throws ConnectionException - */ - public function tell(): int - { - $tell = ftell($this->stream); - if ($tell === false) { - $this->throwException('Could not resolve stream pointer position'); - } - return $tell; - } - - /** - * If stream pointer is at end of file. - * @return bool - */ - public function eof(): int - { - return feof($this->stream); - } - - - /* ---------- Stream option methods ---------------------------------------------- */ - - /** - * Set time out on connection. - * @param int $seconds Timeout part in seconds - * @param int $microseconds Timeout part in microseconds - * @return bool - */ - public function setTimeout(int $seconds, int $microseconds = 0): bool - { - $this->logger->debug("Setting timeout {$seconds}:{$microseconds} seconds"); - return stream_set_timeout($this->stream, $seconds, $microseconds); - } - - - /* ---------- Stream read/write methods ------------------------------------------ */ - - /** - * Read line from stream. - * @param int $length Maximum number of bytes to read - * @param string $ending Line delimiter - * @return string Read data - */ - public function getLine(int $length, string $ending): string - { - $line = stream_get_line($this->stream, $length, $ending); - if ($line === false) { - $this->throwException('Could not read from stream'); - } - $read = strlen($line); - $this->logger->debug("Read {$read} bytes of line."); - return $line; - } - - /** - * Read line from stream. - * @param int $length Maximum number of bytes to read - * @return string Read data - */ - public function gets(int $length): string - { - $line = fgets($this->stream, $length); - if ($line === false) { - $this->throwException('Could not read from stream'); - } - $read = strlen($line); - $this->logger->debug("Read {$read} bytes of line."); - return $line; - } - - /** - * Read characters from stream. - * @param int $length Maximum number of bytes to read - * @return string Read data - */ - public function read(string $length): string - { - $data = ''; - while (strlen($data) < $length) { - $buffer = fread($this->stream, $length - strlen($data)); - if (!$buffer) { - $meta = stream_get_meta_data($this->stream); - 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; - } - - /** - * Write characters to stream. - * @param string $data Data to read - */ - public function write(string $data): void - { - $length = strlen($data); - $written = fwrite($this->stream, $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."); - } - - - /* ---------- Internal helper methods -------------------------------------------- */ - - private function throwException(string $message, int $code = 0): void - { - $meta = ['closed' => true]; - if ($this->isConnected()) { - $meta = $this->getMeta(); - $this->disconnect(); - 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); - } -} diff --git a/vendor/textalk/websocket/lib/ConnectionException.php b/vendor/textalk/websocket/lib/ConnectionException.php deleted file mode 100644 index aa1d7f4..0000000 --- a/vendor/textalk/websocket/lib/ConnectionException.php +++ /dev/null @@ -1,33 +0,0 @@ -data = $data; - } - - public function getData(): array - { - return $this->data; - } -} diff --git a/vendor/textalk/websocket/lib/Exception.php b/vendor/textalk/websocket/lib/Exception.php deleted file mode 100644 index 6482b7e..0000000 --- a/vendor/textalk/websocket/lib/Exception.php +++ /dev/null @@ -1,7 +0,0 @@ -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); - } - - // Split messages into frames - public function getFrames(bool $masked = true, int $framesize = 4096): array - { - - $frames = []; - $split = str_split($this->getContent(), $framesize) ?: ['']; - foreach ($split as $payload) { - $frames[] = [false, $payload, 'continuation', $masked]; - } - $frames[0][2] = $this->opcode; - $frames[array_key_last($frames)][0] = true; - return $frames; - } -} diff --git a/vendor/textalk/websocket/lib/Message/Ping.php b/vendor/textalk/websocket/lib/Message/Ping.php deleted file mode 100644 index f9bb652..0000000 --- a/vendor/textalk/websocket/lib/Message/Ping.php +++ /dev/null @@ -1,15 +0,0 @@ - 0, - 'text' => 1, - 'binary' => 2, - 'close' => 8, - 'ping' => 9, - 'pong' => 10, - ]; -} diff --git a/vendor/textalk/websocket/lib/Server.php b/vendor/textalk/websocket/lib/Server.php deleted file mode 100644 index 1521588..0000000 --- a/vendor/textalk/websocket/lib/Server.php +++ /dev/null @@ -1,470 +0,0 @@ - ['text', 'binary'], - 'fragment_size' => 4096, - 'logger' => null, - 'port' => 8000, - 'return_obj' => false, - 'timeout' => null, - ]; - - protected $port; - protected $listening; - protected $request; - protected $request_path; - private $connections = []; - private $options = []; - private $listen = false; - private $last_opcode; - - - /* ---------- Magic methods ------------------------------------------------------ */ - - /** - * @param array $options - * Associative array containing: - * - filter: Array of opcodes to handle. Default: ['text', 'binary']. - * - fragment_size: Set framgemnt size. Default: 4096 - * - logger: PSR-3 compatible logger. Default NullLogger. - * - port: Chose port for listening. Default 8000. - * - return_obj: If receive() function return Message instance. Default false. - * - timeout: Set the socket timeout in seconds. - */ - public function __construct(array $options = []) - { - $this->options = array_merge(self::$default_options, [ - 'logger' => new NullLogger(), - ], $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}"); - } - - /** - * Get string representation of instance. - * @return string String representation. - */ - public function __toString(): string - { - return sprintf( - "%s(%s)", - get_class($this), - $this->getName() ?: 'closed' - ); - } - - - /* ---------- Server operations -------------------------------------------------- */ - - /** - * Accept a single incoming request. - * Note that this operation will block accepting additional requests. - * @return bool True if listening. - */ - public function accept(): bool - { - $this->disconnect(); - return (bool)$this->listening; - } - - - /* ---------- Server option functions -------------------------------------------- */ - - /** - * Get current port. - * @return int port. - */ - public function getPort(): int - { - return $this->port; - } - - /** - * Set timeout. - * @param int $timeout Timeout in seconds. - */ - public function setTimeout(int $timeout): void - { - $this->options['timeout'] = $timeout; - if (!$this->isConnected()) { - return; - } - foreach ($this->connections as $connection) { - $connection->setTimeout($timeout); - $connection->setOptions($this->options); - } - } - - /** - * Set fragmentation size. - * @param int $fragment_size Fragment size in bytes. - * @return self. - */ - public function setFragmentSize(int $fragment_size): self - { - $this->options['fragment_size'] = $fragment_size; - foreach ($this->connections as $connection) { - $connection->setOptions($this->options); - } - return $this; - } - - /** - * Get fragmentation size. - * @return int $fragment_size Fragment size in bytes. - */ - public function getFragmentSize(): int - { - return $this->options['fragment_size']; - } - - - /* ---------- Connection broadcast operations ------------------------------------ */ - - /** - * Broadcast text message to all conenctions. - * @param string $payload Content as string. - */ - public function text(string $payload): void - { - $this->send($payload); - } - - /** - * Broadcast binary message to all conenctions. - * @param string $payload Content as binary string. - */ - public function binary(string $payload): void - { - $this->send($payload, 'binary'); - } - - /** - * Broadcast ping message to all conenctions. - * @param string $payload Optional text as string. - */ - public function ping(string $payload = ''): void - { - $this->send($payload, 'ping'); - } - - /** - * Broadcast pong message to all conenctions. - * @param string $payload Optional text as string. - */ - public function pong(string $payload = ''): void - { - $this->send($payload, 'pong'); - } - - /** - * Send message on all connections. - * @param string $payload Message to send. - * @param string $opcode Opcode to use, default: 'text'. - * @param bool $masked If message should be masked default: true. - */ - 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); - } - - $factory = new Factory(); - $message = $factory->create($opcode, $payload); - - foreach ($this->connections as $connection) { - $connection->pushMessage($message, $masked); - } - } - - /** - * Close all connections. - * @param int $status Close status, default: 1000. - * @param string $message Close message, default: 'ttfn'. - */ - public function close(int $status = 1000, string $message = 'ttfn'): void - { - foreach ($this->connections as $connection) { - if ($connection->isConnected()) { - $connection->close($status, $message); - } - } - } - - /** - * Disconnect all connections. - */ - public function disconnect(): void - { - foreach ($this->connections as $connection) { - if ($connection->isConnected()) { - $connection->disconnect(); - } - } - $this->connections = []; - } - - /** - * Receive message from single connection. - * Note that this operation will block reading and only read from first available connection. - * @return mixed Message, text or null depending on settings. - */ - public function receive() - { - $filter = $this->options['filter']; - $return_obj = $this->options['return_obj']; - - if (!$this->isConnected()) { - $this->connect(); - } - $connection = current($this->connections); - - while (true) { - $message = $connection->pullMessage(); - $opcode = $message->getOpcode(); - if (in_array($opcode, $filter)) { - $this->last_opcode = $opcode; - $return = $return_obj ? $message : $message->getContent(); - break; - } elseif ($opcode == 'close') { - $this->last_opcode = null; - $return = $return_obj ? $message : null; - break; - } - } - return $return; - } - - - /* ---------- Connection functions ----------------------------------------------- */ - - /** - * Get requested path from last connection. - * @return string Path. - */ - public function getPath(): string - { - return $this->request_path; - } - - /** - * Get request from last connection. - * @return array Request. - */ - public function getRequest(): array - { - return $this->request; - } - - /** - * Get headers from last connection. - * @return string|null Headers. - */ - 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; - } - - /** - * Get last received opcode. - * @return string|null Opcode. - */ - public function getLastOpcode(): ?string - { - return $this->last_opcode; - } - - /** - * Get close status from single connection. - * @return int|null Close status. - */ - public function getCloseStatus(): ?int - { - return $this->connections ? current($this->connections)->getCloseStatus() : null; - } - - /** - * If Server has active connections. - * @return bool True if active connection. - */ - public function isConnected(): bool - { - foreach ($this->connections as $connection) { - if ($connection->isConnected()) { - return true; - } - } - return false; - } - - /** - * Get name of local socket from single connection. - * @return string|null Name of local socket. - */ - public function getName(): ?string - { - return $this->isConnected() ? current($this->connections)->getName() : null; - } - - /** - * Get name of remote socket from single connection. - * @return string|null Name of remote socket. - */ - public function getRemoteName(): ?string - { - return $this->isConnected() ? current($this->connections)->getRemoteName() : null; - } - - /** - * @deprecated Will be removed in future version. - */ - public function getPier(): ?string - { - trigger_error( - 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', - E_USER_DEPRECATED - ); - return $this->getRemoteName(); - } - - - /* ---------- Helper functions --------------------------------------------------- */ - - // Connect when read/write operation is performed. - private function connect(): void - { - try { - $handler = new ErrorHandler(); - $socket = $handler->with(function () { - if (isset($this->options['timeout'])) { - $socket = stream_socket_accept($this->listening, $this->options['timeout']); - } else { - $socket = stream_socket_accept($this->listening); - } - if (!$socket) { - throw new ErrorException('No socket'); - } - return $socket; - }); - } catch (ErrorException $e) { - $error = "Server failed to connect. {$e->getMessage()}"; - $this->logger->error($error, ['severity' => $e->getSeverity()]); - throw new ConnectionException($error, 0, [], $e); - } - - $connection = new Connection($socket, $this->options); - $connection->setLogger($this->logger); - - if (isset($this->options['timeout'])) { - $connection->setTimeout($this->options['timeout']); - } - - $this->logger->info("Client has connected to port {port}", [ - 'port' => $this->port, - 'peer' => $connection->getRemoteName(), - ]); - $this->performHandshake($connection); - $this->connections = ['*' => $connection]; - } - - // Perform upgrade handshake on new connections. - private function performHandshake(Connection $connection): void - { - $request = ''; - do { - $buffer = $connection->getLine(1024, "\r\n"); - $request .= $buffer . "\n"; - $metadata = $connection->getMeta(); - } while (!$connection->eof() && $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"; - - $connection->write($header); - $this->logger->debug("Handshake on {$get_uri}"); - } -} diff --git a/vendor/textalk/websocket/lib/TimeoutException.php b/vendor/textalk/websocket/lib/TimeoutException.php deleted file mode 100644 index 7276556..0000000 --- a/vendor/textalk/websocket/lib/TimeoutException.php +++ /dev/null @@ -1,14 +0,0 @@ - - - - - lib/ - - - - - tests - - - diff --git a/vendor/textalk/websocket/tests/ClientTest.php b/vendor/textalk/websocket/tests/ClientTest.php deleted file mode 100644 index df23d75..0000000 --- a/vendor/textalk/websocket/tests/ClientTest.php +++ /dev/null @@ -1,568 +0,0 @@ -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 testClientNoPath(): void - { - MockSocket::initialize('client.connect-root', $this); - $client = new Client('ws://localhost:8000'); - $client->send('Connect'); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testClientRelativePath(): void - { - MockSocket::initialize('client.connect', $this); - $uri = new Uri('ws://localhost:8000'); - $uri = $uri->withPath('my/mock/path'); - $client = new Client($uri); - $client->send('Connect'); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testClientWsDefaultPort(): void - { - MockSocket::initialize('client.connect-default-port-ws', $this); - $uri = new Uri('ws://localhost'); - $uri = $uri->withPath('my/mock/path'); - $client = new Client($uri); - $client->send('Connect'); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testClientWssDefaultPort(): void - { - MockSocket::initialize('client.connect-default-port-wss', $this); - $uri = new Uri('wss://localhost'); - $uri = $uri->withPath('my/mock/path'); - $client = new Client($uri); - $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 testFailedPersistentConnection(): void - { - MockSocket::initialize('client.connect-persistent-failure', $this); - $client = new Client('ws://localhost:8000/my/mock/path', ['persistent' => true]); - $this->expectException('WebSocket\ConnectionException'); - $this->expectExceptionMessage('Could not resolve stream pointer position'); - $client->send('Connect'); - } - - public function testBadScheme(): void - { - MockSocket::initialize('client.connect', $this); - $this->expectException('WebSocket\BadUriException'); - $this->expectExceptionMessage("Invalid URI scheme, must be 'ws' or 'wss'."); - $client = new Client('bad://localhost:8000/my/mock/path'); - } - - public function testBadUri(): void - { - MockSocket::initialize('client.connect', $this); - $this->expectException('WebSocket\BadUriException'); - $this->expectExceptionMessage("Invalid URI '--:this is not an uri:--' provided."); - $client = new Client('--:this is not an uri:--'); - } - - public function testInvalidUriType(): void - { - MockSocket::initialize('client.connect', $this); - $this->expectException('WebSocket\BadUriException'); - $this->expectExceptionMessage("Provided URI must be a UriInterface or string."); - $client = new Client([]); - } - - public function testUriInterface(): void - { - MockSocket::initialize('client.connect', $this); - $uri = new Uri('ws://localhost:8000/my/mock/path'); - $client = new Client($uri); - $client->send('Connect'); - $this->assertTrue(MockSocket::isEmpty()); - } - - 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 testBadStreamConnection(): void - { - MockSocket::initialize('client.connect-bad-stream', $this); - $client = new Client('ws://localhost:8000/my/mock/path'); - $this->expectException('WebSocket\ConnectionException'); - $this->expectExceptionCode(0); - $this->expectExceptionMessage('Invalid stream on "localhost:8000"'); - $client->send('Connect'); - } - - public function testHandshakeFailure(): void - { - MockSocket::initialize('client.connect-handshake-failure', $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 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:8000/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(1024); - $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->getRemoteName()); - $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->getRemoteName()); - $this->assertEquals('WebSocket\Client(127.0.0.1:12345)', "{$client}"); - } - - public function testUnconnectedClient(): void - { - $client = new Client('ws://localhost:8000/my/mock/path'); - $this->assertFalse($client->isConnected()); - $client->setTimeout(30); - $client->close(); - $this->assertFalse($client->isConnected()); - $this->assertNull($client->getName()); - $this->assertNull($client->getRemoteName()); - $this->assertNull($client->getCloseStatus()); - } - - public function testDeprecated(): void - { - $client = new Client('ws://localhost:8000/my/mock/path'); - (new ErrorHandler())->withAll(function () use ($client) { - $this->assertNull($client->getPier()); - }, function ($exceptions, $result) { - $this->assertEquals( - 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', - $exceptions[0]->getMessage() - ); - }, E_USER_DEPRECATED); - } -} diff --git a/vendor/textalk/websocket/tests/ExceptionTest.php b/vendor/textalk/websocket/tests/ExceptionTest.php deleted file mode 100644 index 2083e70..0000000 --- a/vendor/textalk/websocket/tests/ExceptionTest.php +++ /dev/null @@ -1,51 +0,0 @@ - '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()); - } -} diff --git a/vendor/textalk/websocket/tests/MessageTest.php b/vendor/textalk/websocket/tests/MessageTest.php deleted file mode 100644 index bade435..0000000 --- a/vendor/textalk/websocket/tests/MessageTest.php +++ /dev/null @@ -1,60 +0,0 @@ -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'); - } -} diff --git a/vendor/textalk/websocket/tests/README.md b/vendor/textalk/websocket/tests/README.md deleted file mode 100644 index 0af2997..0000000 --- a/vendor/textalk/websocket/tests/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# 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.4`, `8.0`, `8.1` and `8.2`. - -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. diff --git a/vendor/textalk/websocket/tests/ServerTest.php b/vendor/textalk/websocket/tests/ServerTest.php deleted file mode 100644 index 033895f..0000000 --- a/vendor/textalk/websocket/tests/ServerTest.php +++ /dev/null @@ -1,511 +0,0 @@ -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->getRemoteName()); - $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->getRemoteName()); - $this->assertEquals('WebSocket\Server(127.0.0.1:12345)', "{$server}"); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testUnconnectedServer(): void - { - MockSocket::initialize('server.construct', $this); - $server = new Server(); - $this->assertFalse($server->isConnected()); - $server->setTimeout(30); - $server->close(); - $this->assertFalse($server->isConnected()); - $this->assertNull($server->getName()); - $this->assertNull($server->getRemoteName()); - $this->assertNull($server->getCloseStatus()); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testFailedHandshake(): void - { - MockSocket::initialize('server.construct', $this); - $server = new Server(); - $this->assertTrue(MockSocket::isEmpty()); - - MockSocket::initialize('server.accept-failed-handshake', $this); - $server->accept(); - $this->expectException('WebSocket\ConnectionException'); - $this->expectExceptionCode(0); - $this->expectExceptionMessage('Could not read from stream'); - $server->send('Connect'); - $this->assertFalse($server->isConnected()); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testServerDisconnect(): 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('server.disconnect', $this); - $server->disconnect(); - $this->assertFalse($server->isConnected()); - $this->assertTrue(MockSocket::isEmpty()); - } - - public function testDeprecated(): void - { - MockSocket::initialize('server.construct', $this); - $server = new Server(); - $this->assertTrue(MockSocket::isEmpty()); - (new ErrorHandler())->withAll(function () use ($server) { - $this->assertNull($server->getPier()); - }, function ($exceptions, $result) { - $this->assertEquals( - 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', - $exceptions[0]->getMessage() - ); - }, E_USER_DEPRECATED); - } -} diff --git a/vendor/textalk/websocket/tests/bootstrap.php b/vendor/textalk/websocket/tests/bootstrap.php deleted file mode 100644 index 5d6bdd0..0000000 --- a/vendor/textalk/websocket/tests/bootstrap.php +++ /dev/null @@ -1,6 +0,0 @@ -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); - } -} diff --git a/vendor/textalk/websocket/tests/mock/MockSocket.php b/vendor/textalk/websocket/tests/mock/MockSocket.php deleted file mode 100644 index e96806b..0000000 --- a/vendor/textalk/websocket/tests/mock/MockSocket.php +++ /dev/null @@ -1,81 +0,0 @@ -assertEquals($current['function'], $function); - foreach ($current['params'] as $index => $param) { - if (isset($current['input-op'])) { - $param = self::op($current['input-op'], $params, $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 str_replace('{key}', self::$stored['sec-websocket-key'], $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; - } -} diff --git a/vendor/textalk/websocket/tests/mock/mock-socket.php b/vendor/textalk/websocket/tests/mock/mock-socket.php deleted file mode 100644 index a038933..0000000 --- a/vendor/textalk/websocket/tests/mock/mock-socket.php +++ /dev/null @@ -1,83 +0,0 @@ -