080600
This commit is contained in:
@@ -1,36 +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);
|
||||
}
|
||||
<?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);
|
||||
}
|
||||
|
||||
@@ -1,103 +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;
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,187 +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 Requests 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
<?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 Requests 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +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 string[]
|
||||
*/
|
||||
const ALL = [
|
||||
self::SSL,
|
||||
];
|
||||
}
|
||||
<?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 string[]
|
||||
*/
|
||||
const ALL = [
|
||||
self::SSL,
|
||||
];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,187 +1,187 @@
|
||||
<?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 Cookie header value, possibly pre-parsed (object).
|
||||
* @param string $key Optional. The name for this 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 The key for the item to unset.
|
||||
*/
|
||||
#[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 Response as received.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
<?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 Cookie header value, possibly pre-parsed (object).
|
||||
* @param string $key Optional. The name for this 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 The key for the item to unset.
|
||||
*/
|
||||
#[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 Response as received.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +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;
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +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
|
||||
);
|
||||
}
|
||||
}
|
||||
<?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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +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;
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,35 +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";
|
||||
}
|
||||
<?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";
|
||||
}
|
||||
|
||||
@@ -1,35 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,35 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,35 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,31 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,35 +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';
|
||||
}
|
||||
<?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';
|
||||
}
|
||||
|
||||
@@ -1,49 +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);
|
||||
}
|
||||
}
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
<?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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +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 {}
|
||||
<?php
|
||||
/**
|
||||
* Transport Exception
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
|
||||
namespace WpOrg\Requests\Exception;
|
||||
|
||||
use WpOrg\Requests\Exception;
|
||||
|
||||
/**
|
||||
* Transport Exception
|
||||
*
|
||||
* @package Requests\Exceptions
|
||||
*/
|
||||
class Transport extends Exception {}
|
||||
|
||||
@@ -1,80 +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;
|
||||
}
|
||||
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +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 = []);
|
||||
}
|
||||
<?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 = []);
|
||||
}
|
||||
|
||||
@@ -1,103 +1,103 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,412 +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 Text to examine.
|
||||
* @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 Text to prepare.
|
||||
* @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 Text to convert.
|
||||
* @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 = (int) ($t + (($q - $t) % (self::BOOTSTRAP_BASE - $t)));
|
||||
$output .= self::digit_to_char($digit);
|
||||
// let q = (q - t) div (base - t)
|
||||
$q = (int) 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|float 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));
|
||||
}
|
||||
}
|
||||
<?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 Text to examine.
|
||||
* @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 Text to prepare.
|
||||
* @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 Text to convert.
|
||||
* @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 = (int) ($t + (($q - $t) % (self::BOOTSTRAP_BASE - $t)));
|
||||
$output .= self::digit_to_char($digit);
|
||||
// let q = (q - t) div (base - t)
|
||||
$q = (int) 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|float 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,203 +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;
|
||||
}
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +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}");
|
||||
}
|
||||
}
|
||||
<?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}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +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);
|
||||
}
|
||||
<?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);
|
||||
}
|
||||
|
||||
@@ -1,164 +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;
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,165 +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|null $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;
|
||||
}
|
||||
}
|
||||
<?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|null $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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,127 +1,127 @@
|
||||
<?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 Name of the header to retrieve.
|
||||
* @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 Name of the header to retrieve.
|
||||
* @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));
|
||||
}
|
||||
|
||||
if (is_string($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']);
|
||||
}
|
||||
}
|
||||
<?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 Name of the header to retrieve.
|
||||
* @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 Name of the header to retrieve.
|
||||
* @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));
|
||||
}
|
||||
|
||||
if (is_string($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']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,308 +1,308 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
<?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);
|
||||
}
|
||||
|
||||
public function __wakeup() {
|
||||
throw new \LogicException( __CLASS__ . ' should never be unserialized' );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,182 +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;
|
||||
}
|
||||
}
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +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 = []);
|
||||
}
|
||||
<?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 = []);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,127 +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 The key for the item to unset.
|
||||
*/
|
||||
#[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;
|
||||
}
|
||||
}
|
||||
<?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 The key for the item to unset.
|
||||
*/
|
||||
#[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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +1,97 @@
|
||||
<?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 The array or object to be iterated on.
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent unserialization of the object for security reasons.
|
||||
*
|
||||
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
|
||||
*
|
||||
* @param array $data Restored array of data originally serialized.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function __unserialize($data) {}
|
||||
// phpcs:enable
|
||||
|
||||
/**
|
||||
* Perform reinitialization tasks.
|
||||
*
|
||||
* Prevents a callback from being injected during unserialization of an object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent creating a PHP value from a stored representation of the object for security reasons.
|
||||
*
|
||||
* @param string $data The serialized string.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function unserialize($data) {}
|
||||
}
|
||||
<?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 The array or object to be iterated on.
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent unserialization of the object for security reasons.
|
||||
*
|
||||
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
|
||||
*
|
||||
* @param array $data Restored array of data originally serialized.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function __unserialize($data) {}
|
||||
// phpcs:enable
|
||||
|
||||
/**
|
||||
* Perform reinitialization tasks.
|
||||
*
|
||||
* Prevents a callback from being injected during unserialization of an object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent creating a PHP value from a stored representation of the object for security reasons.
|
||||
*
|
||||
* @param string $data The serialized string.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function unserialize($data) {}
|
||||
}
|
||||
|
||||
@@ -1,109 +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;
|
||||
}
|
||||
}
|
||||
<?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