chore: initial commit
This commit is contained in:
25
api/vendor/autoload.php
vendored
Normal file
25
api/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit1e8acb631b5eb892a9e950c179a2be67::getLoader();
|
||||
585
api/vendor/composer/ClassLoader.php
vendored
Normal file
585
api/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,585 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* 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 <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @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 */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @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 string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $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 string[]|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)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $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] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $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 string[]|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 string[]|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 indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
352
api/vendor/composer/InstalledVersions.php
vendored
Normal file
352
api/vendor/composer/InstalledVersions.php
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* 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<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
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<string>
|
||||
*/
|
||||
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<string>
|
||||
*/
|
||||
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 || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
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($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<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
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<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
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<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
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')) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
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') {
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
21
api/vendor/composer/LICENSE
vendored
Normal file
21
api/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
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.
|
||||
|
||||
11
api/vendor/composer/autoload_classmap.php
vendored
Normal file
11
api/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php',
|
||||
);
|
||||
10
api/vendor/composer/autoload_files.php
vendored
Normal file
10
api/vendor/composer/autoload_files.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'941748b3c8cae4466c827dfb5ca9602a' => $vendorDir . '/rmccue/requests/library/Deprecated.php',
|
||||
);
|
||||
9
api/vendor/composer/autoload_namespaces.php
vendored
Normal file
9
api/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
11
api/vendor/composer/autoload_psr4.php
vendored
Normal file
11
api/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'WpOrg\\Requests\\' => array($vendorDir . '/rmccue/requests/src'),
|
||||
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
|
||||
);
|
||||
50
api/vendor/composer/autoload_real.php
vendored
Normal file
50
api/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit1e8acb631b5eb892a9e950c179a2be67
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit1e8acb631b5eb892a9e950c179a2be67', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit1e8acb631b5eb892a9e950c179a2be67', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
49
api/vendor/composer/autoload_static.php
vendored
Normal file
49
api/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67
|
||||
{
|
||||
public static $files = array (
|
||||
'941748b3c8cae4466c827dfb5ca9602a' => __DIR__ . '/..' . '/rmccue/requests/library/Deprecated.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'W' =>
|
||||
array (
|
||||
'WpOrg\\Requests\\' => 15,
|
||||
),
|
||||
'F' =>
|
||||
array (
|
||||
'Firebase\\JWT\\' => 13,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'WpOrg\\Requests\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/rmccue/requests/src',
|
||||
),
|
||||
'Firebase\\JWT\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'Requests' => __DIR__ . '/..' . '/rmccue/requests/library/Requests.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit1e8acb631b5eb892a9e950c179a2be67::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
156
api/vendor/composer/installed.json
vendored
Normal file
156
api/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.4.0",
|
||||
"version_normalized": "6.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
|
||||
"reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1||^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^7.5||^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"time": "2023-02-09T21:01:23+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.4.0"
|
||||
},
|
||||
"install-path": "../firebase/php-jwt"
|
||||
},
|
||||
{
|
||||
"name": "rmccue/requests",
|
||||
"version": "v2.0.5",
|
||||
"version_normalized": "2.0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/WordPress/Requests.git",
|
||||
"reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/WordPress/Requests/zipball/b717f1d2f4ef7992ec0c127747ed8b7e170c2f49",
|
||||
"reference": "b717f1d2f4ef7992ec0c127747ed8b7e170c2f49",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
|
||||
"php-parallel-lint/php-console-highlighter": "^0.5.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
||||
"phpcompatibility/php-compatibility": "^9.0",
|
||||
"requests/test-server": "dev-main",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"wp-coding-standards/wpcs": "^2.0",
|
||||
"yoast/phpunit-polyfills": "^1.0.0"
|
||||
},
|
||||
"time": "2022-10-11T08:15:28+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"library/Deprecated.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"WpOrg\\Requests\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"library/Requests.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"ISC"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ryan McCue",
|
||||
"homepage": "https://rmccue.io/"
|
||||
},
|
||||
{
|
||||
"name": "Alain Schlesser",
|
||||
"homepage": "https://github.com/schlessera"
|
||||
},
|
||||
{
|
||||
"name": "Juliette Reinders Folmer",
|
||||
"homepage": "https://github.com/jrfnl"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/WordPress/Requests/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A HTTP library written in PHP, for human beings.",
|
||||
"homepage": "https://requests.ryanmccue.info/",
|
||||
"keywords": [
|
||||
"curl",
|
||||
"fsockopen",
|
||||
"http",
|
||||
"idna",
|
||||
"ipv6",
|
||||
"iri",
|
||||
"sockets"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://requests.ryanmccue.info/",
|
||||
"issues": "https://github.com/WordPress/Requests/issues",
|
||||
"source": "https://github.com/WordPress/Requests"
|
||||
},
|
||||
"install-path": "../rmccue/requests"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
41
api/vendor/composer/installed.php
vendored
Normal file
41
api/vendor/composer/installed.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '50e68fa48bd98d995d6e3abd8c2a250664a496c9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '50e68fa48bd98d995d6e3abd8c2a250664a496c9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'firebase/php-jwt' => array(
|
||||
'pretty_version' => 'v6.4.0',
|
||||
'version' => '6.4.0.0',
|
||||
'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'rmccue/requests' => array(
|
||||
'pretty_version' => 'v2.0.5',
|
||||
'version' => '2.0.5.0',
|
||||
'reference' => 'b717f1d2f4ef7992ec0c127747ed8b7e170c2f49',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../rmccue/requests',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
26
api/vendor/composer/platform_check.php
vendored
Normal file
26
api/vendor/composer/platform_check.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70100)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.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
|
||||
);
|
||||
}
|
||||
105
api/vendor/firebase/php-jwt/CHANGELOG.md
vendored
Normal file
105
api/vendor/firebase/php-jwt/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# Changelog
|
||||
|
||||
## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95))
|
||||
* improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c))
|
||||
|
||||
## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd))
|
||||
|
||||
## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22))
|
||||
* string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2))
|
||||
|
||||
## 6.3.0 / 2022-07-15
|
||||
|
||||
- Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399))
|
||||
- Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435))
|
||||
|
||||
## 6.2.0 / 2022-05-14
|
||||
|
||||
- Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397))
|
||||
- Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)).
|
||||
|
||||
## 6.1.0 / 2022-03-23
|
||||
|
||||
- Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0
|
||||
- Add parameter typing and return types where possible
|
||||
|
||||
## 6.0.0 / 2022-01-24
|
||||
|
||||
- **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information.
|
||||
- New Key object to prevent key/algorithm type confusion (#365)
|
||||
- Add JWK support (#273)
|
||||
- Add ES256 support (#256)
|
||||
- Add ES384 support (#324)
|
||||
- Add Ed25519 support (#343)
|
||||
|
||||
## 5.0.0 / 2017-06-26
|
||||
- Support RS384 and RS512.
|
||||
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
|
||||
- Add an example for RS256 openssl.
|
||||
See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)!
|
||||
- Detect invalid Base64 encoding in signature.
|
||||
See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)!
|
||||
- Update `JWT::verify` to handle OpenSSL errors.
|
||||
See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)!
|
||||
- Add `array` type hinting to `decode` method
|
||||
See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)!
|
||||
- Add all JSON error types.
|
||||
See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)!
|
||||
- Bugfix 'kid' not in given key list.
|
||||
See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)!
|
||||
- Miscellaneous cleanup, documentation and test fixes.
|
||||
See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115),
|
||||
[#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and
|
||||
[#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman),
|
||||
[@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)!
|
||||
|
||||
## 4.0.0 / 2016-07-17
|
||||
- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)!
|
||||
- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)!
|
||||
- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)!
|
||||
- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)!
|
||||
|
||||
## 3.0.0 / 2015-07-22
|
||||
- Minimum PHP version updated from `5.2.0` to `5.3.0`.
|
||||
- Add `\Firebase\JWT` namespace. See
|
||||
[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
|
||||
[@Dashron](https://github.com/Dashron)!
|
||||
- Require a non-empty key to decode and verify a JWT. See
|
||||
[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
|
||||
[@sjones608](https://github.com/sjones608)!
|
||||
- Cleaner documentation blocks in the code. See
|
||||
[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
|
||||
[@johanderuijter](https://github.com/johanderuijter)!
|
||||
|
||||
## 2.2.0 / 2015-06-22
|
||||
- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
|
||||
[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
|
||||
[@mcocaro](https://github.com/mcocaro)!
|
||||
|
||||
## 2.1.0 / 2015-05-20
|
||||
- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
|
||||
between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
|
||||
- Add support for passing an object implementing the `ArrayAccess` interface for
|
||||
`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
|
||||
|
||||
## 2.0.0 / 2015-04-01
|
||||
- **Note**: It is strongly recommended that you update to > v2.0.0 to address
|
||||
known security vulnerabilities in prior versions when both symmetric and
|
||||
asymmetric keys are used together.
|
||||
- Update signature for `JWT::decode(...)` to require an array of supported
|
||||
algorithms to use when verifying token signatures.
|
||||
30
api/vendor/firebase/php-jwt/LICENSE
vendored
Normal file
30
api/vendor/firebase/php-jwt/LICENSE
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
Copyright (c) 2011, Neuman Vong
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
332
api/vendor/firebase/php-jwt/README.md
vendored
Normal file
332
api/vendor/firebase/php-jwt/README.md
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||

|
||||
[](https://packagist.org/packages/firebase/php-jwt)
|
||||
[](https://packagist.org/packages/firebase/php-jwt)
|
||||
[](https://packagist.org/packages/firebase/php-jwt)
|
||||
|
||||
PHP-JWT
|
||||
=======
|
||||
A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519).
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Use composer to manage your dependencies and download PHP-JWT:
|
||||
|
||||
```bash
|
||||
composer require firebase/php-jwt
|
||||
```
|
||||
|
||||
Optionally, install the `paragonie/sodium_compat` package from composer if your
|
||||
php is < 7.2 or does not have libsodium installed:
|
||||
|
||||
```bash
|
||||
composer require paragonie/sodium_compat
|
||||
```
|
||||
|
||||
Example
|
||||
-------
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
$key = 'example_key';
|
||||
$payload = [
|
||||
'iss' => 'http://example.org',
|
||||
'aud' => 'http://example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
/**
|
||||
* IMPORTANT:
|
||||
* You must specify supported algorithms for your application. See
|
||||
* https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
|
||||
* for a list of spec-compliant algorithms.
|
||||
*/
|
||||
$jwt = JWT::encode($payload, $key, 'HS256');
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
|
||||
print_r($decoded);
|
||||
|
||||
/*
|
||||
NOTE: This will now be an object instead of an associative array. To get
|
||||
an associative array, you will need to cast it as such:
|
||||
*/
|
||||
|
||||
$decoded_array = (array) $decoded;
|
||||
|
||||
/**
|
||||
* You can add a leeway to account for when there is a clock skew times between
|
||||
* the signing and verifying servers. It is recommended that this leeway should
|
||||
* not be bigger than a few minutes.
|
||||
*
|
||||
* Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
|
||||
*/
|
||||
JWT::$leeway = 60; // $leeway in seconds
|
||||
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
|
||||
```
|
||||
Example with RS256 (openssl)
|
||||
----------------------------
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
$privateKey = <<<EOD
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn
|
||||
vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9
|
||||
5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB
|
||||
AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz
|
||||
bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J
|
||||
Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1
|
||||
cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5
|
||||
5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck
|
||||
ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe
|
||||
k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb
|
||||
qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k
|
||||
eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm
|
||||
B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
EOD;
|
||||
|
||||
$publicKey = <<<EOD
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
|
||||
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
|
||||
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
|
||||
ehde/zUxo6UvS7UrBQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
EOD;
|
||||
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
|
||||
$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
|
||||
|
||||
/*
|
||||
NOTE: This will now be an object instead of an associative array. To get
|
||||
an associative array, you will need to cast it as such:
|
||||
*/
|
||||
|
||||
$decoded_array = (array) $decoded;
|
||||
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
|
||||
```
|
||||
|
||||
Example with a passphrase
|
||||
-------------------------
|
||||
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
// Your passphrase
|
||||
$passphrase = '[YOUR_PASSPHRASE]';
|
||||
|
||||
// Your private key file with passphrase
|
||||
// Can be generated with "ssh-keygen -t rsa -m pem"
|
||||
$privateKeyFile = '/path/to/key-with-passphrase.pem';
|
||||
|
||||
// Create a private key of type "resource"
|
||||
$privateKey = openssl_pkey_get_private(
|
||||
file_get_contents($privateKeyFile),
|
||||
$passphrase
|
||||
);
|
||||
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
|
||||
// Get public key from the private key, or pull from from a file.
|
||||
$publicKey = openssl_pkey_get_details($privateKey)['key'];
|
||||
|
||||
$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
|
||||
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
|
||||
```
|
||||
|
||||
Example with EdDSA (libsodium and Ed25519 signature)
|
||||
----------------------------
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
|
||||
// Public and private keys are expected to be Base64 encoded. The last
|
||||
// non-empty line is used so that keys can be generated with
|
||||
// sodium_crypto_sign_keypair(). The secret keys generated by other tools may
|
||||
// need to be adjusted to match the input expected by libsodium.
|
||||
|
||||
$keyPair = sodium_crypto_sign_keypair();
|
||||
|
||||
$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
|
||||
|
||||
$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
|
||||
|
||||
$payload = [
|
||||
'iss' => 'example.org',
|
||||
'aud' => 'example.com',
|
||||
'iat' => 1356999524,
|
||||
'nbf' => 1357000000
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
|
||||
echo "Encode:\n" . print_r($jwt, true) . "\n";
|
||||
|
||||
$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
|
||||
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
|
||||
````
|
||||
|
||||
Using JWKs
|
||||
----------
|
||||
|
||||
```php
|
||||
use Firebase\JWT\JWK;
|
||||
use Firebase\JWT\JWT;
|
||||
|
||||
// Set of keys. The "keys" key is required. For example, the JSON response to
|
||||
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
|
||||
$jwks = ['keys' => []];
|
||||
|
||||
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
|
||||
// objects. Pass this as the second parameter to JWT::decode.
|
||||
JWT::decode($payload, JWK::parseKeySet($jwks));
|
||||
```
|
||||
|
||||
Using Cached Key Sets
|
||||
---------------------
|
||||
|
||||
The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI.
|
||||
This has the following advantages:
|
||||
|
||||
1. The results are cached for performance.
|
||||
2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
|
||||
3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.
|
||||
|
||||
```php
|
||||
use Firebase\JWT\CachedKeySet;
|
||||
use Firebase\JWT\JWT;
|
||||
|
||||
// The URI for the JWKS you wish to cache the results from
|
||||
$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';
|
||||
|
||||
// Create an HTTP client (can be any PSR-7 compatible HTTP client)
|
||||
$httpClient = new GuzzleHttp\Client();
|
||||
|
||||
// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
|
||||
$httpFactory = new GuzzleHttp\Psr\HttpFactory();
|
||||
|
||||
// Create a cache item pool (can be any PSR-6 compatible cache item pool)
|
||||
$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');
|
||||
|
||||
$keySet = new CachedKeySet(
|
||||
$jwksUri,
|
||||
$httpClient,
|
||||
$httpFactory,
|
||||
$cacheItemPool,
|
||||
null, // $expiresAfter int seconds to set the JWKS to expire
|
||||
true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys
|
||||
);
|
||||
|
||||
$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
|
||||
$decoded = JWT::decode($jwt, $keySet);
|
||||
```
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
#### Exception Handling
|
||||
|
||||
When a call to `JWT::decode` is invalid, it will throw one of the following exceptions:
|
||||
|
||||
```php
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\SignatureInvalidException;
|
||||
use Firebase\JWT\BeforeValidException;
|
||||
use Firebase\JWT\ExpiredException;
|
||||
use DomainException;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
// provided key/key-array is empty or malformed.
|
||||
} catch (DomainException $e) {
|
||||
// provided algorithm is unsupported OR
|
||||
// provided key is invalid OR
|
||||
// unknown error thrown in openSSL or libsodium OR
|
||||
// libsodium is required but not available.
|
||||
} catch (SignatureInvalidException $e) {
|
||||
// provided JWT signature verification failed.
|
||||
} catch (BeforeValidException $e) {
|
||||
// provided JWT is trying to be used before "nbf" claim OR
|
||||
// provided JWT is trying to be used before "iat" claim.
|
||||
} catch (ExpiredException $e) {
|
||||
// provided JWT is trying to be used after "exp" claim.
|
||||
} catch (UnexpectedValueException $e) {
|
||||
// provided JWT is malformed OR
|
||||
// provided JWT is missing an algorithm / using an unsupported algorithm OR
|
||||
// provided JWT algorithm does not match provided key OR
|
||||
// provided key ID in key/key-array is empty or invalid.
|
||||
}
|
||||
```
|
||||
|
||||
All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified
|
||||
like this:
|
||||
|
||||
```php
|
||||
try {
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
} catch (LogicException $e) {
|
||||
// errors having to do with environmental setup or malformed JWT Keys
|
||||
} catch (UnexpectedValueException $e) {
|
||||
// errors having to do with JWT signature and claims
|
||||
}
|
||||
```
|
||||
|
||||
#### Casting to array
|
||||
|
||||
The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays
|
||||
instead, you can do the following:
|
||||
|
||||
```php
|
||||
// return type is stdClass
|
||||
$decoded = JWT::decode($payload, $keys);
|
||||
|
||||
// cast to array
|
||||
$decoded = json_decode(json_encode($decoded), true);
|
||||
```
|
||||
|
||||
Tests
|
||||
-----
|
||||
Run the tests using phpunit:
|
||||
|
||||
```bash
|
||||
$ pear install PHPUnit
|
||||
$ phpunit --configuration phpunit.xml.dist
|
||||
PHPUnit 3.7.10 by Sebastian Bergmann.
|
||||
.....
|
||||
Time: 0 seconds, Memory: 2.50Mb
|
||||
OK (5 tests, 5 assertions)
|
||||
```
|
||||
|
||||
New Lines in private keys
|
||||
-----
|
||||
|
||||
If your private key contains `\n` characters, be sure to wrap it in double quotes `""`
|
||||
and not single quotes `''` in order to properly interpret the escaped characters.
|
||||
|
||||
License
|
||||
-------
|
||||
[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause).
|
||||
42
api/vendor/firebase/php-jwt/composer.json
vendored
Normal file
42
api/vendor/firebase/php-jwt/composer.json
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"php",
|
||||
"jwt"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"require": {
|
||||
"php": "^7.1||^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||
"phpspec/prophecy-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^7.5||^9.5",
|
||||
"psr/cache": "^1.0||^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
}
|
||||
}
|
||||
7
api/vendor/firebase/php-jwt/src/BeforeValidException.php
vendored
Normal file
7
api/vendor/firebase/php-jwt/src/BeforeValidException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
class BeforeValidException extends \UnexpectedValueException
|
||||
{
|
||||
}
|
||||
258
api/vendor/firebase/php-jwt/src/CachedKeySet.php
vendored
Normal file
258
api/vendor/firebase/php-jwt/src/CachedKeySet.php
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
use ArrayAccess;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use OutOfBoundsException;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* @implements ArrayAccess<string, Key>
|
||||
*/
|
||||
class CachedKeySet implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $jwksUri;
|
||||
/**
|
||||
* @var ClientInterface
|
||||
*/
|
||||
private $httpClient;
|
||||
/**
|
||||
* @var RequestFactoryInterface
|
||||
*/
|
||||
private $httpFactory;
|
||||
/**
|
||||
* @var CacheItemPoolInterface
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
private $expiresAfter;
|
||||
/**
|
||||
* @var ?CacheItemInterface
|
||||
*/
|
||||
private $cacheItem;
|
||||
/**
|
||||
* @var array<string, array<mixed>>
|
||||
*/
|
||||
private $keySet;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheKey;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheKeyPrefix = 'jwks';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxKeyLength = 64;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $rateLimit;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rateLimitCacheKey;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxCallsPerMinute = 10;
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $defaultAlg;
|
||||
|
||||
public function __construct(
|
||||
string $jwksUri,
|
||||
ClientInterface $httpClient,
|
||||
RequestFactoryInterface $httpFactory,
|
||||
CacheItemPoolInterface $cache,
|
||||
int $expiresAfter = null,
|
||||
bool $rateLimit = false,
|
||||
string $defaultAlg = null
|
||||
) {
|
||||
$this->jwksUri = $jwksUri;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->httpFactory = $httpFactory;
|
||||
$this->cache = $cache;
|
||||
$this->expiresAfter = $expiresAfter;
|
||||
$this->rateLimit = $rateLimit;
|
||||
$this->defaultAlg = $defaultAlg;
|
||||
$this->setCacheKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @return Key
|
||||
*/
|
||||
public function offsetGet($keyId): Key
|
||||
{
|
||||
if (!$this->keyIdExists($keyId)) {
|
||||
throw new OutOfBoundsException('Key ID not found');
|
||||
}
|
||||
return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($keyId): bool
|
||||
{
|
||||
return $this->keyIdExists($keyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset
|
||||
* @param Key $value
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
throw new LogicException('Method not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
throw new LogicException('Method not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
private function formatJwksForCache(string $jwks): array
|
||||
{
|
||||
$jwks = json_decode($jwks, true);
|
||||
|
||||
if (!isset($jwks['keys'])) {
|
||||
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
|
||||
}
|
||||
|
||||
if (empty($jwks['keys'])) {
|
||||
throw new InvalidArgumentException('JWK Set did not contain any keys');
|
||||
}
|
||||
|
||||
$keys = [];
|
||||
foreach ($jwks['keys'] as $k => $v) {
|
||||
$kid = isset($v['kid']) ? $v['kid'] : $k;
|
||||
$keys[(string) $kid] = $v;
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
private function keyIdExists(string $keyId): bool
|
||||
{
|
||||
if (null === $this->keySet) {
|
||||
$item = $this->getCacheItem();
|
||||
// Try to load keys from cache
|
||||
if ($item->isHit()) {
|
||||
// item found! retrieve it
|
||||
$this->keySet = $item->get();
|
||||
// If the cached item is a string, the JWKS response was cached (previous behavior).
|
||||
// Parse this into expected format array<kid, jwk> instead.
|
||||
if (\is_string($this->keySet)) {
|
||||
$this->keySet = $this->formatJwksForCache($this->keySet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->keySet[$keyId])) {
|
||||
if ($this->rateLimitExceeded()) {
|
||||
return false;
|
||||
}
|
||||
$request = $this->httpFactory->createRequest('GET', $this->jwksUri);
|
||||
$jwksResponse = $this->httpClient->sendRequest($request);
|
||||
$this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody());
|
||||
|
||||
if (!isset($this->keySet[$keyId])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item = $this->getCacheItem();
|
||||
$item->set($this->keySet);
|
||||
if ($this->expiresAfter) {
|
||||
$item->expiresAfter($this->expiresAfter);
|
||||
}
|
||||
$this->cache->save($item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function rateLimitExceeded(): bool
|
||||
{
|
||||
if (!$this->rateLimit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
|
||||
if (!$cacheItem->isHit()) {
|
||||
$cacheItem->expiresAfter(1); // # of calls are cached each minute
|
||||
}
|
||||
|
||||
$callsPerMinute = (int) $cacheItem->get();
|
||||
if (++$callsPerMinute > $this->maxCallsPerMinute) {
|
||||
return true;
|
||||
}
|
||||
$cacheItem->set($callsPerMinute);
|
||||
$this->cache->save($cacheItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getCacheItem(): CacheItemInterface
|
||||
{
|
||||
if (\is_null($this->cacheItem)) {
|
||||
$this->cacheItem = $this->cache->getItem($this->cacheKey);
|
||||
}
|
||||
|
||||
return $this->cacheItem;
|
||||
}
|
||||
|
||||
private function setCacheKeys(): void
|
||||
{
|
||||
if (empty($this->jwksUri)) {
|
||||
throw new RuntimeException('JWKS URI is empty');
|
||||
}
|
||||
|
||||
// ensure we do not have illegal characters
|
||||
$key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri);
|
||||
|
||||
// add prefix
|
||||
$key = $this->cacheKeyPrefix . $key;
|
||||
|
||||
// Hash keys if they exceed $maxKeyLength of 64
|
||||
if (\strlen($key) > $this->maxKeyLength) {
|
||||
$key = substr(hash('sha256', $key), 0, $this->maxKeyLength);
|
||||
}
|
||||
|
||||
$this->cacheKey = $key;
|
||||
|
||||
if ($this->rateLimit) {
|
||||
// add prefix
|
||||
$rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key;
|
||||
|
||||
// Hash keys if they exceed $maxKeyLength of 64
|
||||
if (\strlen($rateLimitKey) > $this->maxKeyLength) {
|
||||
$rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength);
|
||||
}
|
||||
|
||||
$this->rateLimitCacheKey = $rateLimitKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
7
api/vendor/firebase/php-jwt/src/ExpiredException.php
vendored
Normal file
7
api/vendor/firebase/php-jwt/src/ExpiredException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
class ExpiredException extends \UnexpectedValueException
|
||||
{
|
||||
}
|
||||
323
api/vendor/firebase/php-jwt/src/JWK.php
vendored
Normal file
323
api/vendor/firebase/php-jwt/src/JWK.php
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
use DomainException;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* JSON Web Key implementation, based on this spec:
|
||||
* https://tools.ietf.org/html/draft-ietf-jose-json-web-key-41
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Authentication
|
||||
* @package Authentication_JWT
|
||||
* @author Bui Sy Nguyen <nguyenbs@gmail.com>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
|
||||
* @link https://github.com/firebase/php-jwt
|
||||
*/
|
||||
class JWK
|
||||
{
|
||||
private const OID = '1.2.840.10045.2.1';
|
||||
private const ASN1_OBJECT_IDENTIFIER = 0x06;
|
||||
private const ASN1_SEQUENCE = 0x10; // also defined in JWT
|
||||
private const ASN1_BIT_STRING = 0x03;
|
||||
private const EC_CURVES = [
|
||||
'P-256' => '1.2.840.10045.3.1.7', // Len: 64
|
||||
'secp256k1' => '1.3.132.0.10', // Len: 64
|
||||
// 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported)
|
||||
// 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
|
||||
];
|
||||
|
||||
/**
|
||||
* Parse a set of JWK keys
|
||||
*
|
||||
* @param array<mixed> $jwks The JSON Web Key Set as an associative array
|
||||
* @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
|
||||
* JSON Web Key Set
|
||||
*
|
||||
* @return array<string, Key> An associative array of key IDs (kid) to Key objects
|
||||
*
|
||||
* @throws InvalidArgumentException Provided JWK Set is empty
|
||||
* @throws UnexpectedValueException Provided JWK Set was invalid
|
||||
* @throws DomainException OpenSSL failure
|
||||
*
|
||||
* @uses parseKey
|
||||
*/
|
||||
public static function parseKeySet(array $jwks, string $defaultAlg = null): array
|
||||
{
|
||||
$keys = [];
|
||||
|
||||
if (!isset($jwks['keys'])) {
|
||||
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
|
||||
}
|
||||
|
||||
if (empty($jwks['keys'])) {
|
||||
throw new InvalidArgumentException('JWK Set did not contain any keys');
|
||||
}
|
||||
|
||||
foreach ($jwks['keys'] as $k => $v) {
|
||||
$kid = isset($v['kid']) ? $v['kid'] : $k;
|
||||
if ($key = self::parseKey($v, $defaultAlg)) {
|
||||
$keys[(string) $kid] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === \count($keys)) {
|
||||
throw new UnexpectedValueException('No supported algorithms found in JWK Set');
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JWK key
|
||||
*
|
||||
* @param array<mixed> $jwk An individual JWK
|
||||
* @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
|
||||
* JSON Web Key Set
|
||||
*
|
||||
* @return Key The key object for the JWK
|
||||
*
|
||||
* @throws InvalidArgumentException Provided JWK is empty
|
||||
* @throws UnexpectedValueException Provided JWK was invalid
|
||||
* @throws DomainException OpenSSL failure
|
||||
*
|
||||
* @uses createPemFromModulusAndExponent
|
||||
*/
|
||||
public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
|
||||
{
|
||||
if (empty($jwk)) {
|
||||
throw new InvalidArgumentException('JWK must not be empty');
|
||||
}
|
||||
|
||||
if (!isset($jwk['kty'])) {
|
||||
throw new UnexpectedValueException('JWK must contain a "kty" parameter');
|
||||
}
|
||||
|
||||
if (!isset($jwk['alg'])) {
|
||||
if (\is_null($defaultAlg)) {
|
||||
// The "alg" parameter is optional in a KTY, but an algorithm is required
|
||||
// for parsing in this library. Use the $defaultAlg parameter when parsing the
|
||||
// key set in order to prevent this error.
|
||||
// @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
|
||||
throw new UnexpectedValueException('JWK must contain an "alg" parameter');
|
||||
}
|
||||
$jwk['alg'] = $defaultAlg;
|
||||
}
|
||||
|
||||
switch ($jwk['kty']) {
|
||||
case 'RSA':
|
||||
if (!empty($jwk['d'])) {
|
||||
throw new UnexpectedValueException('RSA private keys are not supported');
|
||||
}
|
||||
if (!isset($jwk['n']) || !isset($jwk['e'])) {
|
||||
throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"');
|
||||
}
|
||||
|
||||
$pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']);
|
||||
$publicKey = \openssl_pkey_get_public($pem);
|
||||
if (false === $publicKey) {
|
||||
throw new DomainException(
|
||||
'OpenSSL error: ' . \openssl_error_string()
|
||||
);
|
||||
}
|
||||
return new Key($publicKey, $jwk['alg']);
|
||||
case 'EC':
|
||||
if (isset($jwk['d'])) {
|
||||
// The key is actually a private key
|
||||
throw new UnexpectedValueException('Key data must be for a public key');
|
||||
}
|
||||
|
||||
if (empty($jwk['crv'])) {
|
||||
throw new UnexpectedValueException('crv not set');
|
||||
}
|
||||
|
||||
if (!isset(self::EC_CURVES[$jwk['crv']])) {
|
||||
throw new DomainException('Unrecognised or unsupported EC curve');
|
||||
}
|
||||
|
||||
if (empty($jwk['x']) || empty($jwk['y'])) {
|
||||
throw new UnexpectedValueException('x and y not set');
|
||||
}
|
||||
|
||||
$publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']);
|
||||
return new Key($publicKey, $jwk['alg']);
|
||||
default:
|
||||
// Currently only RSA is supported
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the EC JWK values to pem format.
|
||||
*
|
||||
* @param string $crv The EC curve (only P-256 is supported)
|
||||
* @param string $x The EC x-coordinate
|
||||
* @param string $y The EC y-coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string
|
||||
{
|
||||
$pem =
|
||||
self::encodeDER(
|
||||
self::ASN1_SEQUENCE,
|
||||
self::encodeDER(
|
||||
self::ASN1_SEQUENCE,
|
||||
self::encodeDER(
|
||||
self::ASN1_OBJECT_IDENTIFIER,
|
||||
self::encodeOID(self::OID)
|
||||
)
|
||||
. self::encodeDER(
|
||||
self::ASN1_OBJECT_IDENTIFIER,
|
||||
self::encodeOID(self::EC_CURVES[$crv])
|
||||
)
|
||||
) .
|
||||
self::encodeDER(
|
||||
self::ASN1_BIT_STRING,
|
||||
\chr(0x00) . \chr(0x04)
|
||||
. JWT::urlsafeB64Decode($x)
|
||||
. JWT::urlsafeB64Decode($y)
|
||||
)
|
||||
);
|
||||
|
||||
return sprintf(
|
||||
"-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n",
|
||||
wordwrap(base64_encode($pem), 64, "\n", true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a public key represented in PEM format from RSA modulus and exponent information
|
||||
*
|
||||
* @param string $n The RSA modulus encoded in Base64
|
||||
* @param string $e The RSA exponent encoded in Base64
|
||||
*
|
||||
* @return string The RSA public key represented in PEM format
|
||||
*
|
||||
* @uses encodeLength
|
||||
*/
|
||||
private static function createPemFromModulusAndExponent(
|
||||
string $n,
|
||||
string $e
|
||||
): string {
|
||||
$mod = JWT::urlsafeB64Decode($n);
|
||||
$exp = JWT::urlsafeB64Decode($e);
|
||||
|
||||
$modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod);
|
||||
$publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp);
|
||||
|
||||
$rsaPublicKey = \pack(
|
||||
'Ca*a*a*',
|
||||
48,
|
||||
self::encodeLength(\strlen($modulus) + \strlen($publicExponent)),
|
||||
$modulus,
|
||||
$publicExponent
|
||||
);
|
||||
|
||||
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
|
||||
$rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$rsaPublicKey = \chr(0) . $rsaPublicKey;
|
||||
$rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey;
|
||||
|
||||
$rsaPublicKey = \pack(
|
||||
'Ca*a*',
|
||||
48,
|
||||
self::encodeLength(\strlen($rsaOID . $rsaPublicKey)),
|
||||
$rsaOID . $rsaPublicKey
|
||||
);
|
||||
|
||||
return "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
\chunk_split(\base64_encode($rsaPublicKey), 64) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-encode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private static function encodeLength(int $length): string
|
||||
{
|
||||
if ($length <= 0x7F) {
|
||||
return \chr($length);
|
||||
}
|
||||
|
||||
$temp = \ltrim(\pack('N', $length), \chr(0));
|
||||
|
||||
return \pack('Ca*', 0x80 | \strlen($temp), $temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a value into a DER object.
|
||||
* Also defined in Firebase\JWT\JWT
|
||||
*
|
||||
* @param int $type DER tag
|
||||
* @param string $value the value to encode
|
||||
* @return string the encoded object
|
||||
*/
|
||||
private static function encodeDER(int $type, string $value): string
|
||||
{
|
||||
$tag_header = 0;
|
||||
if ($type === self::ASN1_SEQUENCE) {
|
||||
$tag_header |= 0x20;
|
||||
}
|
||||
|
||||
// Type
|
||||
$der = \chr($tag_header | $type);
|
||||
|
||||
// Length
|
||||
$der .= \chr(\strlen($value));
|
||||
|
||||
return $der . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a string into a DER-encoded OID.
|
||||
*
|
||||
* @param string $oid the OID string
|
||||
* @return string the binary DER-encoded OID
|
||||
*/
|
||||
private static function encodeOID(string $oid): string
|
||||
{
|
||||
$octets = explode('.', $oid);
|
||||
|
||||
// Get the first octet
|
||||
$first = (int) array_shift($octets);
|
||||
$second = (int) array_shift($octets);
|
||||
$oid = \chr($first * 40 + $second);
|
||||
|
||||
// Iterate over subsequent octets
|
||||
foreach ($octets as $octet) {
|
||||
if ($octet == 0) {
|
||||
$oid .= \chr(0x00);
|
||||
continue;
|
||||
}
|
||||
$bin = '';
|
||||
|
||||
while ($octet) {
|
||||
$bin .= \chr(0x80 | ($octet & 0x7f));
|
||||
$octet >>= 7;
|
||||
}
|
||||
$bin[0] = $bin[0] & \chr(0x7f);
|
||||
|
||||
// Convert to big endian if necessary
|
||||
if (pack('V', 65534) == pack('L', 65534)) {
|
||||
$oid .= strrev($bin);
|
||||
} else {
|
||||
$oid .= $bin;
|
||||
}
|
||||
}
|
||||
|
||||
return $oid;
|
||||
}
|
||||
}
|
||||
638
api/vendor/firebase/php-jwt/src/JWT.php
vendored
Normal file
638
api/vendor/firebase/php-jwt/src/JWT.php
vendored
Normal file
@@ -0,0 +1,638 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
use ArrayAccess;
|
||||
use DateTime;
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use OpenSSLAsymmetricKey;
|
||||
use OpenSSLCertificate;
|
||||
use stdClass;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* JSON Web Token implementation, based on this spec:
|
||||
* https://tools.ietf.org/html/rfc7519
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Authentication
|
||||
* @package Authentication_JWT
|
||||
* @author Neuman Vong <neuman@twilio.com>
|
||||
* @author Anant Narayanan <anant@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
|
||||
* @link https://github.com/firebase/php-jwt
|
||||
*/
|
||||
class JWT
|
||||
{
|
||||
private const ASN1_INTEGER = 0x02;
|
||||
private const ASN1_SEQUENCE = 0x10;
|
||||
private const ASN1_BIT_STRING = 0x03;
|
||||
|
||||
/**
|
||||
* When checking nbf, iat or expiration times,
|
||||
* we want to provide some extra leeway time to
|
||||
* account for clock skew.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $leeway = 0;
|
||||
|
||||
/**
|
||||
* Allow the current timestamp to be specified.
|
||||
* Useful for fixing a value within unit testing.
|
||||
* Will default to PHP time() value if null.
|
||||
*
|
||||
* @var ?int
|
||||
*/
|
||||
public static $timestamp = null;
|
||||
|
||||
/**
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
public static $supported_algs = [
|
||||
'ES384' => ['openssl', 'SHA384'],
|
||||
'ES256' => ['openssl', 'SHA256'],
|
||||
'ES256K' => ['openssl', 'SHA256'],
|
||||
'HS256' => ['hash_hmac', 'SHA256'],
|
||||
'HS384' => ['hash_hmac', 'SHA384'],
|
||||
'HS512' => ['hash_hmac', 'SHA512'],
|
||||
'RS256' => ['openssl', 'SHA256'],
|
||||
'RS384' => ['openssl', 'SHA384'],
|
||||
'RS512' => ['openssl', 'SHA512'],
|
||||
'EdDSA' => ['sodium_crypto', 'EdDSA'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Decodes a JWT string into a PHP object.
|
||||
*
|
||||
* @param string $jwt The JWT
|
||||
* @param Key|array<string,Key> $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects.
|
||||
* If the algorithm used is asymmetric, this is the public key
|
||||
* Each Key object contains an algorithm and matching key.
|
||||
* Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
|
||||
* 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||
*
|
||||
* @return stdClass The JWT's payload as a PHP object
|
||||
*
|
||||
* @throws InvalidArgumentException Provided key/key-array was empty or malformed
|
||||
* @throws DomainException Provided JWT is malformed
|
||||
* @throws UnexpectedValueException Provided JWT was invalid
|
||||
* @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
|
||||
* @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
|
||||
* @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat'
|
||||
* @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim
|
||||
*
|
||||
* @uses jsonDecode
|
||||
* @uses urlsafeB64Decode
|
||||
*/
|
||||
public static function decode(
|
||||
string $jwt,
|
||||
$keyOrKeyArray
|
||||
): stdClass {
|
||||
// Validate JWT
|
||||
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
|
||||
|
||||
if (empty($keyOrKeyArray)) {
|
||||
throw new InvalidArgumentException('Key may not be empty');
|
||||
}
|
||||
$tks = \explode('.', $jwt);
|
||||
if (\count($tks) !== 3) {
|
||||
throw new UnexpectedValueException('Wrong number of segments');
|
||||
}
|
||||
list($headb64, $bodyb64, $cryptob64) = $tks;
|
||||
$headerRaw = static::urlsafeB64Decode($headb64);
|
||||
if (null === ($header = static::jsonDecode($headerRaw))) {
|
||||
throw new UnexpectedValueException('Invalid header encoding');
|
||||
}
|
||||
$payloadRaw = static::urlsafeB64Decode($bodyb64);
|
||||
if (null === ($payload = static::jsonDecode($payloadRaw))) {
|
||||
throw new UnexpectedValueException('Invalid claims encoding');
|
||||
}
|
||||
if (\is_array($payload)) {
|
||||
// prevent PHP Fatal Error in edge-cases when payload is empty array
|
||||
$payload = (object) $payload;
|
||||
}
|
||||
if (!$payload instanceof stdClass) {
|
||||
throw new UnexpectedValueException('Payload must be a JSON object');
|
||||
}
|
||||
$sig = static::urlsafeB64Decode($cryptob64);
|
||||
if (empty($header->alg)) {
|
||||
throw new UnexpectedValueException('Empty algorithm');
|
||||
}
|
||||
if (empty(static::$supported_algs[$header->alg])) {
|
||||
throw new UnexpectedValueException('Algorithm not supported');
|
||||
}
|
||||
|
||||
$key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null);
|
||||
|
||||
// Check the algorithm
|
||||
if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) {
|
||||
// See issue #351
|
||||
throw new UnexpectedValueException('Incorrect key for this algorithm');
|
||||
}
|
||||
if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) {
|
||||
// OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures
|
||||
$sig = self::signatureToDER($sig);
|
||||
}
|
||||
if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) {
|
||||
throw new SignatureInvalidException('Signature verification failed');
|
||||
}
|
||||
|
||||
// Check the nbf if it is defined. This is the time that the
|
||||
// token can actually be used. If it's not yet that time, abort.
|
||||
if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
|
||||
throw new BeforeValidException(
|
||||
'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf)
|
||||
);
|
||||
}
|
||||
|
||||
// Check that this token has been created before 'now'. This prevents
|
||||
// using tokens that have been created for later use (and haven't
|
||||
// correctly used the nbf claim).
|
||||
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
|
||||
throw new BeforeValidException(
|
||||
'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat)
|
||||
);
|
||||
}
|
||||
|
||||
// Check if this token has expired.
|
||||
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
|
||||
throw new ExpiredException('Expired token');
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts and signs a PHP array into a JWT string.
|
||||
*
|
||||
* @param array<mixed> $payload PHP array
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
|
||||
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||
* @param string $keyId
|
||||
* @param array<string, string> $head An array with header elements to attach
|
||||
*
|
||||
* @return string A signed JWT
|
||||
*
|
||||
* @uses jsonEncode
|
||||
* @uses urlsafeB64Encode
|
||||
*/
|
||||
public static function encode(
|
||||
array $payload,
|
||||
$key,
|
||||
string $alg,
|
||||
string $keyId = null,
|
||||
array $head = null
|
||||
): string {
|
||||
$header = ['typ' => 'JWT', 'alg' => $alg];
|
||||
if ($keyId !== null) {
|
||||
$header['kid'] = $keyId;
|
||||
}
|
||||
if (isset($head) && \is_array($head)) {
|
||||
$header = \array_merge($head, $header);
|
||||
}
|
||||
$segments = [];
|
||||
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header));
|
||||
$segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload));
|
||||
$signing_input = \implode('.', $segments);
|
||||
|
||||
$signature = static::sign($signing_input, $key, $alg);
|
||||
$segments[] = static::urlsafeB64Encode($signature);
|
||||
|
||||
return \implode('.', $segments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a string with a given key and algorithm.
|
||||
*
|
||||
* @param string $msg The message to sign
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
|
||||
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
|
||||
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
|
||||
*
|
||||
* @return string An encrypted message
|
||||
*
|
||||
* @throws DomainException Unsupported algorithm or bad key was specified
|
||||
*/
|
||||
public static function sign(
|
||||
string $msg,
|
||||
$key,
|
||||
string $alg
|
||||
): string {
|
||||
if (empty(static::$supported_algs[$alg])) {
|
||||
throw new DomainException('Algorithm not supported');
|
||||
}
|
||||
list($function, $algorithm) = static::$supported_algs[$alg];
|
||||
switch ($function) {
|
||||
case 'hash_hmac':
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('key must be a string when using hmac');
|
||||
}
|
||||
return \hash_hmac($algorithm, $msg, $key, true);
|
||||
case 'openssl':
|
||||
$signature = '';
|
||||
$success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
|
||||
if (!$success) {
|
||||
throw new DomainException('OpenSSL unable to sign data');
|
||||
}
|
||||
if ($alg === 'ES256' || $alg === 'ES256K') {
|
||||
$signature = self::signatureFromDER($signature, 256);
|
||||
} elseif ($alg === 'ES384') {
|
||||
$signature = self::signatureFromDER($signature, 384);
|
||||
}
|
||||
return $signature;
|
||||
case 'sodium_crypto':
|
||||
if (!\function_exists('sodium_crypto_sign_detached')) {
|
||||
throw new DomainException('libsodium is not available');
|
||||
}
|
||||
if (!\is_string($key)) {
|
||||
throw new InvalidArgumentException('key must be a string when using EdDSA');
|
||||
}
|
||||
try {
|
||||
// The last non-empty line is used as the key.
|
||||
$lines = array_filter(explode("\n", $key));
|
||||
$key = base64_decode((string) end($lines));
|
||||
if (\strlen($key) === 0) {
|
||||
throw new DomainException('Key cannot be empty string');
|
||||
}
|
||||
return sodium_crypto_sign_detached($msg, $key);
|
||||
} catch (Exception $e) {
|
||||
throw new DomainException($e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new DomainException('Algorithm not supported');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a signature with the message, key and method. Not all methods
|
||||
* are symmetric, so we must have a separate verify and sign method.
|
||||
*
|
||||
* @param string $msg The original message (header and body)
|
||||
* @param string $signature The original signature
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
|
||||
* @param string $alg The algorithm
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure
|
||||
*/
|
||||
private static function verify(
|
||||
string $msg,
|
||||
string $signature,
|
||||
$keyMaterial,
|
||||
string $alg
|
||||
): bool {
|
||||
if (empty(static::$supported_algs[$alg])) {
|
||||
throw new DomainException('Algorithm not supported');
|
||||
}
|
||||
|
||||
list($function, $algorithm) = static::$supported_algs[$alg];
|
||||
switch ($function) {
|
||||
case 'openssl':
|
||||
$success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line
|
||||
if ($success === 1) {
|
||||
return true;
|
||||
}
|
||||
if ($success === 0) {
|
||||
return false;
|
||||
}
|
||||
// returns 1 on success, 0 on failure, -1 on error.
|
||||
throw new DomainException(
|
||||
'OpenSSL error: ' . \openssl_error_string()
|
||||
);
|
||||
case 'sodium_crypto':
|
||||
if (!\function_exists('sodium_crypto_sign_verify_detached')) {
|
||||
throw new DomainException('libsodium is not available');
|
||||
}
|
||||
if (!\is_string($keyMaterial)) {
|
||||
throw new InvalidArgumentException('key must be a string when using EdDSA');
|
||||
}
|
||||
try {
|
||||
// The last non-empty line is used as the key.
|
||||
$lines = array_filter(explode("\n", $keyMaterial));
|
||||
$key = base64_decode((string) end($lines));
|
||||
if (\strlen($key) === 0) {
|
||||
throw new DomainException('Key cannot be empty string');
|
||||
}
|
||||
if (\strlen($signature) === 0) {
|
||||
throw new DomainException('Signature cannot be empty string');
|
||||
}
|
||||
return sodium_crypto_sign_verify_detached($signature, $msg, $key);
|
||||
} catch (Exception $e) {
|
||||
throw new DomainException($e->getMessage(), 0, $e);
|
||||
}
|
||||
case 'hash_hmac':
|
||||
default:
|
||||
if (!\is_string($keyMaterial)) {
|
||||
throw new InvalidArgumentException('key must be a string when using hmac');
|
||||
}
|
||||
$hash = \hash_hmac($algorithm, $msg, $keyMaterial, true);
|
||||
return self::constantTimeEquals($hash, $signature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a JSON string into a PHP object.
|
||||
*
|
||||
* @param string $input JSON string
|
||||
*
|
||||
* @return mixed The decoded JSON string
|
||||
*
|
||||
* @throws DomainException Provided string was invalid JSON
|
||||
*/
|
||||
public static function jsonDecode(string $input)
|
||||
{
|
||||
$obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
|
||||
|
||||
if ($errno = \json_last_error()) {
|
||||
self::handleJsonError($errno);
|
||||
} elseif ($obj === null && $input !== 'null') {
|
||||
throw new DomainException('Null result with non-null input');
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a PHP array into a JSON string.
|
||||
*
|
||||
* @param array<mixed> $input A PHP array
|
||||
*
|
||||
* @return string JSON representation of the PHP array
|
||||
*
|
||||
* @throws DomainException Provided object could not be encoded to valid JSON
|
||||
*/
|
||||
public static function jsonEncode(array $input): string
|
||||
{
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
$json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
|
||||
} else {
|
||||
// PHP 5.3 only
|
||||
$json = \json_encode($input);
|
||||
}
|
||||
if ($errno = \json_last_error()) {
|
||||
self::handleJsonError($errno);
|
||||
} elseif ($json === 'null' && $input !== null) {
|
||||
throw new DomainException('Null result with non-null input');
|
||||
}
|
||||
if ($json === false) {
|
||||
throw new DomainException('Provided object could not be encoded to valid JSON');
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a string with URL-safe Base64.
|
||||
*
|
||||
* @param string $input A Base64 encoded string
|
||||
*
|
||||
* @return string A decoded string
|
||||
*
|
||||
* @throws InvalidArgumentException invalid base64 characters
|
||||
*/
|
||||
public static function urlsafeB64Decode(string $input): string
|
||||
{
|
||||
$remainder = \strlen($input) % 4;
|
||||
if ($remainder) {
|
||||
$padlen = 4 - $remainder;
|
||||
$input .= \str_repeat('=', $padlen);
|
||||
}
|
||||
return \base64_decode(\strtr($input, '-_', '+/'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a string with URL-safe Base64.
|
||||
*
|
||||
* @param string $input The string you want encoded
|
||||
*
|
||||
* @return string The base64 encode of what you passed in
|
||||
*/
|
||||
public static function urlsafeB64Encode(string $input): string
|
||||
{
|
||||
return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if an algorithm has been provided for each Key
|
||||
*
|
||||
* @param Key|ArrayAccess<string,Key>|array<string,Key> $keyOrKeyArray
|
||||
* @param string|null $kid
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*
|
||||
* @return Key
|
||||
*/
|
||||
private static function getKey(
|
||||
$keyOrKeyArray,
|
||||
?string $kid
|
||||
): Key {
|
||||
if ($keyOrKeyArray instanceof Key) {
|
||||
return $keyOrKeyArray;
|
||||
}
|
||||
|
||||
if (empty($kid)) {
|
||||
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
|
||||
}
|
||||
|
||||
if ($keyOrKeyArray instanceof CachedKeySet) {
|
||||
// Skip "isset" check, as this will automatically refresh if not set
|
||||
return $keyOrKeyArray[$kid];
|
||||
}
|
||||
|
||||
if (!isset($keyOrKeyArray[$kid])) {
|
||||
throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
|
||||
}
|
||||
|
||||
return $keyOrKeyArray[$kid];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $left The string of known length to compare against
|
||||
* @param string $right The user-supplied string
|
||||
* @return bool
|
||||
*/
|
||||
public static function constantTimeEquals(string $left, string $right): bool
|
||||
{
|
||||
if (\function_exists('hash_equals')) {
|
||||
return \hash_equals($left, $right);
|
||||
}
|
||||
$len = \min(self::safeStrlen($left), self::safeStrlen($right));
|
||||
|
||||
$status = 0;
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$status |= (\ord($left[$i]) ^ \ord($right[$i]));
|
||||
}
|
||||
$status |= (self::safeStrlen($left) ^ self::safeStrlen($right));
|
||||
|
||||
return ($status === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to create a JSON error.
|
||||
*
|
||||
* @param int $errno An error number from json_last_error()
|
||||
*
|
||||
* @throws DomainException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function handleJsonError(int $errno): void
|
||||
{
|
||||
$messages = [
|
||||
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
|
||||
JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
|
||||
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
|
||||
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
|
||||
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
|
||||
];
|
||||
throw new DomainException(
|
||||
isset($messages[$errno])
|
||||
? $messages[$errno]
|
||||
: 'Unknown JSON error: ' . $errno
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes in cryptographic strings.
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function safeStrlen(string $str): int
|
||||
{
|
||||
if (\function_exists('mb_strlen')) {
|
||||
return \mb_strlen($str, '8bit');
|
||||
}
|
||||
return \strlen($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an ECDSA signature to an ASN.1 DER sequence
|
||||
*
|
||||
* @param string $sig The ECDSA signature to convert
|
||||
* @return string The encoded DER object
|
||||
*/
|
||||
private static function signatureToDER(string $sig): string
|
||||
{
|
||||
// Separate the signature into r-value and s-value
|
||||
$length = max(1, (int) (\strlen($sig) / 2));
|
||||
list($r, $s) = \str_split($sig, $length);
|
||||
|
||||
// Trim leading zeros
|
||||
$r = \ltrim($r, "\x00");
|
||||
$s = \ltrim($s, "\x00");
|
||||
|
||||
// Convert r-value and s-value from unsigned big-endian integers to
|
||||
// signed two's complement
|
||||
if (\ord($r[0]) > 0x7f) {
|
||||
$r = "\x00" . $r;
|
||||
}
|
||||
if (\ord($s[0]) > 0x7f) {
|
||||
$s = "\x00" . $s;
|
||||
}
|
||||
|
||||
return self::encodeDER(
|
||||
self::ASN1_SEQUENCE,
|
||||
self::encodeDER(self::ASN1_INTEGER, $r) .
|
||||
self::encodeDER(self::ASN1_INTEGER, $s)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a value into a DER object.
|
||||
*
|
||||
* @param int $type DER tag
|
||||
* @param string $value the value to encode
|
||||
*
|
||||
* @return string the encoded object
|
||||
*/
|
||||
private static function encodeDER(int $type, string $value): string
|
||||
{
|
||||
$tag_header = 0;
|
||||
if ($type === self::ASN1_SEQUENCE) {
|
||||
$tag_header |= 0x20;
|
||||
}
|
||||
|
||||
// Type
|
||||
$der = \chr($tag_header | $type);
|
||||
|
||||
// Length
|
||||
$der .= \chr(\strlen($value));
|
||||
|
||||
return $der . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes signature from a DER object.
|
||||
*
|
||||
* @param string $der binary signature in DER format
|
||||
* @param int $keySize the number of bits in the key
|
||||
*
|
||||
* @return string the signature
|
||||
*/
|
||||
private static function signatureFromDER(string $der, int $keySize): string
|
||||
{
|
||||
// OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE
|
||||
list($offset, $_) = self::readDER($der);
|
||||
list($offset, $r) = self::readDER($der, $offset);
|
||||
list($offset, $s) = self::readDER($der, $offset);
|
||||
|
||||
// Convert r-value and s-value from signed two's compliment to unsigned
|
||||
// big-endian integers
|
||||
$r = \ltrim($r, "\x00");
|
||||
$s = \ltrim($s, "\x00");
|
||||
|
||||
// Pad out r and s so that they are $keySize bits long
|
||||
$r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT);
|
||||
$s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT);
|
||||
|
||||
return $r . $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads binary DER-encoded data and decodes into a single object
|
||||
*
|
||||
* @param string $der the binary data in DER format
|
||||
* @param int $offset the offset of the data stream containing the object
|
||||
* to decode
|
||||
*
|
||||
* @return array{int, string|null} the new offset and the decoded object
|
||||
*/
|
||||
private static function readDER(string $der, int $offset = 0): array
|
||||
{
|
||||
$pos = $offset;
|
||||
$size = \strlen($der);
|
||||
$constructed = (\ord($der[$pos]) >> 5) & 0x01;
|
||||
$type = \ord($der[$pos++]) & 0x1f;
|
||||
|
||||
// Length
|
||||
$len = \ord($der[$pos++]);
|
||||
if ($len & 0x80) {
|
||||
$n = $len & 0x1f;
|
||||
$len = 0;
|
||||
while ($n-- && $pos < $size) {
|
||||
$len = ($len << 8) | \ord($der[$pos++]);
|
||||
}
|
||||
}
|
||||
|
||||
// Value
|
||||
if ($type === self::ASN1_BIT_STRING) {
|
||||
$pos++; // Skip the first contents octet (padding indicator)
|
||||
$data = \substr($der, $pos, $len - 1);
|
||||
$pos += $len - 1;
|
||||
} elseif (!$constructed) {
|
||||
$data = \substr($der, $pos, $len);
|
||||
$pos += $len;
|
||||
} else {
|
||||
$data = null;
|
||||
}
|
||||
|
||||
return [$pos, $data];
|
||||
}
|
||||
}
|
||||
20
api/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php
vendored
Normal file
20
api/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace Firebase\JWT;
|
||||
|
||||
interface JWTExceptionWithPayloadInterface
|
||||
{
|
||||
/**
|
||||
* Get the payload that caused this exception.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getPayload(): object;
|
||||
|
||||
/**
|
||||
* Get the payload that caused this exception.
|
||||
*
|
||||
* @param object $payload
|
||||
* @return void
|
||||
*/
|
||||
public function setPayload(object $payload): void;
|
||||
}
|
||||
64
api/vendor/firebase/php-jwt/src/Key.php
vendored
Normal file
64
api/vendor/firebase/php-jwt/src/Key.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OpenSSLAsymmetricKey;
|
||||
use OpenSSLCertificate;
|
||||
use TypeError;
|
||||
|
||||
class Key
|
||||
{
|
||||
/** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */
|
||||
private $keyMaterial;
|
||||
/** @var string */
|
||||
private $algorithm;
|
||||
|
||||
/**
|
||||
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial
|
||||
* @param string $algorithm
|
||||
*/
|
||||
public function __construct(
|
||||
$keyMaterial,
|
||||
string $algorithm
|
||||
) {
|
||||
if (
|
||||
!\is_string($keyMaterial)
|
||||
&& !$keyMaterial instanceof OpenSSLAsymmetricKey
|
||||
&& !$keyMaterial instanceof OpenSSLCertificate
|
||||
&& !\is_resource($keyMaterial)
|
||||
) {
|
||||
throw new TypeError('Key material must be a string, resource, or OpenSSLAsymmetricKey');
|
||||
}
|
||||
|
||||
if (empty($keyMaterial)) {
|
||||
throw new InvalidArgumentException('Key material must not be empty');
|
||||
}
|
||||
|
||||
if (empty($algorithm)) {
|
||||
throw new InvalidArgumentException('Algorithm must not be empty');
|
||||
}
|
||||
|
||||
// TODO: Remove in PHP 8.0 in favor of class constructor property promotion
|
||||
$this->keyMaterial = $keyMaterial;
|
||||
$this->algorithm = $algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the algorithm valid for this key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAlgorithm(): string
|
||||
{
|
||||
return $this->algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate
|
||||
*/
|
||||
public function getKeyMaterial()
|
||||
{
|
||||
return $this->keyMaterial;
|
||||
}
|
||||
}
|
||||
7
api/vendor/firebase/php-jwt/src/SignatureInvalidException.php
vendored
Normal file
7
api/vendor/firebase/php-jwt/src/SignatureInvalidException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Firebase\JWT;
|
||||
|
||||
class SignatureInvalidException extends \UnexpectedValueException
|
||||
{
|
||||
}
|
||||
15
api/vendor/rmccue/requests/.editorconfig
vendored
Normal file
15
api/vendor/rmccue/requests/.editorconfig
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = tab
|
||||
|
||||
[{*.json,*.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
1010
api/vendor/rmccue/requests/CHANGELOG.md
vendored
Normal file
1010
api/vendor/rmccue/requests/CHANGELOG.md
vendored
Normal file
File diff suppressed because it is too large
Load Diff
49
api/vendor/rmccue/requests/LICENSE
vendored
Normal file
49
api/vendor/rmccue/requests/LICENSE
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
Requests
|
||||
========
|
||||
|
||||
Copyright (c) 2010-2012 Ryan McCue and contributors
|
||||
|
||||
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.
|
||||
|
||||
|
||||
ComplexPie IRI Parser
|
||||
=====================
|
||||
|
||||
Copyright (c) 2007-2010, Geoffrey Sneddon and Steve Minutillo.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the SimplePie Team nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
168
api/vendor/rmccue/requests/README.md
vendored
Normal file
168
api/vendor/rmccue/requests/README.md
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
Requests for PHP
|
||||
================
|
||||
|
||||
[](https://github.com/WordPress/Requests/actions/workflows/cs.yml)
|
||||
[](https://github.com/WordPress/Requests/actions/workflows/lint.yml)
|
||||
[](https://github.com/WordPress/Requests/actions/workflows/test.yml)
|
||||
[](https://codecov.io/gh/WordPress/Requests?branch=stable)
|
||||
|
||||
Requests is a HTTP library written in PHP, for human beings. It is roughly
|
||||
based on the API from the excellent [Requests Python
|
||||
library](http://python-requests.org/). Requests is [ISC
|
||||
Licensed](https://github.com/WordPress/Requests/blob/stable/LICENSE) (similar to
|
||||
the new BSD license) and has no dependencies, except for PHP 5.6+.
|
||||
|
||||
Despite PHP's use as a language for the web, its tools for sending HTTP requests
|
||||
are severely lacking. cURL has an
|
||||
[interesting API](https://www.php.net/curl-setopt), to say the
|
||||
least, and you can't always rely on it being available. Sockets provide only low
|
||||
level access, and require you to build most of the HTTP response parsing
|
||||
yourself.
|
||||
|
||||
We all have better things to do. That's why Requests was born.
|
||||
|
||||
```php
|
||||
$headers = array('Accept' => 'application/json');
|
||||
$options = array('auth' => array('user', 'pass'));
|
||||
$request = WpOrg\Requests\Requests::get('https://api.github.com/gists', $headers, $options);
|
||||
|
||||
var_dump($request->status_code);
|
||||
// int(200)
|
||||
|
||||
var_dump($request->headers['content-type']);
|
||||
// string(31) "application/json; charset=utf-8"
|
||||
|
||||
var_dump($request->body);
|
||||
// string(26891) "[...]"
|
||||
```
|
||||
|
||||
Requests allows you to send **HEAD**, **GET**, **POST**, **PUT**, **DELETE**,
|
||||
and **PATCH** HTTP requests. You can add headers, form data, multipart files,
|
||||
and parameters with basic arrays, and access the response data in the same way.
|
||||
Requests uses cURL and fsockopen, depending on what your system has available,
|
||||
but abstracts all the nasty stuff out of your way, providing a consistent API.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- International Domains and URLs
|
||||
- Browser-style SSL Verification
|
||||
- Basic/Digest Authentication
|
||||
- Automatic Decompression
|
||||
- Connection Timeouts
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Install with Composer
|
||||
If you're using [Composer](https://getcomposer.org/) to manage
|
||||
dependencies, you can add Requests with it.
|
||||
|
||||
```sh
|
||||
composer require rmccue/requests
|
||||
```
|
||||
|
||||
or
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"rmccue/requests": "^2.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Install source from GitHub
|
||||
To install the source code:
|
||||
```bash
|
||||
$ git clone git://github.com/WordPress/Requests.git
|
||||
```
|
||||
|
||||
Next, include the autoloader in your scripts:
|
||||
```php
|
||||
require_once '/path/to/Requests/src/Autoload.php';
|
||||
```
|
||||
|
||||
You'll probably also want to register the autoloader:
|
||||
```php
|
||||
WpOrg\Requests\Autoload::register();
|
||||
```
|
||||
|
||||
### Install source from zip/tarball
|
||||
Alternatively, you can fetch a [tarball][] or [zipball][]:
|
||||
|
||||
```bash
|
||||
$ curl -L https://github.com/WordPress/Requests/tarball/stable | tar xzv
|
||||
(or)
|
||||
$ wget https://github.com/WordPress/Requests/tarball/stable -O - | tar xzv
|
||||
```
|
||||
|
||||
[tarball]: https://github.com/WordPress/Requests/tarball/stable
|
||||
[zipball]: https://github.com/WordPress/Requests/zipball/stable
|
||||
|
||||
|
||||
### Using a Class Loader
|
||||
If you're using a class loader (e.g., [Symfony Class Loader][]) for
|
||||
[PSR-4][]-style class loading:
|
||||
```php
|
||||
$loader = new Psr4ClassLoader();
|
||||
$loader->addPrefix('WpOrg\\Requests\\', 'path/to/vendor/Requests/src');
|
||||
$loader->register();
|
||||
```
|
||||
|
||||
[Symfony Class Loader]: https://github.com/symfony/ClassLoader
|
||||
[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4.md
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
The best place to start is our [prose-based documentation][], which will guide
|
||||
you through using Requests.
|
||||
|
||||
After that, take a look at [the documentation for
|
||||
`\WpOrg\Requests\Requests::request()`][request_method], where all the parameters are fully
|
||||
documented.
|
||||
|
||||
Requests is [100% documented with PHPDoc](https://requests.ryanmccue.info/api-2.x/).
|
||||
If you find any problems with it, [create a new
|
||||
issue](https://github.com/WordPress/Requests/issues/new)!
|
||||
|
||||
[prose-based documentation]: https://github.com/WordPress/Requests/blob/stable/docs/README.md
|
||||
[request_method]: https://requests.ryanmccue.info/api-2.x/classes/WpOrg-Requests-Requests.html#method_request
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Requests strives to have 100% code-coverage of the library with an extensive
|
||||
set of tests. We're not quite there yet, but [we're getting close][codecov].
|
||||
|
||||
[codecov]: https://codecov.io/github/WordPress/Requests/
|
||||
|
||||
To run the test suite, first check that you have the [PHP
|
||||
JSON extension ](https://www.php.net/book.json) enabled. Then
|
||||
simply:
|
||||
```bash
|
||||
$ phpunit
|
||||
```
|
||||
|
||||
If you'd like to run a single set of tests, specify just the name:
|
||||
```bash
|
||||
$ phpunit Transport/cURL
|
||||
```
|
||||
|
||||
Contribute
|
||||
----------
|
||||
|
||||
1. Check for open issues or open a new issue for a feature request or a bug.
|
||||
2. Fork [the repository][] on Github to start making your changes to the
|
||||
`develop` branch (or branch off of it).
|
||||
3. Write one or more tests which show that the bug was fixed or that the feature works as expected.
|
||||
4. Send in a pull request.
|
||||
|
||||
If you have questions while working on your contribution and you use Slack, there is
|
||||
a [#core-http-api] channel available in the [WordPress Slack] in which contributions can be discussed.
|
||||
|
||||
[the repository]: https://github.com/WordPress/Requests
|
||||
[#core-http-api]: https://wordpress.slack.com/archives/C02BBE29V42
|
||||
[WordPress Slack]: https://make.wordpress.org/chat/
|
||||
3506
api/vendor/rmccue/requests/certificates/cacert.pem
vendored
Normal file
3506
api/vendor/rmccue/requests/certificates/cacert.pem
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
api/vendor/rmccue/requests/certificates/cacert.pem.sha256
vendored
Normal file
1
api/vendor/rmccue/requests/certificates/cacert.pem.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
||||
2cff03f9efdaf52626bd1b451d700605dc1ea000c5da56bd0fc59f8f43071040 cacert.pem
|
||||
88
api/vendor/rmccue/requests/composer.json
vendored
Normal file
88
api/vendor/rmccue/requests/composer.json
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "rmccue/requests",
|
||||
"description": "A HTTP library written in PHP, for human beings.",
|
||||
"homepage": "https://requests.ryanmccue.info/",
|
||||
"license": "ISC",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"http",
|
||||
"idna",
|
||||
"iri",
|
||||
"ipv6",
|
||||
"curl",
|
||||
"sockets",
|
||||
"fsockopen"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ryan McCue",
|
||||
"homepage": "https://rmccue.io/"
|
||||
},
|
||||
{
|
||||
"name": "Alain Schlesser",
|
||||
"homepage": "https://github.com/schlessera"
|
||||
},
|
||||
{
|
||||
"name": "Juliette Reinders Folmer",
|
||||
"homepage": "https://github.com/jrfnl"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/WordPress/Requests/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/WordPress/Requests/issues",
|
||||
"source": "https://github.com/WordPress/Requests",
|
||||
"docs": "https://requests.ryanmccue.info/"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"requests/test-server": "dev-main",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"phpcompatibility/php-compatibility": "^9.0",
|
||||
"wp-coding-standards/wpcs": "^2.0",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
||||
"php-parallel-lint/php-console-highlighter": "^0.5.0",
|
||||
"yoast/phpunit-polyfills": "^1.0.0",
|
||||
"roave/security-advisories": "dev-latest"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"WpOrg\\Requests\\": "src/"
|
||||
},
|
||||
"classmap": ["library/Requests.php"],
|
||||
"files": ["library/Deprecated.php"]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"WpOrg\\Requests\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"lint": [
|
||||
"@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git"
|
||||
],
|
||||
"checkcs": [
|
||||
"@php ./vendor/squizlabs/php_codesniffer/bin/phpcs"
|
||||
],
|
||||
"fixcs": [
|
||||
"@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf"
|
||||
],
|
||||
"test": [
|
||||
"@php ./vendor/phpunit/phpunit/phpunit --no-coverage"
|
||||
],
|
||||
"coverage": [
|
||||
"@php ./vendor/phpunit/phpunit/phpunit"
|
||||
]
|
||||
}
|
||||
}
|
||||
19
api/vendor/rmccue/requests/library/Deprecated.php
vendored
Normal file
19
api/vendor/rmccue/requests/library/Deprecated.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Backwards compatibility layer for Requests.
|
||||
*
|
||||
* Allows for Composer to autoload the old PSR-0 classes via the custom autoloader.
|
||||
* This prevents issues with _extending final classes_ (which was the previous solution).
|
||||
*
|
||||
* Please see the Changelog for the 2.0.0 release for upgrade notes.
|
||||
*
|
||||
* @package Requests
|
||||
*
|
||||
* @deprecated 2.0.0 Use the PSR-4 class names instead.
|
||||
*/
|
||||
|
||||
if (class_exists('WpOrg\Requests\Autoload') === false) {
|
||||
require_once dirname(__DIR__) . '/src/Autoload.php';
|
||||
}
|
||||
|
||||
WpOrg\Requests\Autoload::register();
|
||||
6
api/vendor/rmccue/requests/library/README.md
vendored
Normal file
6
api/vendor/rmccue/requests/library/README.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
## The Library directory is deprecated.
|
||||
|
||||
The files in this directory are only still in place to provide backward compatibility with Requests 1.x.
|
||||
Please see the release notes of Requests 2.0.0 on how to upgrade.
|
||||
|
||||
This directory will be removed in Requests v 4.0.0.
|
||||
78
api/vendor/rmccue/requests/library/Requests.php
vendored
Normal file
78
api/vendor/rmccue/requests/library/Requests.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Requests for PHP
|
||||
*
|
||||
* Inspired by Requests for Python.
|
||||
*
|
||||
* Based on concepts from SimplePie_File, RequestCore and WP_Http.
|
||||
*
|
||||
* @package Requests
|
||||
*
|
||||
* @deprecated 2.0.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
|
||||
* by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
|
||||
* The constant needs to be defined before this class is required.
|
||||
*/
|
||||
if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
||||
trigger_error(
|
||||
'The PSR-0 `Requests_...` class names in the Request library are deprecated.'
|
||||
. ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
// Prevent the deprecation notice from being thrown twice.
|
||||
if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
|
||||
define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
|
||||
}
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__) . '/src/Requests.php';
|
||||
|
||||
/**
|
||||
* Requests for PHP
|
||||
*
|
||||
* Inspired by Requests for Python.
|
||||
*
|
||||
* Based on concepts from SimplePie_File, RequestCore and WP_Http.
|
||||
*
|
||||
* @package Requests
|
||||
*
|
||||
* @deprecated 2.0.0 Use `WpOrg\Requests\Requests` instead for the actual functionality and
|
||||
* use `WpOrg\Requests\Autoload` for the autoloading.
|
||||
*/
|
||||
class Requests extends WpOrg\Requests\Requests {
|
||||
|
||||
/**
|
||||
* Deprecated autoloader for Requests.
|
||||
*
|
||||
* @deprecated 2.0.0 Use the `WpOrg\Requests\Autoload::load()` method instead.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $class Class name to load
|
||||
*/
|
||||
public static function autoloader($class) {
|
||||
if (class_exists('WpOrg\Requests\Autoload') === false) {
|
||||
require_once dirname(__DIR__) . '/src/Autoload.php';
|
||||
}
|
||||
|
||||
return WpOrg\Requests\Autoload::load($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the built-in autoloader
|
||||
*
|
||||
* @deprecated 2.0.0 Include the `WpOrg\Requests\Autoload` class and
|
||||
* call `WpOrg\Requests\Autoload::register()` instead.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function register_autoloader() {
|
||||
require_once dirname(__DIR__) . '/src/Autoload.php';
|
||||
WpOrg\Requests\Autoload::register();
|
||||
}
|
||||
}
|
||||
36
api/vendor/rmccue/requests/src/Auth.php
vendored
Normal file
36
api/vendor/rmccue/requests/src/Auth.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* @package Requests\Authentication
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Hooks;
|
||||
|
||||
/**
|
||||
* Authentication provider interface
|
||||
*
|
||||
* Implement this interface to act as an authentication provider.
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see \WpOrg\Requests\Hooks
|
||||
*
|
||||
* @package Requests\Authentication
|
||||
*/
|
||||
interface Auth {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see \WpOrg\Requests\Requests::request()} when the user
|
||||
* has set an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see \WpOrg\Requests\Hooks::register()
|
||||
* @param \WpOrg\Requests\Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Hooks $hooks);
|
||||
}
|
||||
103
api/vendor/rmccue/requests/src/Auth/Basic.php
vendored
Normal file
103
api/vendor/rmccue/requests/src/Auth/Basic.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* @package Requests\Authentication
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Auth;
|
||||
|
||||
use WpOrg\Requests\Auth;
|
||||
use WpOrg\Requests\Exception\ArgumentCount;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Hooks;
|
||||
|
||||
/**
|
||||
* Basic Authentication provider
|
||||
*
|
||||
* Provides a handler for Basic HTTP authentication via the Authorization
|
||||
* header.
|
||||
*
|
||||
* @package Requests\Authentication
|
||||
*/
|
||||
class Basic implements Auth {
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 2.0 Throws an `InvalidArgument` exception.
|
||||
* @since 2.0 Throws an `ArgumentCount` exception instead of the Requests base `Exception.
|
||||
*
|
||||
* @param array|null $args Array of user and password. Must have exactly two elements
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array or null.
|
||||
* @throws \WpOrg\Requests\Exception\ArgumentCount On incorrect number of array elements (`authbasicbadargs`).
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_array($args)) {
|
||||
if (count($args) !== 2) {
|
||||
throw ArgumentCount::create('an array with exactly two elements', count($args), 'authbasicbadargs');
|
||||
}
|
||||
|
||||
list($this->user, $this->pass) = $args;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($args !== null) {
|
||||
throw InvalidArgument::create(1, '$args', 'array|null', gettype($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @see \WpOrg\Requests\Auth\Basic::curl_before_send()
|
||||
* @see \WpOrg\Requests\Auth\Basic::fsockopen_header()
|
||||
* @param \WpOrg\Requests\Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Hooks $hooks) {
|
||||
$hooks->register('curl.before_send', [$this, 'curl_before_send']);
|
||||
$hooks->register('fsockopen.after_headers', [$this, 'fsockopen_header']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @param resource|\CurlHandle $handle cURL handle
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($handle, CURLOPT_USERPWD, $this->getAuthString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header(&$out) {
|
||||
$out .= sprintf("Authorization: Basic %s\r\n", base64_encode($this->getAuthString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthString() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
||||
187
api/vendor/rmccue/requests/src/Autoload.php
vendored
Normal file
187
api/vendor/rmccue/requests/src/Autoload.php
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* Autoloader for Requests for PHP.
|
||||
*
|
||||
* Include this file if you'd like to avoid having to create your own autoloader.
|
||||
*
|
||||
* @package Requests
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
/*
|
||||
* Ensure the autoloader is only declared once.
|
||||
* This safeguard is in place as this is the typical entry point for this library
|
||||
* and this file being required unconditionally could easily cause
|
||||
* fatal "Class already declared" errors.
|
||||
*/
|
||||
if (class_exists('WpOrg\Requests\Autoload') === false) {
|
||||
|
||||
/**
|
||||
* Autoloader for Requests for PHP.
|
||||
*
|
||||
* This autoloader supports the PSR-4 based Requests 2.0.0 classes in a case-sensitive manner
|
||||
* as the most common server OS-es are case-sensitive and the file names are in mixed case.
|
||||
*
|
||||
* For the PSR-0 Requests 1.x BC-layer, requested classes will be treated case-insensitively.
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
final class Autoload {
|
||||
|
||||
/**
|
||||
* List of the old PSR-0 class names in lowercase as keys with their PSR-4 case-sensitive name as a value.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $deprecated_classes = [
|
||||
// Interfaces.
|
||||
'requests_auth' => '\WpOrg\Requests\Auth',
|
||||
'requests_hooker' => '\WpOrg\Requests\HookManager',
|
||||
'requests_proxy' => '\WpOrg\Requests\Proxy',
|
||||
'requests_transport' => '\WpOrg\Requests\Transport',
|
||||
|
||||
// Classes.
|
||||
'requests_cookie' => '\WpOrg\Requests\Cookie',
|
||||
'requests_exception' => '\WpOrg\Requests\Exception',
|
||||
'requests_hooks' => '\WpOrg\Requests\Hooks',
|
||||
'requests_idnaencoder' => '\WpOrg\Requests\IdnaEncoder',
|
||||
'requests_ipv6' => '\WpOrg\Requests\Ipv6',
|
||||
'requests_iri' => '\WpOrg\Requests\Iri',
|
||||
'requests_response' => '\WpOrg\Requests\Response',
|
||||
'requests_session' => '\WpOrg\Requests\Session',
|
||||
'requests_ssl' => '\WpOrg\Requests\Ssl',
|
||||
'requests_auth_basic' => '\WpOrg\Requests\Auth\Basic',
|
||||
'requests_cookie_jar' => '\WpOrg\Requests\Cookie\Jar',
|
||||
'requests_proxy_http' => '\WpOrg\Requests\Proxy\Http',
|
||||
'requests_response_headers' => '\WpOrg\Requests\Response\Headers',
|
||||
'requests_transport_curl' => '\WpOrg\Requests\Transport\Curl',
|
||||
'requests_transport_fsockopen' => '\WpOrg\Requests\Transport\Fsockopen',
|
||||
'requests_utility_caseinsensitivedictionary' => '\WpOrg\Requests\Utility\CaseInsensitiveDictionary',
|
||||
'requests_utility_filterediterator' => '\WpOrg\Requests\Utility\FilteredIterator',
|
||||
'requests_exception_http' => '\WpOrg\Requests\Exception\Http',
|
||||
'requests_exception_transport' => '\WpOrg\Requests\Exception\Transport',
|
||||
'requests_exception_transport_curl' => '\WpOrg\Requests\Exception\Transport\Curl',
|
||||
'requests_exception_http_304' => '\WpOrg\Requests\Exception\Http\Status304',
|
||||
'requests_exception_http_305' => '\WpOrg\Requests\Exception\Http\Status305',
|
||||
'requests_exception_http_306' => '\WpOrg\Requests\Exception\Http\Status306',
|
||||
'requests_exception_http_400' => '\WpOrg\Requests\Exception\Http\Status400',
|
||||
'requests_exception_http_401' => '\WpOrg\Requests\Exception\Http\Status401',
|
||||
'requests_exception_http_402' => '\WpOrg\Requests\Exception\Http\Status402',
|
||||
'requests_exception_http_403' => '\WpOrg\Requests\Exception\Http\Status403',
|
||||
'requests_exception_http_404' => '\WpOrg\Requests\Exception\Http\Status404',
|
||||
'requests_exception_http_405' => '\WpOrg\Requests\Exception\Http\Status405',
|
||||
'requests_exception_http_406' => '\WpOrg\Requests\Exception\Http\Status406',
|
||||
'requests_exception_http_407' => '\WpOrg\Requests\Exception\Http\Status407',
|
||||
'requests_exception_http_408' => '\WpOrg\Requests\Exception\Http\Status408',
|
||||
'requests_exception_http_409' => '\WpOrg\Requests\Exception\Http\Status409',
|
||||
'requests_exception_http_410' => '\WpOrg\Requests\Exception\Http\Status410',
|
||||
'requests_exception_http_411' => '\WpOrg\Requests\Exception\Http\Status411',
|
||||
'requests_exception_http_412' => '\WpOrg\Requests\Exception\Http\Status412',
|
||||
'requests_exception_http_413' => '\WpOrg\Requests\Exception\Http\Status413',
|
||||
'requests_exception_http_414' => '\WpOrg\Requests\Exception\Http\Status414',
|
||||
'requests_exception_http_415' => '\WpOrg\Requests\Exception\Http\Status415',
|
||||
'requests_exception_http_416' => '\WpOrg\Requests\Exception\Http\Status416',
|
||||
'requests_exception_http_417' => '\WpOrg\Requests\Exception\Http\Status417',
|
||||
'requests_exception_http_418' => '\WpOrg\Requests\Exception\Http\Status418',
|
||||
'requests_exception_http_428' => '\WpOrg\Requests\Exception\Http\Status428',
|
||||
'requests_exception_http_429' => '\WpOrg\Requests\Exception\Http\Status429',
|
||||
'requests_exception_http_431' => '\WpOrg\Requests\Exception\Http\Status431',
|
||||
'requests_exception_http_500' => '\WpOrg\Requests\Exception\Http\Status500',
|
||||
'requests_exception_http_501' => '\WpOrg\Requests\Exception\Http\Status501',
|
||||
'requests_exception_http_502' => '\WpOrg\Requests\Exception\Http\Status502',
|
||||
'requests_exception_http_503' => '\WpOrg\Requests\Exception\Http\Status503',
|
||||
'requests_exception_http_504' => '\WpOrg\Requests\Exception\Http\Status504',
|
||||
'requests_exception_http_505' => '\WpOrg\Requests\Exception\Http\Status505',
|
||||
'requests_exception_http_511' => '\WpOrg\Requests\Exception\Http\Status511',
|
||||
'requests_exception_http_unknown' => '\WpOrg\Requests\Exception\Http\StatusUnknown',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the autoloader.
|
||||
*
|
||||
* Note: the autoloader is *prepended* in the autoload queue.
|
||||
* This is done to ensure that the Requests 2.0 autoloader takes precedence
|
||||
* over a potentially (dependency-registered) Requests 1.x autoloader.
|
||||
*
|
||||
* @internal This method contains a safeguard against the autoloader being
|
||||
* registered multiple times. This safeguard uses a global constant to
|
||||
* (hopefully/in most cases) still function correctly, even if the
|
||||
* class would be renamed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
if (defined('REQUESTS_AUTOLOAD_REGISTERED') === false) {
|
||||
spl_autoload_register([self::class, 'load'], true);
|
||||
define('REQUESTS_AUTOLOAD_REGISTERED', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader.
|
||||
*
|
||||
* @param string $class_name Name of the class name to load.
|
||||
*
|
||||
* @return bool Whether a class was loaded or not.
|
||||
*/
|
||||
public static function load($class_name) {
|
||||
// Check that the class starts with "Requests" (PSR-0) or "WpOrg\Requests" (PSR-4).
|
||||
$psr_4_prefix_pos = strpos($class_name, 'WpOrg\\Requests\\');
|
||||
|
||||
if (stripos($class_name, 'Requests') !== 0 && $psr_4_prefix_pos !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$class_lower = strtolower($class_name);
|
||||
|
||||
if ($class_lower === 'requests') {
|
||||
// Reference to the original PSR-0 Requests class.
|
||||
$file = dirname(__DIR__) . '/library/Requests.php';
|
||||
} elseif ($psr_4_prefix_pos === 0) {
|
||||
// PSR-4 classname.
|
||||
$file = __DIR__ . '/' . strtr(substr($class_name, 15), '\\', '/') . '.php';
|
||||
}
|
||||
|
||||
if (isset($file) && file_exists($file)) {
|
||||
include $file;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Okay, so the class starts with "Requests", but we couldn't find the file.
|
||||
* If this is one of the deprecated/renamed PSR-0 classes being requested,
|
||||
* let's alias it to the new name and throw a deprecation notice.
|
||||
*/
|
||||
if (isset(self::$deprecated_classes[$class_lower])) {
|
||||
/*
|
||||
* Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
|
||||
* by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
|
||||
* The constant needs to be defined before the first deprecated class is requested
|
||||
* via this autoloader.
|
||||
*/
|
||||
if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
||||
trigger_error(
|
||||
'The PSR-0 `Requests_...` class names in the Request library are deprecated.'
|
||||
. ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
// Prevent the deprecation notice from being thrown twice.
|
||||
if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
|
||||
define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Create an alias and let the autoloader recursively kick in to load the PSR-4 class.
|
||||
return class_alias(self::$deprecated_classes[$class_lower], $class_name, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
api/vendor/rmccue/requests/src/Capability.php
vendored
Normal file
36
api/vendor/rmccue/requests/src/Capability.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Capability interface declaring the known capabilities.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
/**
|
||||
* Capability interface declaring the known capabilities.
|
||||
*
|
||||
* This is used as the authoritative source for which capabilities can be queried.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
interface Capability {
|
||||
|
||||
/**
|
||||
* Support for SSL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SSL = 'ssl';
|
||||
|
||||
/**
|
||||
* Collection of all capabilities supported in Requests.
|
||||
*
|
||||
* Note: this does not automatically mean that the capability will be supported for your chosen transport!
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
const ALL = [
|
||||
self::SSL,
|
||||
];
|
||||
}
|
||||
522
api/vendor/rmccue/requests/src/Cookie.php
vendored
Normal file
522
api/vendor/rmccue/requests/src/Cookie.php
vendored
Normal file
@@ -0,0 +1,522 @@
|
||||
<?php
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests\Cookies
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Iri;
|
||||
use WpOrg\Requests\Response\Headers;
|
||||
use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* Cookie storage object
|
||||
*
|
||||
* @package Requests\Cookies
|
||||
*/
|
||||
class Cookie {
|
||||
/**
|
||||
* Cookie name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Cookie value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Cookie attributes
|
||||
*
|
||||
* Valid keys are (currently) path, domain, expires, max-age, secure and
|
||||
* httponly.
|
||||
*
|
||||
* @var \WpOrg\Requests\Utility\CaseInsensitiveDictionary|array Array-like object
|
||||
*/
|
||||
public $attributes = [];
|
||||
|
||||
/**
|
||||
* Cookie flags
|
||||
*
|
||||
* Valid keys are (currently) creation, last-access, persistent and
|
||||
* host-only.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $flags = [];
|
||||
|
||||
/**
|
||||
* Reference time for relative calculations
|
||||
*
|
||||
* This is used in place of `time()` when calculating Max-Age expiration and
|
||||
* checking time validity.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $reference_time = 0;
|
||||
|
||||
/**
|
||||
* Create a new cookie object
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array|\WpOrg\Requests\Utility\CaseInsensitiveDictionary $attributes Associative array of attribute data
|
||||
* @param array $flags
|
||||
* @param int|null $reference_time
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $name argument is not a string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $value argument is not a string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $attributes argument is not an array or iterable object with array access.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $flags argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $reference_time argument is not an integer or null.
|
||||
*/
|
||||
public function __construct($name, $value, $attributes = [], $flags = [], $reference_time = null) {
|
||||
if (is_string($name) === false) {
|
||||
throw InvalidArgument::create(1, '$name', 'string', gettype($name));
|
||||
}
|
||||
|
||||
if (is_string($value) === false) {
|
||||
throw InvalidArgument::create(2, '$value', 'string', gettype($value));
|
||||
}
|
||||
|
||||
if (InputValidator::has_array_access($attributes) === false || InputValidator::is_iterable($attributes) === false) {
|
||||
throw InvalidArgument::create(3, '$attributes', 'array|ArrayAccess&Traversable', gettype($attributes));
|
||||
}
|
||||
|
||||
if (is_array($flags) === false) {
|
||||
throw InvalidArgument::create(4, '$flags', 'array', gettype($flags));
|
||||
}
|
||||
|
||||
if ($reference_time !== null && is_int($reference_time) === false) {
|
||||
throw InvalidArgument::create(5, '$reference_time', 'integer|null', gettype($reference_time));
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
$this->attributes = $attributes;
|
||||
$default_flags = [
|
||||
'creation' => time(),
|
||||
'last-access' => time(),
|
||||
'persistent' => false,
|
||||
'host-only' => true,
|
||||
];
|
||||
$this->flags = array_merge($default_flags, $flags);
|
||||
|
||||
$this->reference_time = time();
|
||||
if ($reference_time !== null) {
|
||||
$this->reference_time = $reference_time;
|
||||
}
|
||||
|
||||
$this->normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie value
|
||||
*
|
||||
* Attributes and other data can be accessed via methods.
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a cookie is expired.
|
||||
*
|
||||
* Checks the age against $this->reference_time to determine if the cookie
|
||||
* is expired.
|
||||
*
|
||||
* @return boolean True if expired, false if time is valid.
|
||||
*/
|
||||
public function is_expired() {
|
||||
// RFC6265, s. 4.1.2.2:
|
||||
// If a cookie has both the Max-Age and the Expires attribute, the Max-
|
||||
// Age attribute has precedence and controls the expiration date of the
|
||||
// cookie.
|
||||
if (isset($this->attributes['max-age'])) {
|
||||
$max_age = $this->attributes['max-age'];
|
||||
return $max_age < $this->reference_time;
|
||||
}
|
||||
|
||||
if (isset($this->attributes['expires'])) {
|
||||
$expires = $this->attributes['expires'];
|
||||
return $expires < $this->reference_time;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a cookie is valid for a given URI
|
||||
*
|
||||
* @param \WpOrg\Requests\Iri $uri URI to check
|
||||
* @return boolean Whether the cookie is valid for the given URI
|
||||
*/
|
||||
public function uri_matches(Iri $uri) {
|
||||
if (!$this->domain_matches($uri->host)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->path_matches($uri->path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return empty($this->attributes['secure']) || $uri->scheme === 'https';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a cookie is valid for a given domain
|
||||
*
|
||||
* @param string $domain Domain to check
|
||||
* @return boolean Whether the cookie is valid for the given domain
|
||||
*/
|
||||
public function domain_matches($domain) {
|
||||
if (is_string($domain) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->attributes['domain'])) {
|
||||
// Cookies created manually; cookies created by Requests will set
|
||||
// the domain to the requested domain
|
||||
return true;
|
||||
}
|
||||
|
||||
$cookie_domain = $this->attributes['domain'];
|
||||
if ($cookie_domain === $domain) {
|
||||
// The cookie domain and the passed domain are identical.
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the cookie is marked as host-only and we don't have an exact
|
||||
// match, reject the cookie
|
||||
if ($this->flags['host-only'] === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($domain) <= strlen($cookie_domain)) {
|
||||
// For obvious reasons, the cookie domain cannot be a suffix if the passed domain
|
||||
// is shorter than the cookie domain
|
||||
return false;
|
||||
}
|
||||
|
||||
if (substr($domain, -1 * strlen($cookie_domain)) !== $cookie_domain) {
|
||||
// The cookie domain should be a suffix of the passed domain.
|
||||
return false;
|
||||
}
|
||||
|
||||
$prefix = substr($domain, 0, strlen($domain) - strlen($cookie_domain));
|
||||
if (substr($prefix, -1) !== '.') {
|
||||
// The last character of the passed domain that is not included in the
|
||||
// domain string should be a %x2E (".") character.
|
||||
return false;
|
||||
}
|
||||
|
||||
// The passed domain should be a host name (i.e., not an IP address).
|
||||
return !preg_match('#^(.+\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a cookie is valid for a given path
|
||||
*
|
||||
* From the path-match check in RFC 6265 section 5.1.4
|
||||
*
|
||||
* @param string $request_path Path to check
|
||||
* @return boolean Whether the cookie is valid for the given path
|
||||
*/
|
||||
public function path_matches($request_path) {
|
||||
if (empty($request_path)) {
|
||||
// Normalize empty path to root
|
||||
$request_path = '/';
|
||||
}
|
||||
|
||||
if (!isset($this->attributes['path'])) {
|
||||
// Cookies created manually; cookies created by Requests will set
|
||||
// the path to the requested path
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_scalar($request_path) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cookie_path = $this->attributes['path'];
|
||||
|
||||
if ($cookie_path === $request_path) {
|
||||
// The cookie-path and the request-path are identical.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strlen($request_path) > strlen($cookie_path) && substr($request_path, 0, strlen($cookie_path)) === $cookie_path) {
|
||||
if (substr($cookie_path, -1) === '/') {
|
||||
// The cookie-path is a prefix of the request-path, and the last
|
||||
// character of the cookie-path is %x2F ("/").
|
||||
return true;
|
||||
}
|
||||
|
||||
if (substr($request_path, strlen($cookie_path), 1) === '/') {
|
||||
// The cookie-path is a prefix of the request-path, and the
|
||||
// first character of the request-path that is not included in
|
||||
// the cookie-path is a %x2F ("/") character.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize cookie and attributes
|
||||
*
|
||||
* @return boolean Whether the cookie was successfully normalized
|
||||
*/
|
||||
public function normalize() {
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
$orig_value = $value;
|
||||
$value = $this->normalize_attribute($key, $value);
|
||||
if ($value === null) {
|
||||
unset($this->attributes[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value !== $orig_value) {
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an individual cookie attribute
|
||||
*
|
||||
* Handles parsing individual attributes from the cookie values.
|
||||
*
|
||||
* @param string $name Attribute name
|
||||
* @param string|boolean $value Attribute value (string value, or true if empty/flag)
|
||||
* @return mixed Value if available, or null if the attribute value is invalid (and should be skipped)
|
||||
*/
|
||||
protected function normalize_attribute($name, $value) {
|
||||
switch (strtolower($name)) {
|
||||
case 'expires':
|
||||
// Expiration parsing, as per RFC 6265 section 5.2.1
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$expiry_time = strtotime($value);
|
||||
if ($expiry_time === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $expiry_time;
|
||||
|
||||
case 'max-age':
|
||||
// Expiration parsing, as per RFC 6265 section 5.2.2
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Check that we have a valid age
|
||||
if (!preg_match('/^-?\d+$/', $value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$delta_seconds = (int) $value;
|
||||
if ($delta_seconds <= 0) {
|
||||
$expiry_time = 0;
|
||||
} else {
|
||||
$expiry_time = $this->reference_time + $delta_seconds;
|
||||
}
|
||||
|
||||
return $expiry_time;
|
||||
|
||||
case 'domain':
|
||||
// Domains are not required as per RFC 6265 section 5.2.3
|
||||
if (empty($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Domain normalization, as per RFC 6265 section 5.2.3
|
||||
if ($value[0] === '.') {
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Cookie header
|
||||
*
|
||||
* This is used when sending cookies to a server.
|
||||
*
|
||||
* @return string Cookie formatted for Cookie header
|
||||
*/
|
||||
public function format_for_header() {
|
||||
return sprintf('%s=%s', $this->name, $this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a cookie for a Set-Cookie header
|
||||
*
|
||||
* This is used when sending cookies to clients. This isn't really
|
||||
* applicable to client-side usage, but might be handy for debugging.
|
||||
*
|
||||
* @return string Cookie formatted for Set-Cookie header
|
||||
*/
|
||||
public function format_for_set_cookie() {
|
||||
$header_value = $this->format_for_header();
|
||||
if (!empty($this->attributes)) {
|
||||
$parts = [];
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
// Ignore non-associative attributes
|
||||
if (is_numeric($key)) {
|
||||
$parts[] = $value;
|
||||
} else {
|
||||
$parts[] = sprintf('%s=%s', $key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$header_value .= '; ' . implode('; ', $parts);
|
||||
}
|
||||
|
||||
return $header_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a cookie string into a cookie object
|
||||
*
|
||||
* Based on Mozilla's parsing code in Firefox and related projects, which
|
||||
* is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265
|
||||
* specifies some of this handling, but not in a thorough manner.
|
||||
*
|
||||
* @param string $cookie_header Cookie header value (from a Set-Cookie header)
|
||||
* @param string $name
|
||||
* @param int|null $reference_time
|
||||
* @return \WpOrg\Requests\Cookie Parsed cookie object
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cookie_header argument is not a string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $name argument is not a string.
|
||||
*/
|
||||
public static function parse($cookie_header, $name = '', $reference_time = null) {
|
||||
if (is_string($cookie_header) === false) {
|
||||
throw InvalidArgument::create(1, '$cookie_header', 'string', gettype($cookie_header));
|
||||
}
|
||||
|
||||
if (is_string($name) === false) {
|
||||
throw InvalidArgument::create(2, '$name', 'string', gettype($name));
|
||||
}
|
||||
|
||||
$parts = explode(';', $cookie_header);
|
||||
$kvparts = array_shift($parts);
|
||||
|
||||
if (!empty($name)) {
|
||||
$value = $cookie_header;
|
||||
} elseif (strpos($kvparts, '=') === false) {
|
||||
// Some sites might only have a value without the equals separator.
|
||||
// Deviate from RFC 6265 and pretend it was actually a blank name
|
||||
// (`=foo`)
|
||||
//
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=169091
|
||||
$name = '';
|
||||
$value = $kvparts;
|
||||
} else {
|
||||
list($name, $value) = explode('=', $kvparts, 2);
|
||||
}
|
||||
|
||||
$name = trim($name);
|
||||
$value = trim($value);
|
||||
|
||||
// Attribute keys are handled case-insensitively
|
||||
$attributes = new CaseInsensitiveDictionary();
|
||||
|
||||
if (!empty($parts)) {
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '=') === false) {
|
||||
$part_key = $part;
|
||||
$part_value = true;
|
||||
} else {
|
||||
list($part_key, $part_value) = explode('=', $part, 2);
|
||||
$part_value = trim($part_value);
|
||||
}
|
||||
|
||||
$part_key = trim($part_key);
|
||||
$attributes[$part_key] = $part_value;
|
||||
}
|
||||
}
|
||||
|
||||
return new static($name, $value, $attributes, [], $reference_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all Set-Cookie headers from request headers
|
||||
*
|
||||
* @param \WpOrg\Requests\Response\Headers $headers Headers to parse from
|
||||
* @param \WpOrg\Requests\Iri|null $origin URI for comparing cookie origins
|
||||
* @param int|null $time Reference time for expiration calculation
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_from_headers(Headers $headers, Iri $origin = null, $time = null) {
|
||||
$cookie_headers = $headers->getValues('Set-Cookie');
|
||||
if (empty($cookie_headers)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$cookies = [];
|
||||
foreach ($cookie_headers as $header) {
|
||||
$parsed = self::parse($header, '', $time);
|
||||
|
||||
// Default domain/path attributes
|
||||
if (empty($parsed->attributes['domain']) && !empty($origin)) {
|
||||
$parsed->attributes['domain'] = $origin->host;
|
||||
$parsed->flags['host-only'] = true;
|
||||
} else {
|
||||
$parsed->flags['host-only'] = false;
|
||||
}
|
||||
|
||||
$path_is_valid = (!empty($parsed->attributes['path']) && $parsed->attributes['path'][0] === '/');
|
||||
if (!$path_is_valid && !empty($origin)) {
|
||||
$path = $origin->path;
|
||||
|
||||
// Default path normalization as per RFC 6265 section 5.1.4
|
||||
if (substr($path, 0, 1) !== '/') {
|
||||
// If the uri-path is empty or if the first character of
|
||||
// the uri-path is not a %x2F ("/") character, output
|
||||
// %x2F ("/") and skip the remaining steps.
|
||||
$path = '/';
|
||||
} elseif (substr_count($path, '/') === 1) {
|
||||
// If the uri-path contains no more than one %x2F ("/")
|
||||
// character, output %x2F ("/") and skip the remaining
|
||||
// step.
|
||||
$path = '/';
|
||||
} else {
|
||||
// Output the characters of the uri-path from the first
|
||||
// character up to, but not including, the right-most
|
||||
// %x2F ("/").
|
||||
$path = substr($path, 0, strrpos($path, '/'));
|
||||
}
|
||||
|
||||
$parsed->attributes['path'] = $path;
|
||||
}
|
||||
|
||||
// Reject invalid cookie domains
|
||||
if (!empty($origin) && !$parsed->domain_matches($origin->host)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cookies[$parsed->name] = $parsed;
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
}
|
||||
186
api/vendor/rmccue/requests/src/Cookie/Jar.php
vendored
Normal file
186
api/vendor/rmccue/requests/src/Cookie/Jar.php
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests\Cookies
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Cookie;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use ReturnTypeWillChange;
|
||||
use WpOrg\Requests\Cookie;
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\HookManager;
|
||||
use WpOrg\Requests\Iri;
|
||||
use WpOrg\Requests\Response;
|
||||
|
||||
/**
|
||||
* Cookie holder object
|
||||
*
|
||||
* @package Requests\Cookies
|
||||
*/
|
||||
class Jar implements ArrayAccess, IteratorAggregate {
|
||||
/**
|
||||
* Actual item data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = [];
|
||||
|
||||
/**
|
||||
* Create a new jar
|
||||
*
|
||||
* @param array $cookies Existing cookie values
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array.
|
||||
*/
|
||||
public function __construct($cookies = []) {
|
||||
if (is_array($cookies) === false) {
|
||||
throw InvalidArgument::create(1, '$cookies', 'array', gettype($cookies));
|
||||
}
|
||||
|
||||
$this->cookies = $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise cookie data into a \WpOrg\Requests\Cookie
|
||||
*
|
||||
* @param string|\WpOrg\Requests\Cookie $cookie
|
||||
* @return \WpOrg\Requests\Cookie
|
||||
*/
|
||||
public function normalize_cookie($cookie, $key = '') {
|
||||
if ($cookie instanceof Cookie) {
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
return Cookie::parse($cookie, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item exists
|
||||
*
|
||||
* @param string $offset Item key
|
||||
* @return boolean Does the item exist?
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset) {
|
||||
return isset($this->cookies[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the item
|
||||
*
|
||||
* @param string $offset Item key
|
||||
* @return string|null Item value (null if offsetExists is false)
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset) {
|
||||
if (!isset($this->cookies[$offset])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->cookies[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @param string $offset Item name
|
||||
* @param string $value Item value
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value) {
|
||||
if ($offset === null) {
|
||||
throw new Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
$this->cookies[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the given header
|
||||
*
|
||||
* @param string $offset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset) {
|
||||
unset($this->cookies[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the cookie handler with the request's hooking system
|
||||
*
|
||||
* @param \WpOrg\Requests\HookManager $hooks Hooking system
|
||||
*/
|
||||
public function register(HookManager $hooks) {
|
||||
$hooks->register('requests.before_request', [$this, 'before_request']);
|
||||
$hooks->register('requests.before_redirect_check', [$this, 'before_redirect_check']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Cookie header to a request if we have any
|
||||
*
|
||||
* As per RFC 6265, cookies are separated by '; '
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*/
|
||||
public function before_request($url, &$headers, &$data, &$type, &$options) {
|
||||
if (!$url instanceof Iri) {
|
||||
$url = new Iri($url);
|
||||
}
|
||||
|
||||
if (!empty($this->cookies)) {
|
||||
$cookies = [];
|
||||
foreach ($this->cookies as $key => $cookie) {
|
||||
$cookie = $this->normalize_cookie($cookie, $key);
|
||||
|
||||
// Skip expired cookies
|
||||
if ($cookie->is_expired()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($cookie->domain_matches($url->host)) {
|
||||
$cookies[] = $cookie->format_for_header();
|
||||
}
|
||||
}
|
||||
|
||||
$headers['Cookie'] = implode('; ', $cookies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all cookies from a response and attach them to the response
|
||||
*
|
||||
* @param \WpOrg\Requests\Response $response
|
||||
*/
|
||||
public function before_redirect_check(Response $response) {
|
||||
$url = $response->url;
|
||||
if (!$url instanceof Iri) {
|
||||
$url = new Iri($url);
|
||||
}
|
||||
|
||||
$cookies = Cookie::parse_from_headers($response->headers, $url);
|
||||
$this->cookies = array_merge($this->cookies, $cookies);
|
||||
$response->cookies = $this;
|
||||
}
|
||||
}
|
||||
66
api/vendor/rmccue/requests/src/Exception.php
vendored
Normal file
66
api/vendor/rmccue/requests/src/Exception.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use Exception as PHPException;
|
||||
|
||||
/**
|
||||
* Exception for HTTP requests
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
class Exception extends PHPException {
|
||||
/**
|
||||
* Type of exception
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Data associated with the exception
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* @param string $message Exception message
|
||||
* @param string $type Exception type
|
||||
* @param mixed $data Associated data
|
||||
* @param integer $code Exception numerical code, if applicable
|
||||
*/
|
||||
public function __construct($message, $type, $data = null, $code = 0) {
|
||||
parent::__construct($message, $code);
|
||||
|
||||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@see \Exception::getCode()}, but a string code.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives any relevant data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
47
api/vendor/rmccue/requests/src/Exception/ArgumentCount.php
vendored
Normal file
47
api/vendor/rmccue/requests/src/Exception/ArgumentCount.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace WpOrg\Requests\Exception;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
|
||||
/**
|
||||
* Exception for when an incorrect number of arguments are passed to a method.
|
||||
*
|
||||
* Typically, this exception is used when all arguments for a method are optional,
|
||||
* but certain arguments need to be passed together, i.e. a method which can be called
|
||||
* with no arguments or with two arguments, but not with one argument.
|
||||
*
|
||||
* Along the same lines, this exception is also used if a method expects an array
|
||||
* with a certain number of elements and the provided number of elements does not comply.
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
* @since 2.0.0
|
||||
*/
|
||||
final class ArgumentCount extends Exception {
|
||||
|
||||
/**
|
||||
* Create a new argument count exception with a standardized text.
|
||||
*
|
||||
* @param string $expected The argument count expected as a phrase.
|
||||
* For example: `at least 2 arguments` or `exactly 1 argument`.
|
||||
* @param int $received The actual argument count received.
|
||||
* @param string $type Exception type.
|
||||
*
|
||||
* @return \WpOrg\Requests\Exception\ArgumentCount
|
||||
*/
|
||||
public static function create($expected, $received, $type) {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
|
||||
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
|
||||
return new self(
|
||||
sprintf(
|
||||
'%s::%s() expects %s, %d given',
|
||||
$stack[1]['class'],
|
||||
$stack[1]['function'],
|
||||
$expected,
|
||||
$received
|
||||
),
|
||||
$type
|
||||
);
|
||||
}
|
||||
}
|
||||
78
api/vendor/rmccue/requests/src/Exception/Http.php
vendored
Normal file
78
api/vendor/rmccue/requests/src/Exception/Http.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\Http\StatusUnknown;
|
||||
|
||||
/**
|
||||
* Exception based on HTTP response
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
class Http extends Exception {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* There is no mechanism to pass in the status code, as this is set by the
|
||||
* subclass used. Reason phrases can vary, however.
|
||||
*
|
||||
* @param string|null $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($reason !== null) {
|
||||
$this->reason = $reason;
|
||||
}
|
||||
|
||||
$message = sprintf('%d %s', $this->code, $this->reason);
|
||||
parent::__construct($message, 'httpresponse', $data, $this->code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReason() {
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct exception class for a given error code
|
||||
*
|
||||
* @param int|bool $code HTTP status code, or false if unavailable
|
||||
* @return string Exception class name to use
|
||||
*/
|
||||
public static function get_class($code) {
|
||||
if (!$code) {
|
||||
return StatusUnknown::class;
|
||||
}
|
||||
|
||||
$class = sprintf('\WpOrg\Requests\Exception\Http\Status%d', $code);
|
||||
if (class_exists($class)) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return StatusUnknown::class;
|
||||
}
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status304.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status304.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 304 Not Modified responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 304 Not Modified responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status304 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 304;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Modified';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status305.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status305.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 305 Use Proxy responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 305 Use Proxy responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status305 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 305;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Use Proxy';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status306.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status306.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 306 Switch Proxy responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 306 Switch Proxy responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status306 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 306;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Switch Proxy';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status400.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status400.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 400 Bad Request responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status400 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 400;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Request';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status401.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status401.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 401 Unauthorized responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status401 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 401;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unauthorized';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status402.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status402.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 402 Payment Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status402 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 402;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Payment Required';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status403.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status403.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 403 Forbidden responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status403 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 403;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Forbidden';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status404.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status404.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 404 Not Found responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status404 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 404;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Found';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status405.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status405.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 405 Method Not Allowed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status405 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 405;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Method Not Allowed';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status406.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status406.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 406 Not Acceptable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status406 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 406;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Acceptable';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status407.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status407.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 407 Proxy Authentication Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status407 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 407;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Proxy Authentication Required';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status408.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status408.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 408 Request Timeout responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status408 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 408;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Timeout';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status409.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status409.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 409 Conflict responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status409 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 409;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Conflict';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status410.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status410.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 410 Gone responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status410 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 410;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gone';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status411.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status411.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 411 Length Required responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status411 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 411;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Length Required';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status412.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status412.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 412 Precondition Failed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status412 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 412;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Failed';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status413.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status413.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 413 Request Entity Too Large responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status413 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 413;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Entity Too Large';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status414.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status414.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 414 Request-URI Too Large responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status414 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 414;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request-URI Too Large';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status415.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status415.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 415 Unsupported Media Type responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status415 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 415;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unsupported Media Type';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status416.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status416.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 416 Requested Range Not Satisfiable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status416 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 416;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Requested Range Not Satisfiable';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status417.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status417.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 417 Expectation Failed responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status417 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 417;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Expectation Failed';
|
||||
}
|
||||
35
api/vendor/rmccue/requests/src/Exception/Http/Status418.php
vendored
Normal file
35
api/vendor/rmccue/requests/src/Exception/Http/Status418.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc2324
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 418 I'm A Teapot responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc2324
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status418 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 418;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = "I'm A Teapot";
|
||||
}
|
||||
35
api/vendor/rmccue/requests/src/Exception/Http/Status428.php
vendored
Normal file
35
api/vendor/rmccue/requests/src/Exception/Http/Status428.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 428 Precondition Required responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status428 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 428;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Precondition Required';
|
||||
}
|
||||
35
api/vendor/rmccue/requests/src/Exception/Http/Status429.php
vendored
Normal file
35
api/vendor/rmccue/requests/src/Exception/Http/Status429.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 429 Too Many Requests responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/draft-nottingham-http-new-status-04
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status429 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 429;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Too Many Requests';
|
||||
}
|
||||
35
api/vendor/rmccue/requests/src/Exception/Http/Status431.php
vendored
Normal file
35
api/vendor/rmccue/requests/src/Exception/Http/Status431.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 431 Request Header Fields Too Large responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status431 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 431;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Request Header Fields Too Large';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status500.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status500.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 500 Internal Server Error responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status500 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 500;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Internal Server Error';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status501.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status501.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 501 Not Implemented responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status501 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 501;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Not Implemented';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status502.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status502.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 502 Bad Gateway responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status502 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 502;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Bad Gateway';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status503.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status503.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 503 Service Unavailable responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status503 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 503;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Service Unavailable';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status504.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status504.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 504 Gateway Timeout responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status504 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 504;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Gateway Timeout';
|
||||
}
|
||||
31
api/vendor/rmccue/requests/src/Exception/Http/Status505.php
vendored
Normal file
31
api/vendor/rmccue/requests/src/Exception/Http/Status505.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 505 HTTP Version Not Supported responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status505 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 505;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'HTTP Version Not Supported';
|
||||
}
|
||||
35
api/vendor/rmccue/requests/src/Exception/Http/Status511.php
vendored
Normal file
35
api/vendor/rmccue/requests/src/Exception/Http/Status511.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
|
||||
/**
|
||||
* Exception for 511 Network Authentication Required responses
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc6585
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Status511 extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = 511;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Network Authentication Required';
|
||||
}
|
||||
49
api/vendor/rmccue/requests/src/Exception/Http/StatusUnknown.php
vendored
Normal file
49
api/vendor/rmccue/requests/src/Exception/Http/StatusUnknown.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Http;
|
||||
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
use WpOrg\Requests\Response;
|
||||
|
||||
/**
|
||||
* Exception for unknown status responses
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class StatusUnknown extends Http {
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer|bool Code if available, false if an error occurred
|
||||
*/
|
||||
protected $code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception
|
||||
*
|
||||
* If `$data` is an instance of {@see \WpOrg\Requests\Response}, uses the status
|
||||
* code from it. Otherwise, sets as 0
|
||||
*
|
||||
* @param string|null $reason Reason phrase
|
||||
* @param mixed $data Associated data
|
||||
*/
|
||||
public function __construct($reason = null, $data = null) {
|
||||
if ($data instanceof Response) {
|
||||
$this->code = (int) $data->status_code;
|
||||
}
|
||||
|
||||
parent::__construct($reason, $data);
|
||||
}
|
||||
}
|
||||
41
api/vendor/rmccue/requests/src/Exception/InvalidArgument.php
vendored
Normal file
41
api/vendor/rmccue/requests/src/Exception/InvalidArgument.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace WpOrg\Requests\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Exception for an invalid argument passed.
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
* @since 2.0.0
|
||||
*/
|
||||
final class InvalidArgument extends InvalidArgumentException {
|
||||
|
||||
/**
|
||||
* Create a new invalid argument exception with a standardized text.
|
||||
*
|
||||
* @param int $position The argument position in the function signature. 1-based.
|
||||
* @param string $name The argument name in the function signature.
|
||||
* @param string $expected The argument type expected as a string.
|
||||
* @param string $received The actual argument type received.
|
||||
*
|
||||
* @return \WpOrg\Requests\Exception\InvalidArgument
|
||||
*/
|
||||
public static function create($position, $name, $expected, $received) {
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
|
||||
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
|
||||
return new self(
|
||||
sprintf(
|
||||
'%s::%s(): Argument #%d (%s) must be of type %s, %s given',
|
||||
$stack[1]['class'],
|
||||
$stack[1]['function'],
|
||||
$position,
|
||||
$name,
|
||||
$expected,
|
||||
$received
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
17
api/vendor/rmccue/requests/src/Exception/Transport.php
vendored
Normal file
17
api/vendor/rmccue/requests/src/Exception/Transport.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Transport Exception
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
|
||||
/**
|
||||
* Transport Exception
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
class Transport extends Exception {}
|
||||
80
api/vendor/rmccue/requests/src/Exception/Transport/Curl.php
vendored
Normal file
80
api/vendor/rmccue/requests/src/Exception/Transport/Curl.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* CURL Transport Exception.
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception\Transport;
|
||||
|
||||
use WpOrg\Requests\Exception\Transport;
|
||||
|
||||
/**
|
||||
* CURL Transport Exception.
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
final class Curl extends Transport {
|
||||
|
||||
const EASY = 'cURLEasy';
|
||||
const MULTI = 'cURLMulti';
|
||||
const SHARE = 'cURLShare';
|
||||
|
||||
/**
|
||||
* cURL error code
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $code = -1;
|
||||
|
||||
/**
|
||||
* Which type of cURL error
|
||||
*
|
||||
* EASY|MULTI|SHARE
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'Unknown';
|
||||
|
||||
/**
|
||||
* Clear text error message
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reason = 'Unknown';
|
||||
|
||||
/**
|
||||
* Create a new exception.
|
||||
*
|
||||
* @param string $message Exception message.
|
||||
* @param string $type Exception type.
|
||||
* @param mixed $data Associated data, if applicable.
|
||||
* @param int $code Exception numerical code, if applicable.
|
||||
*/
|
||||
public function __construct($message, $type, $data = null, $code = 0) {
|
||||
if ($type !== null) {
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
if ($code !== null) {
|
||||
$this->code = (int) $code;
|
||||
}
|
||||
|
||||
if ($message !== null) {
|
||||
$this->reason = $message;
|
||||
}
|
||||
|
||||
$message = sprintf('%d %s', $this->code, $this->reason);
|
||||
parent::__construct($message, $this->type, $data, $this->code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReason() {
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
}
|
||||
33
api/vendor/rmccue/requests/src/HookManager.php
vendored
Normal file
33
api/vendor/rmccue/requests/src/HookManager.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests\EventDispatcher
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
/**
|
||||
* Event dispatcher
|
||||
*
|
||||
* @package Requests\EventDispatcher
|
||||
*/
|
||||
interface HookManager {
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callable $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0);
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
*/
|
||||
public function dispatch($hook, $parameters = []);
|
||||
}
|
||||
99
api/vendor/rmccue/requests/src/Hooks.php
vendored
Normal file
99
api/vendor/rmccue/requests/src/Hooks.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests\EventDispatcher
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\HookManager;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* Handles adding and dispatching events
|
||||
*
|
||||
* @package Requests\EventDispatcher
|
||||
*/
|
||||
class Hooks implements HookManager {
|
||||
/**
|
||||
* Registered callbacks for each hook
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hooks = [];
|
||||
|
||||
/**
|
||||
* Register a callback for a hook
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param callable $callback Function/method to call on event
|
||||
* @param int $priority Priority number. <0 is executed earlier, >0 is executed later
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $hook argument is not a string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $callback argument is not callable.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $priority argument is not an integer.
|
||||
*/
|
||||
public function register($hook, $callback, $priority = 0) {
|
||||
if (is_string($hook) === false) {
|
||||
throw InvalidArgument::create(1, '$hook', 'string', gettype($hook));
|
||||
}
|
||||
|
||||
if (is_callable($callback) === false) {
|
||||
throw InvalidArgument::create(2, '$callback', 'callable', gettype($callback));
|
||||
}
|
||||
|
||||
if (InputValidator::is_numeric_array_key($priority) === false) {
|
||||
throw InvalidArgument::create(3, '$priority', 'integer', gettype($priority));
|
||||
}
|
||||
|
||||
if (!isset($this->hooks[$hook])) {
|
||||
$this->hooks[$hook] = [
|
||||
$priority => [],
|
||||
];
|
||||
} elseif (!isset($this->hooks[$hook][$priority])) {
|
||||
$this->hooks[$hook][$priority] = [];
|
||||
}
|
||||
|
||||
$this->hooks[$hook][$priority][] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a message
|
||||
*
|
||||
* @param string $hook Hook name
|
||||
* @param array $parameters Parameters to pass to callbacks
|
||||
* @return boolean Successfulness
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $hook argument is not a string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $parameters argument is not an array.
|
||||
*/
|
||||
public function dispatch($hook, $parameters = []) {
|
||||
if (is_string($hook) === false) {
|
||||
throw InvalidArgument::create(1, '$hook', 'string', gettype($hook));
|
||||
}
|
||||
|
||||
// Check strictly against array, as Array* objects don't work in combination with `call_user_func_array()`.
|
||||
if (is_array($parameters) === false) {
|
||||
throw InvalidArgument::create(2, '$parameters', 'array', gettype($parameters));
|
||||
}
|
||||
|
||||
if (empty($this->hooks[$hook])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($parameters)) {
|
||||
// Strip potential keys from the array to prevent them being interpreted as parameter names in PHP 8.0.
|
||||
$parameters = array_values($parameters);
|
||||
}
|
||||
|
||||
ksort($this->hooks[$hook]);
|
||||
|
||||
foreach ($this->hooks[$hook] as $priority => $hooked) {
|
||||
foreach ($hooked as $callback) {
|
||||
$callback(...$parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
412
api/vendor/rmccue/requests/src/IdnaEncoder.php
vendored
Normal file
412
api/vendor/rmccue/requests/src/IdnaEncoder.php
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* IDNA URL encoder
|
||||
*
|
||||
* Note: Not fully compliant, as nameprep does nothing yet.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3490 IDNA specification
|
||||
* @link https://tools.ietf.org/html/rfc3492 Punycode/Bootstrap specification
|
||||
*/
|
||||
class IdnaEncoder {
|
||||
/**
|
||||
* ACE prefix used for IDNA
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3490#section-5
|
||||
* @var string
|
||||
*/
|
||||
const ACE_PREFIX = 'xn--';
|
||||
|
||||
/**
|
||||
* Maximum length of a IDNA URL in ASCII.
|
||||
*
|
||||
* @see \WpOrg\Requests\IdnaEncoder::to_ascii()
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAX_LENGTH = 64;
|
||||
|
||||
/**#@+
|
||||
* Bootstrap constant for Punycode
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3492#section-5
|
||||
* @var int
|
||||
*/
|
||||
const BOOTSTRAP_BASE = 36;
|
||||
const BOOTSTRAP_TMIN = 1;
|
||||
const BOOTSTRAP_TMAX = 26;
|
||||
const BOOTSTRAP_SKEW = 38;
|
||||
const BOOTSTRAP_DAMP = 700;
|
||||
const BOOTSTRAP_INITIAL_BIAS = 72;
|
||||
const BOOTSTRAP_INITIAL_N = 128;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Encode a hostname using Punycode
|
||||
*
|
||||
* @param string|Stringable $hostname Hostname
|
||||
* @return string Punycode-encoded hostname
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
|
||||
*/
|
||||
public static function encode($hostname) {
|
||||
if (InputValidator::is_string_or_stringable($hostname) === false) {
|
||||
throw InvalidArgument::create(1, '$hostname', 'string|Stringable', gettype($hostname));
|
||||
}
|
||||
|
||||
$parts = explode('.', $hostname);
|
||||
foreach ($parts as &$part) {
|
||||
$part = self::to_ascii($part);
|
||||
}
|
||||
|
||||
return implode('.', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 text string to an ASCII string using Punycode
|
||||
*
|
||||
* @param string $text ASCII or UTF-8 string (max length 64 characters)
|
||||
* @return string ASCII string
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception Provided string longer than 64 ASCII characters (`idna.provided_too_long`)
|
||||
* @throws \WpOrg\Requests\Exception Prepared string longer than 64 ASCII characters (`idna.prepared_too_long`)
|
||||
* @throws \WpOrg\Requests\Exception Provided string already begins with xn-- (`idna.provided_is_prefixed`)
|
||||
* @throws \WpOrg\Requests\Exception Encoded string longer than 64 ASCII characters (`idna.encoded_too_long`)
|
||||
*/
|
||||
public static function to_ascii($text) {
|
||||
// Step 1: Check if the text is already ASCII
|
||||
if (self::is_ascii($text)) {
|
||||
// Skip to step 7
|
||||
if (strlen($text) < self::MAX_LENGTH) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
throw new Exception('Provided string is too long', 'idna.provided_too_long', $text);
|
||||
}
|
||||
|
||||
// Step 2: nameprep
|
||||
$text = self::nameprep($text);
|
||||
|
||||
// Step 3: UseSTD3ASCIIRules is false, continue
|
||||
// Step 4: Check if it's ASCII now
|
||||
if (self::is_ascii($text)) {
|
||||
// Skip to step 7
|
||||
/*
|
||||
* As the `nameprep()` method returns the original string, this code will never be reached until
|
||||
* that method is properly implemented.
|
||||
*/
|
||||
// @codeCoverageIgnoreStart
|
||||
if (strlen($text) < self::MAX_LENGTH) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
throw new Exception('Prepared string is too long', 'idna.prepared_too_long', $text);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// Step 5: Check ACE prefix
|
||||
if (strpos($text, self::ACE_PREFIX) === 0) {
|
||||
throw new Exception('Provided string begins with ACE prefix', 'idna.provided_is_prefixed', $text);
|
||||
}
|
||||
|
||||
// Step 6: Encode with Punycode
|
||||
$text = self::punycode_encode($text);
|
||||
|
||||
// Step 7: Prepend ACE prefix
|
||||
$text = self::ACE_PREFIX . $text;
|
||||
|
||||
// Step 8: Check size
|
||||
if (strlen($text) < self::MAX_LENGTH) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
throw new Exception('Encoded string is too long', 'idna.encoded_too_long', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given text string contains only ASCII characters
|
||||
*
|
||||
* @internal (Testing found regex was the fastest implementation)
|
||||
*
|
||||
* @param string $text
|
||||
* @return bool Is the text string ASCII-only?
|
||||
*/
|
||||
protected static function is_ascii($text) {
|
||||
return (preg_match('/(?:[^\x00-\x7F])/', $text) !== 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a text string for use as an IDNA name
|
||||
*
|
||||
* @todo Implement this based on RFC 3491 and the newer 5891
|
||||
* @param string $text
|
||||
* @return string Prepared string
|
||||
*/
|
||||
protected static function nameprep($text) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to a UCS-4 codepoint array
|
||||
*
|
||||
* Based on \WpOrg\Requests\Iri::replace_invalid_with_pct_encoding()
|
||||
*
|
||||
* @param string $input
|
||||
* @return array Unicode code points
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception Invalid UTF-8 codepoint (`idna.invalidcodepoint`)
|
||||
*/
|
||||
protected static function utf8_to_codepoints($input) {
|
||||
$codepoints = [];
|
||||
|
||||
// Get number of bytes
|
||||
$strlen = strlen($input);
|
||||
|
||||
// phpcs:ignore Generic.CodeAnalysis.JumbledIncrementer -- This is a deliberate choice.
|
||||
for ($position = 0; $position < $strlen; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
if ((~$value & 0x80) === 0x80) { // One byte sequence:
|
||||
$character = $value;
|
||||
$length = 1;
|
||||
$remaining = 0;
|
||||
} elseif (($value & 0xE0) === 0xC0) { // Two byte sequence:
|
||||
$character = ($value & 0x1F) << 6;
|
||||
$length = 2;
|
||||
$remaining = 1;
|
||||
} elseif (($value & 0xF0) === 0xE0) { // Three byte sequence:
|
||||
$character = ($value & 0x0F) << 12;
|
||||
$length = 3;
|
||||
$remaining = 2;
|
||||
} elseif (($value & 0xF8) === 0xF0) { // Four byte sequence:
|
||||
$character = ($value & 0x07) << 18;
|
||||
$length = 4;
|
||||
$remaining = 3;
|
||||
} else { // Invalid byte:
|
||||
throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $value);
|
||||
}
|
||||
|
||||
if ($remaining > 0) {
|
||||
if ($position + $length > $strlen) {
|
||||
throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
for ($position++; $remaining > 0; $position++) {
|
||||
$value = ord($input[$position]);
|
||||
|
||||
// If it is invalid, count the sequence as invalid and reprocess the current byte:
|
||||
if (($value & 0xC0) !== 0x80) {
|
||||
throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
--$remaining;
|
||||
$character |= ($value & 0x3F) << ($remaining * 6);
|
||||
}
|
||||
|
||||
$position--;
|
||||
}
|
||||
|
||||
if (// Non-shortest form sequences are invalid
|
||||
$length > 1 && $character <= 0x7F
|
||||
|| $length > 2 && $character <= 0x7FF
|
||||
|| $length > 3 && $character <= 0xFFFF
|
||||
// Outside of range of ucschar codepoints
|
||||
// Noncharacters
|
||||
|| ($character & 0xFFFE) === 0xFFFE
|
||||
|| $character >= 0xFDD0 && $character <= 0xFDEF
|
||||
|| (
|
||||
// Everything else not in ucschar
|
||||
$character > 0xD7FF && $character < 0xF900
|
||||
|| $character < 0x20
|
||||
|| $character > 0x7E && $character < 0xA0
|
||||
|| $character > 0xEFFFD
|
||||
)
|
||||
) {
|
||||
throw new Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
|
||||
}
|
||||
|
||||
$codepoints[] = $character;
|
||||
}
|
||||
|
||||
return $codepoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC3492-compliant encoder
|
||||
*
|
||||
* @internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
|
||||
*
|
||||
* @param string $input UTF-8 encoded string to encode
|
||||
* @return string Punycode-encoded string
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)
|
||||
*/
|
||||
public static function punycode_encode($input) {
|
||||
$output = '';
|
||||
// let n = initial_n
|
||||
$n = self::BOOTSTRAP_INITIAL_N;
|
||||
// let delta = 0
|
||||
$delta = 0;
|
||||
// let bias = initial_bias
|
||||
$bias = self::BOOTSTRAP_INITIAL_BIAS;
|
||||
// let h = b = the number of basic code points in the input
|
||||
$h = 0;
|
||||
$b = 0; // see loop
|
||||
// copy them to the output in order
|
||||
$codepoints = self::utf8_to_codepoints($input);
|
||||
$extended = [];
|
||||
|
||||
foreach ($codepoints as $char) {
|
||||
if ($char < 128) {
|
||||
// Character is valid ASCII
|
||||
// TODO: this should also check if it's valid for a URL
|
||||
$output .= chr($char);
|
||||
$h++;
|
||||
|
||||
// Check if the character is non-ASCII, but below initial n
|
||||
// This never occurs for Punycode, so ignore in coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
} elseif ($char < $n) {
|
||||
throw new Exception('Invalid character', 'idna.character_outside_domain', $char);
|
||||
// @codeCoverageIgnoreEnd
|
||||
} else {
|
||||
$extended[$char] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$extended = array_keys($extended);
|
||||
sort($extended);
|
||||
$b = $h;
|
||||
// [copy them] followed by a delimiter if b > 0
|
||||
if (strlen($output) > 0) {
|
||||
$output .= '-';
|
||||
}
|
||||
|
||||
// {if the input contains a non-basic code point < n then fail}
|
||||
// while h < length(input) do begin
|
||||
$codepointcount = count($codepoints);
|
||||
while ($h < $codepointcount) {
|
||||
// let m = the minimum code point >= n in the input
|
||||
$m = array_shift($extended);
|
||||
//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
|
||||
// let delta = delta + (m - n) * (h + 1), fail on overflow
|
||||
$delta += ($m - $n) * ($h + 1);
|
||||
// let n = m
|
||||
$n = $m;
|
||||
// for each code point c in the input (in order) do begin
|
||||
for ($num = 0; $num < $codepointcount; $num++) {
|
||||
$c = $codepoints[$num];
|
||||
// if c < n then increment delta, fail on overflow
|
||||
if ($c < $n) {
|
||||
$delta++;
|
||||
} elseif ($c === $n) { // if c == n then begin
|
||||
// let q = delta
|
||||
$q = $delta;
|
||||
// for k = base to infinity in steps of base do begin
|
||||
for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
|
||||
// let t = tmin if k <= bias {+ tmin}, or
|
||||
// tmax if k >= bias + tmax, or k - bias otherwise
|
||||
if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
|
||||
$t = self::BOOTSTRAP_TMIN;
|
||||
} elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
|
||||
$t = self::BOOTSTRAP_TMAX;
|
||||
} else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
|
||||
// if q < t then break
|
||||
if ($q < $t) {
|
||||
break;
|
||||
}
|
||||
|
||||
// output the code point for digit t + ((q - t) mod (base - t))
|
||||
$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
|
||||
$output .= self::digit_to_char($digit);
|
||||
// let q = (q - t) div (base - t)
|
||||
$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
|
||||
} // end
|
||||
// output the code point for digit q
|
||||
$output .= self::digit_to_char($q);
|
||||
// let bias = adapt(delta, h + 1, test h equals b?)
|
||||
$bias = self::adapt($delta, $h + 1, $h === $b);
|
||||
// let delta = 0
|
||||
$delta = 0;
|
||||
// increment h
|
||||
$h++;
|
||||
} // end
|
||||
} // end
|
||||
// increment delta and n
|
||||
$delta++;
|
||||
$n++;
|
||||
} // end
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a digit to its respective character
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3492#section-5
|
||||
*
|
||||
* @param int $digit Digit in the range 0-35
|
||||
* @return string Single character corresponding to digit
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On invalid digit (`idna.invalid_digit`)
|
||||
*/
|
||||
protected static function digit_to_char($digit) {
|
||||
// @codeCoverageIgnoreStart
|
||||
// As far as I know, this never happens, but still good to be sure.
|
||||
if ($digit < 0 || $digit > 35) {
|
||||
throw new Exception(sprintf('Invalid digit %d', $digit), 'idna.invalid_digit', $digit);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
$digits = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
return substr($digits, $digit, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the bias
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3492#section-6.1
|
||||
* @param int $delta
|
||||
* @param int $numpoints
|
||||
* @param bool $firsttime
|
||||
* @return int New bias
|
||||
*
|
||||
* function adapt(delta,numpoints,firsttime):
|
||||
*/
|
||||
protected static function adapt($delta, $numpoints, $firsttime) {
|
||||
// if firsttime then let delta = delta div damp
|
||||
if ($firsttime) {
|
||||
$delta = floor($delta / self::BOOTSTRAP_DAMP);
|
||||
} else {
|
||||
// else let delta = delta div 2
|
||||
$delta = floor($delta / 2);
|
||||
}
|
||||
|
||||
// let delta = delta + (delta div numpoints)
|
||||
$delta += floor($delta / $numpoints);
|
||||
// let k = 0
|
||||
$k = 0;
|
||||
// while delta > ((base - tmin) * tmax) div 2 do begin
|
||||
$max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
|
||||
while ($delta > $max) {
|
||||
// let delta = delta div (base - tmin)
|
||||
$delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
|
||||
// let k = k + base
|
||||
$k += self::BOOTSTRAP_BASE;
|
||||
} // end
|
||||
// return k + (((base - tmin + 1) * delta) div (delta + skew))
|
||||
return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
|
||||
}
|
||||
}
|
||||
203
api/vendor/rmccue/requests/src/Ipv6.php
vendored
Normal file
203
api/vendor/rmccue/requests/src/Ipv6.php
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses
|
||||
*
|
||||
* This was originally based on the PEAR class of the same name, but has been
|
||||
* entirely rewritten.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
final class Ipv6 {
|
||||
/**
|
||||
* Uncompresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and expands the '::' to
|
||||
* the required number of zero pieces.
|
||||
*
|
||||
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
|
||||
* ::1 -> 0:0:0:0:0:0:0:1
|
||||
*
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license https://opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* @param string|Stringable $ip An IPv6 address
|
||||
* @return string The uncompressed IPv6 address
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
|
||||
*/
|
||||
public static function uncompress($ip) {
|
||||
if (InputValidator::is_string_or_stringable($ip) === false) {
|
||||
throw InvalidArgument::create(1, '$ip', 'string|Stringable', gettype($ip));
|
||||
}
|
||||
|
||||
$ip = (string) $ip;
|
||||
|
||||
if (substr_count($ip, '::') !== 1) {
|
||||
return $ip;
|
||||
}
|
||||
|
||||
list($ip1, $ip2) = explode('::', $ip);
|
||||
$c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
|
||||
$c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
|
||||
|
||||
if (strpos($ip2, '.') !== false) {
|
||||
$c2++;
|
||||
}
|
||||
|
||||
if ($c1 === -1 && $c2 === -1) {
|
||||
// ::
|
||||
$ip = '0:0:0:0:0:0:0:0';
|
||||
} elseif ($c1 === -1) {
|
||||
// ::xxx
|
||||
$fill = str_repeat('0:', 7 - $c2);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
} elseif ($c2 === -1) {
|
||||
// xxx::
|
||||
$fill = str_repeat(':0', 7 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
} else {
|
||||
// xxx::xxx
|
||||
$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress consecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and compresses consecutive
|
||||
* zero pieces to '::'.
|
||||
*
|
||||
* Example: FF01:0:0:0:0:0:0:101 -> FF01::101
|
||||
* 0:0:0:0:0:0:0:1 -> ::1
|
||||
*
|
||||
* @see \WpOrg\Requests\Ipv6::uncompress()
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The compressed IPv6 address
|
||||
*/
|
||||
public static function compress($ip) {
|
||||
// Prepare the IP to be compressed.
|
||||
// Note: Input validation is handled in the `uncompress()` method, which is the first call made in this method.
|
||||
$ip = self::uncompress($ip);
|
||||
$ip_parts = self::split_v6_v4($ip);
|
||||
|
||||
// Replace all leading zeros
|
||||
$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
|
||||
|
||||
// Find bunches of zeros
|
||||
if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
|
||||
$max = 0;
|
||||
$pos = null;
|
||||
foreach ($matches[0] as $match) {
|
||||
if (strlen($match[0]) > $max) {
|
||||
$max = strlen($match[0]);
|
||||
$pos = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
|
||||
}
|
||||
|
||||
if ($ip_parts[1] !== '') {
|
||||
return implode(':', $ip_parts);
|
||||
} else {
|
||||
return $ip_parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an IPv6 address into the IPv6 and IPv4 representation parts
|
||||
*
|
||||
* RFC 4291 allows you to represent the last two parts of an IPv6 address
|
||||
* using the standard IPv4 representation
|
||||
*
|
||||
* Example: 0:0:0:0:0:0:13.1.68.3
|
||||
* 0:0:0:0:0:FFFF:129.144.52.38
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
|
||||
*/
|
||||
private static function split_v6_v4($ip) {
|
||||
if (strpos($ip, '.') !== false) {
|
||||
$pos = strrpos($ip, ':');
|
||||
$ipv6_part = substr($ip, 0, $pos);
|
||||
$ipv4_part = substr($ip, $pos + 1);
|
||||
return [$ipv6_part, $ipv4_part];
|
||||
} else {
|
||||
return [$ip, ''];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an IPv6 address
|
||||
*
|
||||
* Checks if the given IP is a valid IPv6 address
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return bool true if $ip is a valid IPv6 address
|
||||
*/
|
||||
public static function check_ipv6($ip) {
|
||||
// Note: Input validation is handled in the `uncompress()` method, which is the first call made in this method.
|
||||
$ip = self::uncompress($ip);
|
||||
list($ipv6, $ipv4) = self::split_v6_v4($ip);
|
||||
$ipv6 = explode(':', $ipv6);
|
||||
$ipv4 = explode('.', $ipv4);
|
||||
if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
|
||||
foreach ($ipv6 as $ipv6_part) {
|
||||
// The section can't be empty
|
||||
if ($ipv6_part === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nor can it be over four characters
|
||||
if (strlen($ipv6_part) > 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove leading zeros (this is safe because of the above)
|
||||
$ipv6_part = ltrim($ipv6_part, '0');
|
||||
if ($ipv6_part === '') {
|
||||
$ipv6_part = '0';
|
||||
}
|
||||
|
||||
// Check the value is valid
|
||||
$value = hexdec($ipv6_part);
|
||||
if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($ipv4) === 4) {
|
||||
foreach ($ipv4 as $ipv4_part) {
|
||||
$value = (int) $ipv4_part;
|
||||
if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
1101
api/vendor/rmccue/requests/src/Iri.php
vendored
Normal file
1101
api/vendor/rmccue/requests/src/Iri.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
75
api/vendor/rmccue/requests/src/Port.php
vendored
Normal file
75
api/vendor/rmccue/requests/src/Port.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Port utilities for Requests
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
|
||||
/**
|
||||
* Find the correct port depending on the Request type.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
* @since 2.0.0
|
||||
*/
|
||||
final class Port {
|
||||
|
||||
/**
|
||||
* Port to use with Acap requests.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const ACAP = 674;
|
||||
|
||||
/**
|
||||
* Port to use with Dictionary requests.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DICT = 2628;
|
||||
|
||||
/**
|
||||
* Port to use with HTTP requests.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const HTTP = 80;
|
||||
|
||||
/**
|
||||
* Port to use with HTTP over SSL requests.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const HTTPS = 443;
|
||||
|
||||
/**
|
||||
* Retrieve the port number to use.
|
||||
*
|
||||
* @param string $type Request type.
|
||||
* The following requests types are supported:
|
||||
* 'acap', 'dict', 'http' and 'https'.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When a non-string input has been passed.
|
||||
* @throws \WpOrg\Requests\Exception When a non-supported port is requested ('portnotsupported').
|
||||
*/
|
||||
public static function get($type) {
|
||||
if (!is_string($type)) {
|
||||
throw InvalidArgument::create(1, '$type', 'string', gettype($type));
|
||||
}
|
||||
|
||||
$type = strtoupper($type);
|
||||
if (!defined("self::{$type}")) {
|
||||
$message = sprintf('Invalid port type (%s) passed', $type);
|
||||
throw new Exception($message, 'portnotsupported');
|
||||
}
|
||||
|
||||
return constant("self::{$type}");
|
||||
}
|
||||
}
|
||||
38
api/vendor/rmccue/requests/src/Proxy.php
vendored
Normal file
38
api/vendor/rmccue/requests/src/Proxy.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* @package Requests\Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Hooks;
|
||||
|
||||
/**
|
||||
* Proxy connection interface
|
||||
*
|
||||
* Implement this interface to handle proxy settings and authentication
|
||||
*
|
||||
* Parameters should be passed via the constructor where possible, as this
|
||||
* makes it much easier for users to use your provider.
|
||||
*
|
||||
* @see \WpOrg\Requests\Hooks
|
||||
*
|
||||
* @package Requests\Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
interface Proxy {
|
||||
/**
|
||||
* Register hooks as needed
|
||||
*
|
||||
* This method is called in {@see \WpOrg\Requests\Requests::request()} when the user
|
||||
* has set an instance as the 'auth' option. Use this callback to register all the
|
||||
* hooks you'll need.
|
||||
*
|
||||
* @see \WpOrg\Requests\Hooks::register()
|
||||
* @param \WpOrg\Requests\Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Hooks $hooks);
|
||||
}
|
||||
164
api/vendor/rmccue/requests/src/Proxy/Http.php
vendored
Normal file
164
api/vendor/rmccue/requests/src/Proxy/Http.php
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* @package Requests\Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Proxy;
|
||||
|
||||
use WpOrg\Requests\Exception\ArgumentCount;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Hooks;
|
||||
use WpOrg\Requests\Proxy;
|
||||
|
||||
/**
|
||||
* HTTP Proxy connection interface
|
||||
*
|
||||
* Provides a handler for connection via an HTTP proxy
|
||||
*
|
||||
* @package Requests\Proxy
|
||||
* @since 1.6
|
||||
*/
|
||||
final class Http implements Proxy {
|
||||
/**
|
||||
* Proxy host and port
|
||||
*
|
||||
* Notation: "host:port" (eg 127.0.0.1:8080 or someproxy.com:3128)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $proxy;
|
||||
|
||||
/**
|
||||
* Username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pass;
|
||||
|
||||
/**
|
||||
* Do we need to authenticate? (ie username & password have been provided)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $use_authentication;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param array|string|null $args Proxy as a string or an array of proxy, user and password.
|
||||
* When passed as an array, must have exactly one (proxy)
|
||||
* or three elements (proxy, user, password).
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array, a string or null.
|
||||
* @throws \WpOrg\Requests\Exception\ArgumentCount On incorrect number of arguments (`proxyhttpbadargs`)
|
||||
*/
|
||||
public function __construct($args = null) {
|
||||
if (is_string($args)) {
|
||||
$this->proxy = $args;
|
||||
} elseif (is_array($args)) {
|
||||
if (count($args) === 1) {
|
||||
list($this->proxy) = $args;
|
||||
} elseif (count($args) === 3) {
|
||||
list($this->proxy, $this->user, $this->pass) = $args;
|
||||
$this->use_authentication = true;
|
||||
} else {
|
||||
throw ArgumentCount::create(
|
||||
'an array with exactly one element or exactly three elements',
|
||||
count($args),
|
||||
'proxyhttpbadargs'
|
||||
);
|
||||
}
|
||||
} elseif ($args !== null) {
|
||||
throw InvalidArgument::create(1, '$args', 'array|string|null', gettype($args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the necessary callbacks
|
||||
*
|
||||
* @since 1.6
|
||||
* @see \WpOrg\Requests\Proxy\Http::curl_before_send()
|
||||
* @see \WpOrg\Requests\Proxy\Http::fsockopen_remote_socket()
|
||||
* @see \WpOrg\Requests\Proxy\Http::fsockopen_remote_host_path()
|
||||
* @see \WpOrg\Requests\Proxy\Http::fsockopen_header()
|
||||
* @param \WpOrg\Requests\Hooks $hooks Hook system
|
||||
*/
|
||||
public function register(Hooks $hooks) {
|
||||
$hooks->register('curl.before_send', [$this, 'curl_before_send']);
|
||||
|
||||
$hooks->register('fsockopen.remote_socket', [$this, 'fsockopen_remote_socket']);
|
||||
$hooks->register('fsockopen.remote_host_path', [$this, 'fsockopen_remote_host_path']);
|
||||
if ($this->use_authentication) {
|
||||
$hooks->register('fsockopen.after_headers', [$this, 'fsockopen_header']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cURL parameters before the data is sent
|
||||
*
|
||||
* @since 1.6
|
||||
* @param resource|\CurlHandle $handle cURL handle
|
||||
*/
|
||||
public function curl_before_send(&$handle) {
|
||||
curl_setopt($handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curl_setopt($handle, CURLOPT_PROXY, $this->proxy);
|
||||
|
||||
if ($this->use_authentication) {
|
||||
curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_setopt($handle, CURLOPT_PROXYUSERPWD, $this->get_auth_string());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote socket information before opening socket connection
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $remote_socket Socket connection string
|
||||
*/
|
||||
public function fsockopen_remote_socket(&$remote_socket) {
|
||||
$remote_socket = $this->proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter remote path before getting stream data
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $path Path to send in HTTP request string ("GET ...")
|
||||
* @param string $url Full URL we're requesting
|
||||
*/
|
||||
public function fsockopen_remote_host_path(&$path, $url) {
|
||||
$path = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra headers to the request before sending
|
||||
*
|
||||
* @since 1.6
|
||||
* @param string $out HTTP header string
|
||||
*/
|
||||
public function fsockopen_header(&$out) {
|
||||
$out .= sprintf("Proxy-Authorization: Basic %s\r\n", base64_encode($this->get_auth_string()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication string (user:pass)
|
||||
*
|
||||
* @since 1.6
|
||||
* @return string
|
||||
*/
|
||||
public function get_auth_string() {
|
||||
return $this->user . ':' . $this->pass;
|
||||
}
|
||||
}
|
||||
1095
api/vendor/rmccue/requests/src/Requests.php
vendored
Normal file
1095
api/vendor/rmccue/requests/src/Requests.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
165
api/vendor/rmccue/requests/src/Response.php
vendored
Normal file
165
api/vendor/rmccue/requests/src/Response.php
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from \WpOrg\Requests\Requests::request()
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Cookie\Jar;
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\Http;
|
||||
use WpOrg\Requests\Response\Headers;
|
||||
|
||||
/**
|
||||
* HTTP response class
|
||||
*
|
||||
* Contains a response from \WpOrg\Requests\Requests::request()
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Response {
|
||||
|
||||
/**
|
||||
* Response body
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Raw HTTP data from the transport
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $raw = '';
|
||||
|
||||
/**
|
||||
* Headers, as an associative array
|
||||
*
|
||||
* @var \WpOrg\Requests\Response\Headers Array-like object representing headers
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* Status code, false if non-blocking
|
||||
*
|
||||
* @var integer|boolean
|
||||
*/
|
||||
public $status_code = false;
|
||||
|
||||
/**
|
||||
* Protocol version, false if non-blocking
|
||||
*
|
||||
* @var float|boolean
|
||||
*/
|
||||
public $protocol_version = false;
|
||||
|
||||
/**
|
||||
* Whether the request succeeded or not
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $success = false;
|
||||
|
||||
/**
|
||||
* Number of redirects the request used
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $redirects = 0;
|
||||
|
||||
/**
|
||||
* URL requested
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $url = '';
|
||||
|
||||
/**
|
||||
* Previous requests (from redirects)
|
||||
*
|
||||
* @var array Array of \WpOrg\Requests\Response objects
|
||||
*/
|
||||
public $history = [];
|
||||
|
||||
/**
|
||||
* Cookies from the request
|
||||
*
|
||||
* @var \WpOrg\Requests\Cookie\Jar Array-like object representing a cookie jar
|
||||
*/
|
||||
public $cookies = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->headers = new Headers();
|
||||
$this->cookies = new Jar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the response a redirect?
|
||||
*
|
||||
* @return boolean True if redirect (3xx status), false if not.
|
||||
*/
|
||||
public function is_redirect() {
|
||||
$code = $this->status_code;
|
||||
return in_array($code, [300, 301, 302, 303, 307], true) || $code > 307 && $code < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the request was not successful
|
||||
*
|
||||
* @param boolean $allow_redirects Set to false to throw on a 3xx as well
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception If `$allow_redirects` is false, and code is 3xx (`response.no_redirects`)
|
||||
* @throws \WpOrg\Requests\Exception\Http On non-successful status code. Exception class corresponds to "Status" + code (e.g. {@see \WpOrg\Requests\Exception\Http\Status404})
|
||||
*/
|
||||
public function throw_for_status($allow_redirects = true) {
|
||||
if ($this->is_redirect()) {
|
||||
if ($allow_redirects !== true) {
|
||||
throw new Exception('Redirection not allowed', 'response.no_redirects', $this);
|
||||
}
|
||||
} elseif (!$this->success) {
|
||||
$exception = Http::get_class($this->status_code);
|
||||
throw new $exception(null, $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON decode the response body.
|
||||
*
|
||||
* The method parameters are the same as those for the PHP native `json_decode()` function.
|
||||
*
|
||||
* @link https://php.net/json-decode
|
||||
*
|
||||
* @param ?bool $associative Optional. When `true`, JSON objects will be returned as associative arrays;
|
||||
* When `false`, JSON objects will be returned as objects.
|
||||
* When `null`, JSON objects will be returned as associative arrays
|
||||
* or objects depending on whether `JSON_OBJECT_AS_ARRAY` is set in the flags.
|
||||
* Defaults to `true` (in contrast to the PHP native default of `null`).
|
||||
* @param int $depth Optional. Maximum nesting depth of the structure being decoded.
|
||||
* Defaults to `512`.
|
||||
* @param int $options Optional. Bitmask of JSON_BIGINT_AS_STRING, JSON_INVALID_UTF8_IGNORE,
|
||||
* JSON_INVALID_UTF8_SUBSTITUTE, JSON_OBJECT_AS_ARRAY, JSON_THROW_ON_ERROR.
|
||||
* Defaults to `0` (no options set).
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception If `$this->body` is not valid json.
|
||||
*/
|
||||
public function decode_body($associative = true, $depth = 512, $options = 0) {
|
||||
$data = json_decode($this->body, $associative, $depth, $options);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
$last_error = json_last_error_msg();
|
||||
throw new Exception('Unable to parse JSON data: ' . $last_error, 'response.invalid', $this);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
124
api/vendor/rmccue/requests/src/Response/Headers.php
vendored
Normal file
124
api/vendor/rmccue/requests/src/Response/Headers.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Response;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
|
||||
use WpOrg\Requests\Utility\FilteredIterator;
|
||||
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests
|
||||
*/
|
||||
class Headers extends CaseInsensitiveDictionary {
|
||||
/**
|
||||
* Get the given header
|
||||
*
|
||||
* Unlike {@see \WpOrg\Requests\Response\Headers::getValues()}, this returns a string. If there are
|
||||
* multiple values, it concatenates them with a comma as per RFC2616.
|
||||
*
|
||||
* Avoid using this where commas may be used unquoted in values, such as
|
||||
* Set-Cookie headers.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return string|null Header value
|
||||
*/
|
||||
public function offsetGet($offset) {
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
if (!isset($this->data[$offset])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->flatten($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @param string $offset Item name
|
||||
* @param string $value Item value
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*/
|
||||
public function offsetSet($offset, $value) {
|
||||
if ($offset === null) {
|
||||
throw new Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
if (!isset($this->data[$offset])) {
|
||||
$this->data[$offset] = [];
|
||||
}
|
||||
|
||||
$this->data[$offset][] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values for a given header
|
||||
*
|
||||
* @param string $offset
|
||||
* @return array|null Header values
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not valid as an array key.
|
||||
*/
|
||||
public function getValues($offset) {
|
||||
if (!is_string($offset) && !is_int($offset)) {
|
||||
throw InvalidArgument::create(1, '$offset', 'string|int', gettype($offset));
|
||||
}
|
||||
|
||||
$offset = strtolower($offset);
|
||||
if (!isset($this->data[$offset])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->data[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a value into a string
|
||||
*
|
||||
* Converts an array into a string by imploding values with a comma, as per
|
||||
* RFC2616's rules for folding headers.
|
||||
*
|
||||
* @param string|array $value Value to flatten
|
||||
* @return string Flattened value
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or an array.
|
||||
*/
|
||||
public function flatten($value) {
|
||||
if (is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
return implode(',', $value);
|
||||
}
|
||||
|
||||
throw InvalidArgument::create(1, '$value', 'string|array', gettype($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* Converts the internally stored values to a comma-separated string if there is more
|
||||
* than one value for a key.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new FilteredIterator($this->data, [$this, 'flatten']);
|
||||
}
|
||||
}
|
||||
304
api/vendor/rmccue/requests/src/Session.php
vendored
Normal file
304
api/vendor/rmccue/requests/src/Session.php
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* @package Requests\SessionHandler
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Cookie\Jar;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Iri;
|
||||
use WpOrg\Requests\Requests;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* Session handler for persistent requests and default parameters
|
||||
*
|
||||
* Allows various options to be set as default values, and merges both the
|
||||
* options and URL properties together. A base URL can be set for all requests,
|
||||
* with all subrequests resolved from this. Base options can be set (including
|
||||
* a shared cookie jar), then overridden for individual requests.
|
||||
*
|
||||
* @package Requests\SessionHandler
|
||||
*/
|
||||
class Session {
|
||||
/**
|
||||
* Base URL for requests
|
||||
*
|
||||
* URLs will be made absolute using this as the base
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $url = null;
|
||||
|
||||
/**
|
||||
* Base headers for requests
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $headers = [];
|
||||
|
||||
/**
|
||||
* Base data for requests
|
||||
*
|
||||
* If both the base data and the per-request data are arrays, the data will
|
||||
* be merged before sending the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* Base options for requests
|
||||
*
|
||||
* The base options are merged with the per-request data for each request.
|
||||
* The only default option is a shared cookie jar between requests.
|
||||
*
|
||||
* Values here can also be set directly via properties on the Session
|
||||
* object, e.g. `$session->useragent = 'X';`
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = [];
|
||||
|
||||
/**
|
||||
* Create a new session
|
||||
*
|
||||
* @param string|Stringable|null $url Base URL for requests
|
||||
* @param array $headers Default headers for requests
|
||||
* @param array $data Default data for requests
|
||||
* @param array $options Default options for requests
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string, Stringable or null.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
*/
|
||||
public function __construct($url = null, $headers = [], $data = [], $options = []) {
|
||||
if ($url !== null && InputValidator::is_string_or_stringable($url) === false) {
|
||||
throw InvalidArgument::create(1, '$url', 'string|Stringable|null', gettype($url));
|
||||
}
|
||||
|
||||
if (is_array($headers) === false) {
|
||||
throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
|
||||
}
|
||||
|
||||
if (is_array($data) === false) {
|
||||
throw InvalidArgument::create(3, '$data', 'array', gettype($data));
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(4, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
$this->url = $url;
|
||||
$this->headers = $headers;
|
||||
$this->data = $data;
|
||||
$this->options = $options;
|
||||
|
||||
if (empty($this->options['cookies'])) {
|
||||
$this->options['cookies'] = new Jar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a property's value
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @return mixed|null Property value, null if none found
|
||||
*/
|
||||
public function __get($name) {
|
||||
if (isset($this->options[$name])) {
|
||||
return $this->options[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property's value
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @param mixed $value Property value
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
$this->options[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $name Property name.
|
||||
*/
|
||||
public function __isset($name) {
|
||||
return isset($this->options[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a property's value
|
||||
*
|
||||
* @param string $name Property name.
|
||||
*/
|
||||
public function __unset($name) {
|
||||
unset($this->options[$name]);
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @see \WpOrg\Requests\Session::request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $options
|
||||
* @return \WpOrg\Requests\Response
|
||||
*/
|
||||
/**
|
||||
* Send a GET request
|
||||
*/
|
||||
public function get($url, $headers = [], $options = []) {
|
||||
return $this->request($url, $headers, null, Requests::GET, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a HEAD request
|
||||
*/
|
||||
public function head($url, $headers = [], $options = []) {
|
||||
return $this->request($url, $headers, null, Requests::HEAD, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request
|
||||
*/
|
||||
public function delete($url, $headers = [], $options = []) {
|
||||
return $this->request($url, $headers, null, Requests::DELETE, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @see \WpOrg\Requests\Session::request()
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param array $data
|
||||
* @param array $options
|
||||
* @return \WpOrg\Requests\Response
|
||||
*/
|
||||
/**
|
||||
* Send a POST request
|
||||
*/
|
||||
public function post($url, $headers = [], $data = [], $options = []) {
|
||||
return $this->request($url, $headers, $data, Requests::POST, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request
|
||||
*/
|
||||
public function put($url, $headers = [], $data = [], $options = []) {
|
||||
return $this->request($url, $headers, $data, Requests::PUT, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request
|
||||
*
|
||||
* Note: Unlike {@see \WpOrg\Requests\Session::post()} and {@see \WpOrg\Requests\Session::put()},
|
||||
* `$headers` is required, as the specification recommends that should send an ETag
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc5789
|
||||
*/
|
||||
public function patch($url, $headers, $data = [], $options = []) {
|
||||
return $this->request($url, $headers, $data, Requests::PATCH, $options);
|
||||
}
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Main interface for HTTP requests
|
||||
*
|
||||
* This method initiates a request and sends it via a transport before
|
||||
* parsing.
|
||||
*
|
||||
* @see \WpOrg\Requests\Requests::request()
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Extra headers to send with the request
|
||||
* @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
|
||||
* @param string $type HTTP request type (use \WpOrg\Requests\Requests constants)
|
||||
* @param array $options Options for the request (see {@see \WpOrg\Requests\Requests::request()})
|
||||
* @return \WpOrg\Requests\Response
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On invalid URLs (`nonhttp`)
|
||||
*/
|
||||
public function request($url, $headers = [], $data = [], $type = Requests::GET, $options = []) {
|
||||
$request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
|
||||
|
||||
return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple HTTP requests simultaneously
|
||||
*
|
||||
* @see \WpOrg\Requests\Requests::request_multiple()
|
||||
*
|
||||
* @param array $requests Requests data (see {@see \WpOrg\Requests\Requests::request_multiple()})
|
||||
* @param array $options Global and default options (see {@see \WpOrg\Requests\Requests::request()})
|
||||
* @return array Responses (either \WpOrg\Requests\Response or a \WpOrg\Requests\Exception object)
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
*/
|
||||
public function request_multiple($requests, $options = []) {
|
||||
if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
|
||||
throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(2, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
foreach ($requests as $key => $request) {
|
||||
$requests[$key] = $this->merge_request($request, false);
|
||||
}
|
||||
|
||||
$options = array_merge($this->options, $options);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($options['type']);
|
||||
|
||||
return Requests::request_multiple($requests, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a request's data with the default data
|
||||
*
|
||||
* @param array $request Request data (same form as {@see \WpOrg\Requests\Session::request_multiple()})
|
||||
* @param boolean $merge_options Should we merge options as well?
|
||||
* @return array Request data
|
||||
*/
|
||||
protected function merge_request($request, $merge_options = true) {
|
||||
if ($this->url !== null) {
|
||||
$request['url'] = Iri::absolutize($this->url, $request['url']);
|
||||
$request['url'] = $request['url']->uri;
|
||||
}
|
||||
|
||||
if (empty($request['headers'])) {
|
||||
$request['headers'] = [];
|
||||
}
|
||||
|
||||
$request['headers'] = array_merge($this->headers, $request['headers']);
|
||||
|
||||
if (empty($request['data'])) {
|
||||
if (is_array($this->data)) {
|
||||
$request['data'] = $this->data;
|
||||
}
|
||||
} elseif (is_array($request['data']) && is_array($this->data)) {
|
||||
$request['data'] = array_merge($this->data, $request['data']);
|
||||
}
|
||||
|
||||
if ($merge_options === true) {
|
||||
$request['options'] = array_merge($this->options, $request['options']);
|
||||
|
||||
// Disallow forcing the type, as that's a per request setting
|
||||
unset($request['options']['type']);
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
182
api/vendor/rmccue/requests/src/Ssl.php
vendored
Normal file
182
api/vendor/rmccue/requests/src/Ssl.php
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* SSL utilities for Requests
|
||||
*
|
||||
* Collection of utilities for working with and verifying SSL certificates.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
final class Ssl {
|
||||
/**
|
||||
* Verify the certificate against common name and subject alternative names
|
||||
*
|
||||
* Unfortunately, PHP doesn't check the certificate against the alternative
|
||||
* names, leading things like 'https://www.github.com/' to be invalid.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
|
||||
*
|
||||
* @param string|Stringable $host Host name to verify against
|
||||
* @param array $cert Certificate data from openssl_x509_parse()
|
||||
* @return bool
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $host argument is not a string or a stringable object.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cert argument is not an array or array accessible.
|
||||
*/
|
||||
public static function verify_certificate($host, $cert) {
|
||||
if (InputValidator::is_string_or_stringable($host) === false) {
|
||||
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
|
||||
}
|
||||
|
||||
if (InputValidator::has_array_access($cert) === false) {
|
||||
throw InvalidArgument::create(2, '$cert', 'array|ArrayAccess', gettype($cert));
|
||||
}
|
||||
|
||||
$has_dns_alt = false;
|
||||
|
||||
// Check the subjectAltName
|
||||
if (!empty($cert['extensions']['subjectAltName'])) {
|
||||
$altnames = explode(',', $cert['extensions']['subjectAltName']);
|
||||
foreach ($altnames as $altname) {
|
||||
$altname = trim($altname);
|
||||
if (strpos($altname, 'DNS:') !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$has_dns_alt = true;
|
||||
|
||||
// Strip the 'DNS:' prefix and trim whitespace
|
||||
$altname = trim(substr($altname, 4));
|
||||
|
||||
// Check for a match
|
||||
if (self::match_domain($host, $altname) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($has_dns_alt === true) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to checking the common name if we didn't get any dNSName
|
||||
// alt names, as per RFC2818
|
||||
if (!empty($cert['subject']['CN'])) {
|
||||
// Check for a match
|
||||
return (self::match_domain($host, $cert['subject']['CN']) === true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a reference name is valid
|
||||
*
|
||||
* Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
|
||||
* - Wildcards can only occur in a name with more than 3 components
|
||||
* - Wildcards can only occur as the last character in the first
|
||||
* component
|
||||
* - Wildcards may be preceded by additional characters
|
||||
*
|
||||
* We modify these rules to be a bit stricter and only allow the wildcard
|
||||
* character to be the full first component; that is, with the exclusion of
|
||||
* the third rule.
|
||||
*
|
||||
* @param string|Stringable $reference Reference dNSName
|
||||
* @return boolean Is the name valid?
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
|
||||
*/
|
||||
public static function verify_reference_name($reference) {
|
||||
if (InputValidator::is_string_or_stringable($reference) === false) {
|
||||
throw InvalidArgument::create(1, '$reference', 'string|Stringable', gettype($reference));
|
||||
}
|
||||
|
||||
if ($reference === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('`\s`', $reference) > 0) {
|
||||
// Whitespace detected. This can never be a dNSName.
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = explode('.', $reference);
|
||||
if ($parts !== array_filter($parts)) {
|
||||
// DNSName cannot contain two dots next to each other.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the first part of the name
|
||||
$first = array_shift($parts);
|
||||
|
||||
if (strpos($first, '*') !== false) {
|
||||
// Check that the wildcard is the full part
|
||||
if ($first !== '*') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that we have at least 3 components (including first)
|
||||
if (count($parts) < 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the remaining parts
|
||||
foreach ($parts as $part) {
|
||||
if (strpos($part, '*') !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found, verified!
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a hostname against a dNSName reference
|
||||
*
|
||||
* @param string|Stringable $host Requested host
|
||||
* @param string|Stringable $reference dNSName to match against
|
||||
* @return boolean Does the domain match?
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When either of the passed arguments is not a string or a stringable object.
|
||||
*/
|
||||
public static function match_domain($host, $reference) {
|
||||
if (InputValidator::is_string_or_stringable($host) === false) {
|
||||
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
|
||||
}
|
||||
|
||||
// Check if the reference is blocklisted first
|
||||
if (self::verify_reference_name($reference) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a direct match
|
||||
if ((string) $host === (string) $reference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the valid wildcard match if the host is not an IP address
|
||||
// Also validates that the host has 3 parts or more, as per Firefox's ruleset,
|
||||
// as a wildcard reference is only allowed with 3 parts or more, so the
|
||||
// comparison will never match if host doesn't contain 3 parts or more as well.
|
||||
if (ip2long($host) === false) {
|
||||
$parts = explode('.', $host);
|
||||
$parts[0] = '*';
|
||||
$wildcard = implode('.', $parts);
|
||||
if ($wildcard === (string) $reference) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
45
api/vendor/rmccue/requests/src/Transport.php
vendored
Normal file
45
api/vendor/rmccue/requests/src/Transport.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests;
|
||||
|
||||
/**
|
||||
* Base HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
interface Transport {
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*/
|
||||
public function request($url, $headers = [], $data = [], $options = []);
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see \WpOrg\Requests\Transport::request()}
|
||||
* @param array $options Global options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
|
||||
*/
|
||||
public function request_multiple($requests, $options);
|
||||
|
||||
/**
|
||||
* Self-test whether the transport can be used.
|
||||
*
|
||||
* The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
|
||||
*
|
||||
* @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
|
||||
* @return bool Whether the transport can be used.
|
||||
*/
|
||||
public static function test($capabilities = []);
|
||||
}
|
||||
640
api/vendor/rmccue/requests/src/Transport/Curl.php
vendored
Normal file
640
api/vendor/rmccue/requests/src/Transport/Curl.php
vendored
Normal file
@@ -0,0 +1,640 @@
|
||||
<?php
|
||||
/**
|
||||
* cURL HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Transport;
|
||||
|
||||
use RecursiveArrayIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use WpOrg\Requests\Capability;
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Exception\Transport\Curl as CurlException;
|
||||
use WpOrg\Requests\Requests;
|
||||
use WpOrg\Requests\Transport;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* cURL HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
final class Curl implements Transport {
|
||||
const CURL_7_10_5 = 0x070A05;
|
||||
const CURL_7_16_2 = 0x071002;
|
||||
|
||||
/**
|
||||
* Raw HTTP data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $headers = '';
|
||||
|
||||
/**
|
||||
* Raw body data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $response_data = '';
|
||||
|
||||
/**
|
||||
* Information on the current request
|
||||
*
|
||||
* @var array cURL information array, see {@link https://www.php.net/curl_getinfo}
|
||||
*/
|
||||
public $info;
|
||||
|
||||
/**
|
||||
* cURL version number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* cURL handle
|
||||
*
|
||||
* @var resource|\CurlHandle Resource in PHP < 8.0, Instance of CurlHandle in PHP >= 8.0.
|
||||
*/
|
||||
private $handle;
|
||||
|
||||
/**
|
||||
* Hook dispatcher instance
|
||||
*
|
||||
* @var \WpOrg\Requests\Hooks
|
||||
*/
|
||||
private $hooks;
|
||||
|
||||
/**
|
||||
* Have we finished the headers yet?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $done_headers = false;
|
||||
|
||||
/**
|
||||
* If streaming to a file, keep the file pointer
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $stream_handle;
|
||||
|
||||
/**
|
||||
* How many bytes are in the response body?
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $response_bytes;
|
||||
|
||||
/**
|
||||
* What's the maximum number of bytes we should keep?
|
||||
*
|
||||
* @var int|bool Byte count, or false if no limit.
|
||||
*/
|
||||
private $response_byte_limit;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$curl = curl_version();
|
||||
$this->version = $curl['version_number'];
|
||||
$this->handle = curl_init();
|
||||
|
||||
curl_setopt($this->handle, CURLOPT_HEADER, false);
|
||||
curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
|
||||
if ($this->version >= self::CURL_7_10_5) {
|
||||
curl_setopt($this->handle, CURLOPT_ENCODING, '');
|
||||
}
|
||||
|
||||
if (defined('CURLOPT_PROTOCOLS')) {
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_protocolsFound
|
||||
curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
|
||||
if (defined('CURLOPT_REDIR_PROTOCOLS')) {
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_redir_protocolsFound
|
||||
curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
if (is_resource($this->handle)) {
|
||||
curl_close($this->handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @param string|Stringable $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data parameter is not an array or string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception On a cURL error (`curlerror`)
|
||||
*/
|
||||
public function request($url, $headers = [], $data = [], $options = []) {
|
||||
if (InputValidator::is_string_or_stringable($url) === false) {
|
||||
throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url));
|
||||
}
|
||||
|
||||
if (is_array($headers) === false) {
|
||||
throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
|
||||
}
|
||||
|
||||
if (!is_array($data) && !is_string($data)) {
|
||||
if ($data === null) {
|
||||
$data = '';
|
||||
} else {
|
||||
throw InvalidArgument::create(3, '$data', 'array|string', gettype($data));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(4, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
$this->hooks = $options['hooks'];
|
||||
|
||||
$this->setup_handle($url, $headers, $data, $options);
|
||||
|
||||
$options['hooks']->dispatch('curl.before_send', [&$this->handle]);
|
||||
|
||||
if ($options['filename'] !== false) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silenced the PHP native warning in favour of throwing an exception.
|
||||
$this->stream_handle = @fopen($options['filename'], 'wb');
|
||||
if ($this->stream_handle === false) {
|
||||
$error = error_get_last();
|
||||
throw new Exception($error['message'], 'fopen');
|
||||
}
|
||||
}
|
||||
|
||||
$this->response_data = '';
|
||||
$this->response_bytes = 0;
|
||||
$this->response_byte_limit = false;
|
||||
if ($options['max_bytes'] !== false) {
|
||||
$this->response_byte_limit = $options['max_bytes'];
|
||||
}
|
||||
|
||||
if (isset($options['verify'])) {
|
||||
if ($options['verify'] === false) {
|
||||
curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
} elseif (is_string($options['verify'])) {
|
||||
curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
curl_exec($this->handle);
|
||||
$response = $this->response_data;
|
||||
|
||||
$options['hooks']->dispatch('curl.after_send', []);
|
||||
|
||||
if (curl_errno($this->handle) === CURLE_WRITE_ERROR || curl_errno($this->handle) === CURLE_BAD_CONTENT_ENCODING) {
|
||||
// Reset encoding and try again
|
||||
curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
|
||||
|
||||
$this->response_data = '';
|
||||
$this->response_bytes = 0;
|
||||
curl_exec($this->handle);
|
||||
$response = $this->response_data;
|
||||
}
|
||||
|
||||
$this->process_response($response, $options);
|
||||
|
||||
// Need to remove the $this reference from the curl handle.
|
||||
// Otherwise \WpOrg\Requests\Transport\Curl won't be garbage collected and the curl_close() will never be called.
|
||||
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
|
||||
curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data
|
||||
* @param array $options Global options
|
||||
* @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
*/
|
||||
public function request_multiple($requests, $options) {
|
||||
// If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
|
||||
if (empty($requests)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
|
||||
throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(2, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
$multihandle = curl_multi_init();
|
||||
$subrequests = [];
|
||||
$subhandles = [];
|
||||
|
||||
$class = get_class($this);
|
||||
foreach ($requests as $id => $request) {
|
||||
$subrequests[$id] = new $class();
|
||||
$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
|
||||
$request['options']['hooks']->dispatch('curl.before_multi_add', [&$subhandles[$id]]);
|
||||
curl_multi_add_handle($multihandle, $subhandles[$id]);
|
||||
}
|
||||
|
||||
$completed = 0;
|
||||
$responses = [];
|
||||
$subrequestcount = count($subrequests);
|
||||
|
||||
$request['options']['hooks']->dispatch('curl.before_multi_exec', [&$multihandle]);
|
||||
|
||||
do {
|
||||
$active = 0;
|
||||
|
||||
do {
|
||||
$status = curl_multi_exec($multihandle, $active);
|
||||
} while ($status === CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
$to_process = [];
|
||||
|
||||
// Read the information as needed
|
||||
while ($done = curl_multi_info_read($multihandle)) {
|
||||
$key = array_search($done['handle'], $subhandles, true);
|
||||
if (!isset($to_process[$key])) {
|
||||
$to_process[$key] = $done;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the finished requests before we start getting the new ones
|
||||
foreach ($to_process as $key => $done) {
|
||||
$options = $requests[$key]['options'];
|
||||
if ($done['result'] !== CURLE_OK) {
|
||||
//get error string for handle.
|
||||
$reason = curl_error($done['handle']);
|
||||
$exception = new CurlException(
|
||||
$reason,
|
||||
CurlException::EASY,
|
||||
$done['handle'],
|
||||
$done['result']
|
||||
);
|
||||
$responses[$key] = $exception;
|
||||
$options['hooks']->dispatch('transport.internal.parse_error', [&$responses[$key], $requests[$key]]);
|
||||
} else {
|
||||
$responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
|
||||
|
||||
$options['hooks']->dispatch('transport.internal.parse_response', [&$responses[$key], $requests[$key]]);
|
||||
}
|
||||
|
||||
curl_multi_remove_handle($multihandle, $done['handle']);
|
||||
curl_close($done['handle']);
|
||||
|
||||
if (!is_string($responses[$key])) {
|
||||
$options['hooks']->dispatch('multiple.request.complete', [&$responses[$key], $key]);
|
||||
}
|
||||
|
||||
$completed++;
|
||||
}
|
||||
} while ($active || $completed < $subrequestcount);
|
||||
|
||||
$request['options']['hooks']->dispatch('curl.after_multi_exec', [&$multihandle]);
|
||||
|
||||
curl_multi_close($multihandle);
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cURL handle for use in a multi-request
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return resource|\CurlHandle Subrequest's cURL handle
|
||||
*/
|
||||
public function &get_subrequest_handle($url, $headers, $data, $options) {
|
||||
$this->setup_handle($url, $headers, $data, $options);
|
||||
|
||||
if ($options['filename'] !== false) {
|
||||
$this->stream_handle = fopen($options['filename'], 'wb');
|
||||
}
|
||||
|
||||
$this->response_data = '';
|
||||
$this->response_bytes = 0;
|
||||
$this->response_byte_limit = false;
|
||||
if ($options['max_bytes'] !== false) {
|
||||
$this->response_byte_limit = $options['max_bytes'];
|
||||
}
|
||||
|
||||
$this->hooks = $options['hooks'];
|
||||
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the cURL handle for the given data
|
||||
*
|
||||
* @param string $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
*/
|
||||
private function setup_handle($url, $headers, $data, $options) {
|
||||
$options['hooks']->dispatch('curl.before_request', [&$this->handle]);
|
||||
|
||||
// Force closing the connection for old versions of cURL (<7.22).
|
||||
if (!isset($headers['Connection'])) {
|
||||
$headers['Connection'] = 'close';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Expect" header.
|
||||
*
|
||||
* By default, cURL adds a "Expect: 100-Continue" to most requests. This header can
|
||||
* add as much as a second to the time it takes for cURL to perform a request. To
|
||||
* prevent this, we need to set an empty "Expect" header. To match the behaviour of
|
||||
* Guzzle, we'll add the empty header to requests that are smaller than 1 MB and use
|
||||
* HTTP/1.1.
|
||||
*
|
||||
* https://curl.se/mail/lib-2017-07/0013.html
|
||||
*/
|
||||
if (!isset($headers['Expect']) && $options['protocol_version'] === 1.1) {
|
||||
$headers['Expect'] = $this->get_expect_header($data);
|
||||
}
|
||||
|
||||
$headers = Requests::flatten($headers);
|
||||
|
||||
if (!empty($data)) {
|
||||
$data_format = $options['data_format'];
|
||||
|
||||
if ($data_format === 'query') {
|
||||
$url = self::format_get($url, $data);
|
||||
$data = '';
|
||||
} elseif (!is_string($data)) {
|
||||
$data = http_build_query($data, '', '&');
|
||||
}
|
||||
}
|
||||
|
||||
switch ($options['type']) {
|
||||
case Requests::POST:
|
||||
curl_setopt($this->handle, CURLOPT_POST, true);
|
||||
curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
|
||||
break;
|
||||
case Requests::HEAD:
|
||||
curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
|
||||
curl_setopt($this->handle, CURLOPT_NOBODY, true);
|
||||
break;
|
||||
case Requests::TRACE:
|
||||
curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
|
||||
break;
|
||||
case Requests::PATCH:
|
||||
case Requests::PUT:
|
||||
case Requests::DELETE:
|
||||
case Requests::OPTIONS:
|
||||
default:
|
||||
curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
|
||||
if (!empty($data)) {
|
||||
curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
}
|
||||
|
||||
// cURL requires a minimum timeout of 1 second when using the system
|
||||
// DNS resolver, as it uses `alarm()`, which is second resolution only.
|
||||
// There's no way to detect which DNS resolver is being used from our
|
||||
// end, so we need to round up regardless of the supplied timeout.
|
||||
//
|
||||
// https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609
|
||||
$timeout = max($options['timeout'], 1);
|
||||
|
||||
if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
|
||||
curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
|
||||
} else {
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_timeout_msFound
|
||||
curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
|
||||
}
|
||||
|
||||
if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
|
||||
curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
|
||||
} else {
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_connecttimeout_msFound
|
||||
curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
|
||||
}
|
||||
|
||||
curl_setopt($this->handle, CURLOPT_URL, $url);
|
||||
curl_setopt($this->handle, CURLOPT_USERAGENT, $options['useragent']);
|
||||
if (!empty($headers)) {
|
||||
curl_setopt($this->handle, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
|
||||
if ($options['protocol_version'] === 1.1) {
|
||||
curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
} else {
|
||||
curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
}
|
||||
|
||||
if ($options['blocking'] === true) {
|
||||
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, [$this, 'stream_headers']);
|
||||
curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, [$this, 'stream_body']);
|
||||
curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a response
|
||||
*
|
||||
* @param string $response Response data from the body
|
||||
* @param array $options Request options
|
||||
* @return string|false HTTP response data including headers. False if non-blocking.
|
||||
* @throws \WpOrg\Requests\Exception
|
||||
*/
|
||||
public function process_response($response, $options) {
|
||||
if ($options['blocking'] === false) {
|
||||
$fake_headers = '';
|
||||
$options['hooks']->dispatch('curl.after_request', [&$fake_headers]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($options['filename'] !== false && $this->stream_handle) {
|
||||
fclose($this->stream_handle);
|
||||
$this->headers = trim($this->headers);
|
||||
} else {
|
||||
$this->headers .= $response;
|
||||
}
|
||||
|
||||
if (curl_errno($this->handle)) {
|
||||
$error = sprintf(
|
||||
'cURL error %s: %s',
|
||||
curl_errno($this->handle),
|
||||
curl_error($this->handle)
|
||||
);
|
||||
throw new Exception($error, 'curlerror', $this->handle);
|
||||
}
|
||||
|
||||
$this->info = curl_getinfo($this->handle);
|
||||
|
||||
$options['hooks']->dispatch('curl.after_request', [&$this->headers, &$this->info]);
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the headers as they are received
|
||||
*
|
||||
* @param resource|\CurlHandle $handle cURL handle
|
||||
* @param string $headers Header string
|
||||
* @return integer Length of provided header
|
||||
*/
|
||||
public function stream_headers($handle, $headers) {
|
||||
// Why do we do this? cURL will send both the final response and any
|
||||
// interim responses, such as a 100 Continue. We don't need that.
|
||||
// (We may want to keep this somewhere just in case)
|
||||
if ($this->done_headers) {
|
||||
$this->headers = '';
|
||||
$this->done_headers = false;
|
||||
}
|
||||
|
||||
$this->headers .= $headers;
|
||||
|
||||
if ($headers === "\r\n") {
|
||||
$this->done_headers = true;
|
||||
}
|
||||
|
||||
return strlen($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect data as it's received
|
||||
*
|
||||
* @since 1.6.1
|
||||
*
|
||||
* @param resource|\CurlHandle $handle cURL handle
|
||||
* @param string $data Body data
|
||||
* @return integer Length of provided data
|
||||
*/
|
||||
public function stream_body($handle, $data) {
|
||||
$this->hooks->dispatch('request.progress', [$data, $this->response_bytes, $this->response_byte_limit]);
|
||||
$data_length = strlen($data);
|
||||
|
||||
// Are we limiting the response size?
|
||||
if ($this->response_byte_limit) {
|
||||
if ($this->response_bytes === $this->response_byte_limit) {
|
||||
// Already at maximum, move on
|
||||
return $data_length;
|
||||
}
|
||||
|
||||
if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
|
||||
// Limit the length
|
||||
$limited_length = ($this->response_byte_limit - $this->response_bytes);
|
||||
$data = substr($data, 0, $limited_length);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->stream_handle) {
|
||||
fwrite($this->stream_handle, $data);
|
||||
} else {
|
||||
$this->response_data .= $data;
|
||||
}
|
||||
|
||||
$this->response_bytes += strlen($data);
|
||||
return $data_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a URL given GET data
|
||||
*
|
||||
* @param string $url
|
||||
* @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query}
|
||||
* @return string URL with data
|
||||
*/
|
||||
private static function format_get($url, $data) {
|
||||
if (!empty($data)) {
|
||||
$query = '';
|
||||
$url_parts = parse_url($url);
|
||||
if (empty($url_parts['query'])) {
|
||||
$url_parts['query'] = '';
|
||||
} else {
|
||||
$query = $url_parts['query'];
|
||||
}
|
||||
|
||||
$query .= '&' . http_build_query($data, '', '&');
|
||||
$query = trim($query, '&');
|
||||
|
||||
if (empty($url_parts['query'])) {
|
||||
$url .= '?' . $query;
|
||||
} else {
|
||||
$url = str_replace($url_parts['query'], $query, $url);
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-test whether the transport can be used.
|
||||
*
|
||||
* The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
|
||||
* @return bool Whether the transport can be used.
|
||||
*/
|
||||
public static function test($capabilities = []) {
|
||||
if (!function_exists('curl_init') || !function_exists('curl_exec')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If needed, check that our installed curl version supports SSL
|
||||
if (isset($capabilities[Capability::SSL]) && $capabilities[Capability::SSL]) {
|
||||
$curl_version = curl_version();
|
||||
if (!(CURL_VERSION_SSL & $curl_version['features'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct "Expect" header for the given request data.
|
||||
*
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD.
|
||||
* @return string The "Expect" header.
|
||||
*/
|
||||
private function get_expect_header($data) {
|
||||
if (!is_array($data)) {
|
||||
return strlen((string) $data) >= 1048576 ? '100-Continue' : '';
|
||||
}
|
||||
|
||||
$bytesize = 0;
|
||||
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
|
||||
|
||||
foreach ($iterator as $datum) {
|
||||
$bytesize += strlen((string) $datum);
|
||||
|
||||
if ($bytesize >= 1048576) {
|
||||
return '100-Continue';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
505
api/vendor/rmccue/requests/src/Transport/Fsockopen.php
vendored
Normal file
505
api/vendor/rmccue/requests/src/Transport/Fsockopen.php
vendored
Normal file
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
/**
|
||||
* fsockopen HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Transport;
|
||||
|
||||
use WpOrg\Requests\Capability;
|
||||
use WpOrg\Requests\Exception;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Port;
|
||||
use WpOrg\Requests\Requests;
|
||||
use WpOrg\Requests\Ssl;
|
||||
use WpOrg\Requests\Transport;
|
||||
use WpOrg\Requests\Utility\CaseInsensitiveDictionary;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* fsockopen HTTP transport
|
||||
*
|
||||
* @package Requests\Transport
|
||||
*/
|
||||
final class Fsockopen implements Transport {
|
||||
/**
|
||||
* Second to microsecond conversion
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const SECOND_IN_MICROSECONDS = 1000000;
|
||||
|
||||
/**
|
||||
* Raw HTTP data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $headers = '';
|
||||
|
||||
/**
|
||||
* Stream metadata
|
||||
*
|
||||
* @var array Associative array of properties, see {@link https://www.php.net/stream_get_meta_data}
|
||||
*/
|
||||
public $info;
|
||||
|
||||
/**
|
||||
* What's the maximum number of bytes we should keep?
|
||||
*
|
||||
* @var int|bool Byte count, or false if no limit.
|
||||
*/
|
||||
private $max_bytes = false;
|
||||
|
||||
private $connect_error = '';
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*
|
||||
* @param string|Stringable $url URL to request
|
||||
* @param array $headers Associative array of request headers
|
||||
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
|
||||
* @param array $options Request options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return string Raw HTTP result
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $headers argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data parameter is not an array or string.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
* @throws \WpOrg\Requests\Exception On failure to connect to socket (`fsockopenerror`)
|
||||
* @throws \WpOrg\Requests\Exception On socket timeout (`timeout`)
|
||||
*/
|
||||
public function request($url, $headers = [], $data = [], $options = []) {
|
||||
if (InputValidator::is_string_or_stringable($url) === false) {
|
||||
throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url));
|
||||
}
|
||||
|
||||
if (is_array($headers) === false) {
|
||||
throw InvalidArgument::create(2, '$headers', 'array', gettype($headers));
|
||||
}
|
||||
|
||||
if (!is_array($data) && !is_string($data)) {
|
||||
if ($data === null) {
|
||||
$data = '';
|
||||
} else {
|
||||
throw InvalidArgument::create(3, '$data', 'array|string', gettype($data));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(4, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.before_request');
|
||||
|
||||
$url_parts = parse_url($url);
|
||||
if (empty($url_parts)) {
|
||||
throw new Exception('Invalid URL.', 'invalidurl', $url);
|
||||
}
|
||||
|
||||
$host = $url_parts['host'];
|
||||
$context = stream_context_create();
|
||||
$verifyname = false;
|
||||
$case_insensitive_headers = new CaseInsensitiveDictionary($headers);
|
||||
|
||||
// HTTPS support
|
||||
if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
|
||||
$remote_socket = 'ssl://' . $host;
|
||||
if (!isset($url_parts['port'])) {
|
||||
$url_parts['port'] = Port::HTTPS;
|
||||
}
|
||||
|
||||
$context_options = [
|
||||
'verify_peer' => true,
|
||||
'capture_peer_cert' => true,
|
||||
];
|
||||
$verifyname = true;
|
||||
|
||||
// SNI, if enabled (OpenSSL >=0.9.8j)
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.openssl_tlsext_server_nameFound
|
||||
if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
|
||||
$context_options['SNI_enabled'] = true;
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
$context_options['SNI_enabled'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verify'])) {
|
||||
if ($options['verify'] === false) {
|
||||
$context_options['verify_peer'] = false;
|
||||
$context_options['verify_peer_name'] = false;
|
||||
$verifyname = false;
|
||||
} elseif (is_string($options['verify'])) {
|
||||
$context_options['cafile'] = $options['verify'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['verifyname']) && $options['verifyname'] === false) {
|
||||
$context_options['verify_peer_name'] = false;
|
||||
$verifyname = false;
|
||||
}
|
||||
|
||||
stream_context_set_option($context, ['ssl' => $context_options]);
|
||||
} else {
|
||||
$remote_socket = 'tcp://' . $host;
|
||||
}
|
||||
|
||||
$this->max_bytes = $options['max_bytes'];
|
||||
|
||||
if (!isset($url_parts['port'])) {
|
||||
$url_parts['port'] = Port::HTTP;
|
||||
}
|
||||
|
||||
$remote_socket .= ':' . $url_parts['port'];
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
|
||||
set_error_handler([$this, 'connect_error_handler'], E_WARNING | E_NOTICE);
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.remote_socket', [&$remote_socket]);
|
||||
|
||||
$socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
|
||||
throw new Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
|
||||
}
|
||||
|
||||
if (!$socket) {
|
||||
if ($errno === 0) {
|
||||
// Connection issue
|
||||
throw new Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
|
||||
}
|
||||
|
||||
throw new Exception($errstr, 'fsockopenerror', null, $errno);
|
||||
}
|
||||
|
||||
$data_format = $options['data_format'];
|
||||
|
||||
if ($data_format === 'query') {
|
||||
$path = self::format_get($url_parts, $data);
|
||||
$data = '';
|
||||
} else {
|
||||
$path = self::format_get($url_parts, []);
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.remote_host_path', [&$path, $url]);
|
||||
|
||||
$request_body = '';
|
||||
$out = sprintf("%s %s HTTP/%.1F\r\n", $options['type'], $path, $options['protocol_version']);
|
||||
|
||||
if ($options['type'] !== Requests::TRACE) {
|
||||
if (is_array($data)) {
|
||||
$request_body = http_build_query($data, '', '&');
|
||||
} else {
|
||||
$request_body = $data;
|
||||
}
|
||||
|
||||
// Always include Content-length on POST requests to prevent
|
||||
// 411 errors from some servers when the body is empty.
|
||||
if (!empty($data) || $options['type'] === Requests::POST) {
|
||||
if (!isset($case_insensitive_headers['Content-Length'])) {
|
||||
$headers['Content-Length'] = strlen($request_body);
|
||||
}
|
||||
|
||||
if (!isset($case_insensitive_headers['Content-Type'])) {
|
||||
$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($case_insensitive_headers['Host'])) {
|
||||
$out .= sprintf('Host: %s', $url_parts['host']);
|
||||
$scheme_lower = strtolower($url_parts['scheme']);
|
||||
|
||||
if (($scheme_lower === 'http' && $url_parts['port'] !== Port::HTTP) || ($scheme_lower === 'https' && $url_parts['port'] !== Port::HTTPS)) {
|
||||
$out .= ':' . $url_parts['port'];
|
||||
}
|
||||
|
||||
$out .= "\r\n";
|
||||
}
|
||||
|
||||
if (!isset($case_insensitive_headers['User-Agent'])) {
|
||||
$out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
|
||||
}
|
||||
|
||||
$accept_encoding = $this->accept_encoding();
|
||||
if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
|
||||
$out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
|
||||
}
|
||||
|
||||
$headers = Requests::flatten($headers);
|
||||
|
||||
if (!empty($headers)) {
|
||||
$out .= implode("\r\n", $headers) . "\r\n";
|
||||
}
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.after_headers', [&$out]);
|
||||
|
||||
if (substr($out, -2) !== "\r\n") {
|
||||
$out .= "\r\n";
|
||||
}
|
||||
|
||||
if (!isset($case_insensitive_headers['Connection'])) {
|
||||
$out .= "Connection: Close\r\n";
|
||||
}
|
||||
|
||||
$out .= "\r\n" . $request_body;
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.before_send', [&$out]);
|
||||
|
||||
fwrite($socket, $out);
|
||||
$options['hooks']->dispatch('fsockopen.after_send', [$out]);
|
||||
|
||||
if (!$options['blocking']) {
|
||||
fclose($socket);
|
||||
$fake_headers = '';
|
||||
$options['hooks']->dispatch('fsockopen.after_request', [&$fake_headers]);
|
||||
return '';
|
||||
}
|
||||
|
||||
$timeout_sec = (int) floor($options['timeout']);
|
||||
if ($timeout_sec === $options['timeout']) {
|
||||
$timeout_msec = 0;
|
||||
} else {
|
||||
$timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
|
||||
}
|
||||
|
||||
stream_set_timeout($socket, $timeout_sec, $timeout_msec);
|
||||
|
||||
$response = '';
|
||||
$body = '';
|
||||
$headers = '';
|
||||
$this->info = stream_get_meta_data($socket);
|
||||
$size = 0;
|
||||
$doingbody = false;
|
||||
$download = false;
|
||||
if ($options['filename']) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silenced the PHP native warning in favour of throwing an exception.
|
||||
$download = @fopen($options['filename'], 'wb');
|
||||
if ($download === false) {
|
||||
$error = error_get_last();
|
||||
throw new Exception($error['message'], 'fopen');
|
||||
}
|
||||
}
|
||||
|
||||
while (!feof($socket)) {
|
||||
$this->info = stream_get_meta_data($socket);
|
||||
if ($this->info['timed_out']) {
|
||||
throw new Exception('fsocket timed out', 'timeout');
|
||||
}
|
||||
|
||||
$block = fread($socket, Requests::BUFFER_SIZE);
|
||||
if (!$doingbody) {
|
||||
$response .= $block;
|
||||
if (strpos($response, "\r\n\r\n")) {
|
||||
list($headers, $block) = explode("\r\n\r\n", $response, 2);
|
||||
$doingbody = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Are we in body mode now?
|
||||
if ($doingbody) {
|
||||
$options['hooks']->dispatch('request.progress', [$block, $size, $this->max_bytes]);
|
||||
$data_length = strlen($block);
|
||||
if ($this->max_bytes) {
|
||||
// Have we already hit a limit?
|
||||
if ($size === $this->max_bytes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($size + $data_length) > $this->max_bytes) {
|
||||
// Limit the length
|
||||
$limited_length = ($this->max_bytes - $size);
|
||||
$block = substr($block, 0, $limited_length);
|
||||
}
|
||||
}
|
||||
|
||||
$size += strlen($block);
|
||||
if ($download) {
|
||||
fwrite($download, $block);
|
||||
} else {
|
||||
$body .= $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->headers = $headers;
|
||||
|
||||
if ($download) {
|
||||
fclose($download);
|
||||
} else {
|
||||
$this->headers .= "\r\n\r\n" . $body;
|
||||
}
|
||||
|
||||
fclose($socket);
|
||||
|
||||
$options['hooks']->dispatch('fsockopen.after_request', [&$this->headers, &$this->info]);
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send multiple requests simultaneously
|
||||
*
|
||||
* @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see \WpOrg\Requests\Transport::request()}
|
||||
* @param array $options Global options, see {@see \WpOrg\Requests\Requests::response()} for documentation
|
||||
* @return array Array of \WpOrg\Requests\Response objects (may contain \WpOrg\Requests\Exception or string responses as well)
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access.
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array.
|
||||
*/
|
||||
public function request_multiple($requests, $options) {
|
||||
// If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
|
||||
if (empty($requests)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) {
|
||||
throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests));
|
||||
}
|
||||
|
||||
if (is_array($options) === false) {
|
||||
throw InvalidArgument::create(2, '$options', 'array', gettype($options));
|
||||
}
|
||||
|
||||
$responses = [];
|
||||
$class = get_class($this);
|
||||
foreach ($requests as $id => $request) {
|
||||
try {
|
||||
$handler = new $class();
|
||||
$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
|
||||
|
||||
$request['options']['hooks']->dispatch('transport.internal.parse_response', [&$responses[$id], $request]);
|
||||
} catch (Exception $e) {
|
||||
$responses[$id] = $e;
|
||||
}
|
||||
|
||||
if (!is_string($responses[$id])) {
|
||||
$request['options']['hooks']->dispatch('multiple.request.complete', [&$responses[$id], $id]);
|
||||
}
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the encodings we can accept
|
||||
*
|
||||
* @return string Accept-Encoding header value
|
||||
*/
|
||||
private static function accept_encoding() {
|
||||
$type = [];
|
||||
if (function_exists('gzinflate')) {
|
||||
$type[] = 'deflate;q=1.0';
|
||||
}
|
||||
|
||||
if (function_exists('gzuncompress')) {
|
||||
$type[] = 'compress;q=0.5';
|
||||
}
|
||||
|
||||
$type[] = 'gzip;q=0.5';
|
||||
|
||||
return implode(', ', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a URL given GET data
|
||||
*
|
||||
* @param array $url_parts
|
||||
* @param array|object $data Data to build query using, see {@link https://www.php.net/http_build_query}
|
||||
* @return string URL with data
|
||||
*/
|
||||
private static function format_get($url_parts, $data) {
|
||||
if (!empty($data)) {
|
||||
if (empty($url_parts['query'])) {
|
||||
$url_parts['query'] = '';
|
||||
}
|
||||
|
||||
$url_parts['query'] .= '&' . http_build_query($data, '', '&');
|
||||
$url_parts['query'] = trim($url_parts['query'], '&');
|
||||
}
|
||||
|
||||
if (isset($url_parts['path'])) {
|
||||
if (isset($url_parts['query'])) {
|
||||
$get = $url_parts['path'] . '?' . $url_parts['query'];
|
||||
} else {
|
||||
$get = $url_parts['path'];
|
||||
}
|
||||
} else {
|
||||
$get = '/';
|
||||
}
|
||||
|
||||
return $get;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for stream_socket_client()
|
||||
*
|
||||
* @param int $errno Error number (e.g. E_WARNING)
|
||||
* @param string $errstr Error message
|
||||
*/
|
||||
public function connect_error_handler($errno, $errstr) {
|
||||
// Double-check we can handle it
|
||||
if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
|
||||
// Return false to indicate the default error handler should engage
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->connect_error .= $errstr . "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the certificate against common name and subject alternative names
|
||||
*
|
||||
* Unfortunately, PHP doesn't check the certificate against the alternative
|
||||
* names, leading things like 'https://www.github.com/' to be invalid.
|
||||
* Instead
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
|
||||
*
|
||||
* @param string $host Host name to verify against
|
||||
* @param resource $context Stream context
|
||||
* @return bool
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
|
||||
* @throws \WpOrg\Requests\Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
|
||||
*/
|
||||
public function verify_certificate_from_context($host, $context) {
|
||||
$meta = stream_context_get_options($context);
|
||||
|
||||
// If we don't have SSL options, then we couldn't make the connection at
|
||||
// all
|
||||
if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
|
||||
throw new Exception(rtrim($this->connect_error), 'ssl.connect_error');
|
||||
}
|
||||
|
||||
$cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
|
||||
|
||||
return Ssl::verify_certificate($host, $cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-test whether the transport can be used.
|
||||
*
|
||||
* The available capabilities to test for can be found in {@see \WpOrg\Requests\Capability}.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`.
|
||||
* @return bool Whether the transport can be used.
|
||||
*/
|
||||
public static function test($capabilities = []) {
|
||||
if (!function_exists('fsockopen')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If needed, check that streams support SSL
|
||||
if (isset($capabilities[Capability::SSL]) && $capabilities[Capability::SSL]) {
|
||||
if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
127
api/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php
vendored
Normal file
127
api/vendor/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Utility;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use ReturnTypeWillChange;
|
||||
use WpOrg\Requests\Exception;
|
||||
|
||||
/**
|
||||
* Case-insensitive dictionary, suitable for HTTP headers
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
class CaseInsensitiveDictionary implements ArrayAccess, IteratorAggregate {
|
||||
/**
|
||||
* Actual item data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* Creates a case insensitive dictionary.
|
||||
*
|
||||
* @param array $data Dictionary/map to convert to case-insensitive
|
||||
*/
|
||||
public function __construct(array $data = []) {
|
||||
foreach ($data as $offset => $value) {
|
||||
$this->offsetSet($offset, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item exists
|
||||
*
|
||||
* @param string $offset Item key
|
||||
* @return boolean Does the item exist?
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset) {
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
return isset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the item
|
||||
*
|
||||
* @param string $offset Item key
|
||||
* @return string|null Item value (null if the item key doesn't exist)
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset) {
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
if (!isset($this->data[$offset])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->data[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given item
|
||||
*
|
||||
* @param string $offset Item name
|
||||
* @param string $value Item value
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception On attempting to use dictionary as list (`invalidset`)
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value) {
|
||||
if ($offset === null) {
|
||||
throw new Exception('Object is a dictionary, not a list', 'invalidset');
|
||||
}
|
||||
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the given header
|
||||
*
|
||||
* @param string $offset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset) {
|
||||
if (is_string($offset)) {
|
||||
$offset = strtolower($offset);
|
||||
}
|
||||
|
||||
unset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the data
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers as an array
|
||||
*
|
||||
* @return array Header data
|
||||
*/
|
||||
public function getAll() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
82
api/vendor/rmccue/requests/src/Utility/FilteredIterator.php
vendored
Normal file
82
api/vendor/rmccue/requests/src/Utility/FilteredIterator.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* Iterator for arrays requiring filtered values
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Utility;
|
||||
|
||||
use ArrayIterator;
|
||||
use ReturnTypeWillChange;
|
||||
use WpOrg\Requests\Exception\InvalidArgument;
|
||||
use WpOrg\Requests\Utility\InputValidator;
|
||||
|
||||
/**
|
||||
* Iterator for arrays requiring filtered values
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
final class FilteredIterator extends ArrayIterator {
|
||||
/**
|
||||
* Callback to run as a filter
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
private $callback;
|
||||
|
||||
/**
|
||||
* Create a new iterator
|
||||
*
|
||||
* @param array $data
|
||||
* @param callable $callback Callback to be called on each value
|
||||
*
|
||||
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $data argument is not iterable.
|
||||
*/
|
||||
public function __construct($data, $callback) {
|
||||
if (InputValidator::is_iterable($data) === false) {
|
||||
throw InvalidArgument::create(1, '$data', 'iterable', gettype($data));
|
||||
}
|
||||
|
||||
parent::__construct($data);
|
||||
|
||||
if (is_callable($callback)) {
|
||||
$this->callback = $callback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function __unserialize($data) {}
|
||||
// phpcs:enable
|
||||
|
||||
public function __wakeup() {
|
||||
unset($this->callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current item's value after filtering
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function current() {
|
||||
$value = parent::current();
|
||||
|
||||
if (is_callable($this->callback)) {
|
||||
$value = call_user_func($this->callback, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function unserialize($data) {}
|
||||
}
|
||||
109
api/vendor/rmccue/requests/src/Utility/InputValidator.php
vendored
Normal file
109
api/vendor/rmccue/requests/src/Utility/InputValidator.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Input validation utilities.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Utility;
|
||||
|
||||
use ArrayAccess;
|
||||
use CurlHandle;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Input validation utilities.
|
||||
*
|
||||
* @package Requests\Utilities
|
||||
*/
|
||||
final class InputValidator {
|
||||
|
||||
/**
|
||||
* Verify that a received input parameter is of type string or is "stringable".
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_string_or_stringable($input) {
|
||||
return is_string($input) || self::is_stringable_object($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether a received input parameter is usable as an integer array key.
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_numeric_array_key($input) {
|
||||
if (is_int($input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_string($input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) preg_match('`^-?[0-9]+$`', $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether a received input parameter is "stringable".
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_stringable_object($input) {
|
||||
return is_object($input) && method_exists($input, '__toString');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether a received input parameter is _accessible as if it were an array_.
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_array_access($input) {
|
||||
return is_array($input) || $input instanceof ArrayAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether a received input parameter is "iterable".
|
||||
*
|
||||
* @internal The PHP native `is_iterable()` function was only introduced in PHP 7.1
|
||||
* and this library still supports PHP 5.6.
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_iterable($input) {
|
||||
return is_array($input) || $input instanceof Traversable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether a received input parameter is a Curl handle.
|
||||
*
|
||||
* The PHP Curl extension worked with resources prior to PHP 8.0 and with
|
||||
* an instance of the `CurlHandle` class since PHP 8.0.
|
||||
* {@link https://www.php.net/manual/en/migration80.incompatible.php#migration80.incompatible.resource2object}
|
||||
*
|
||||
* @param mixed $input Input parameter to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_curl_handle($input) {
|
||||
if (is_resource($input)) {
|
||||
return get_resource_type($input) === 'curl';
|
||||
}
|
||||
|
||||
if (is_object($input)) {
|
||||
return $input instanceof CurlHandle;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user