wip
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@ final class BodySummarizer implements \YoastSEO_Vendor\GuzzleHttp\BodySummarizer
|
||||
* @var int|null
|
||||
*/
|
||||
private $truncateAt;
|
||||
public function __construct(int $truncateAt = null)
|
||||
public function __construct(?int $truncateAt = null)
|
||||
{
|
||||
$this->truncateAt = $truncateAt;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class Client implements \YoastSEO_Vendor\GuzzleHttp\ClientInterface, \YoastSEO_V
|
||||
*
|
||||
* @param array $config Client configuration settings.
|
||||
*
|
||||
* @see \GuzzleHttp\RequestOptions for a list of available request options.
|
||||
* @see RequestOptions for a list of available request options.
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
@@ -178,7 +178,7 @@ class Client implements \YoastSEO_Vendor\GuzzleHttp\ClientInterface, \YoastSEO_V
|
||||
*
|
||||
* @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
||||
*/
|
||||
public function getConfig(string $option = null)
|
||||
public function getConfig(?string $option = null)
|
||||
{
|
||||
return $option === null ? $this->config : $this->config[$option] ?? null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -74,5 +74,5 @@ interface ClientInterface
|
||||
*
|
||||
* @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
|
||||
*/
|
||||
public function getConfig(string $option = null);
|
||||
public function getConfig(?string $option = null);
|
||||
}
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ class CookieJar implements \YoastSEO_Vendor\GuzzleHttp\Cookie\CookieJarInterface
|
||||
return $cookie->toArray();
|
||||
}, $this->getIterator()->getArrayCopy());
|
||||
}
|
||||
public function clear(string $domain = null, string $path = null, string $name = null) : void
|
||||
public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void
|
||||
{
|
||||
if (!$domain) {
|
||||
$this->cookies = [];
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate
|
||||
* @param string|null $path Clears cookies matching a domain and path
|
||||
* @param string|null $name Clears cookies matching a domain, path, and name
|
||||
*/
|
||||
public function clear(string $domain = null, string $path = null, string $name = null) : void;
|
||||
public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void;
|
||||
/**
|
||||
* Discard all sessions cookies.
|
||||
*
|
||||
|
||||
+4
@@ -46,6 +46,10 @@ class SetCookie
|
||||
if (\is_numeric($value)) {
|
||||
$data[$search] = (int) $value;
|
||||
}
|
||||
} elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') {
|
||||
if ($value) {
|
||||
$data[$search] = \true;
|
||||
}
|
||||
} else {
|
||||
$data[$search] = $value;
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
|
||||
*/
|
||||
class BadResponseException extends \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException
|
||||
{
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, \Throwable $previous = null, array $handlerContext = [])
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, ?\Throwable $previous = null, array $handlerContext = [])
|
||||
{
|
||||
parent::__construct($message, $request, $response, $previous, $handlerContext);
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ class ConnectException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
|
||||
* @var array
|
||||
*/
|
||||
private $handlerContext;
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \Throwable $previous = null, array $handlerContext = [])
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\Throwable $previous = null, array $handlerContext = [])
|
||||
{
|
||||
parent::__construct($message, 0, $previous);
|
||||
$this->request = $request;
|
||||
|
||||
+3
-16
@@ -7,7 +7,6 @@ use YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface;
|
||||
use YoastSEO_Vendor\Psr\Http\Client\RequestExceptionInterface;
|
||||
use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
|
||||
use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
|
||||
use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
|
||||
/**
|
||||
* HTTP Request exception
|
||||
*/
|
||||
@@ -25,7 +24,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
|
||||
* @var array
|
||||
*/
|
||||
private $handlerContext;
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $previous = null, array $handlerContext = [])
|
||||
public function __construct(string $message, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [])
|
||||
{
|
||||
// Set the code of the exception if the response is set and not future.
|
||||
$code = $response ? $response->getStatusCode() : 0;
|
||||
@@ -50,7 +49,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
|
||||
* @param array $handlerContext Optional handler context
|
||||
* @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer
|
||||
*/
|
||||
public static function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $previous = null, array $handlerContext = [], \YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : self
|
||||
public static function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [], ?\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : self
|
||||
{
|
||||
if (!$response) {
|
||||
return new self('Error completing request', $request, null, $previous, $handlerContext);
|
||||
@@ -66,8 +65,7 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
|
||||
$label = 'Unsuccessful request';
|
||||
$className = __CLASS__;
|
||||
}
|
||||
$uri = $request->getUri();
|
||||
$uri = static::obfuscateUri($uri);
|
||||
$uri = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
|
||||
// Client Error: `GET /` resulted in a `404 Not Found` response:
|
||||
// <html> ... (truncated)
|
||||
$message = \sprintf('%s: `%s %s` resulted in a `%s %s` response', $label, $request->getMethod(), $uri->__toString(), $response->getStatusCode(), $response->getReasonPhrase());
|
||||
@@ -77,17 +75,6 @@ class RequestException extends \YoastSEO_Vendor\GuzzleHttp\Exception\TransferExc
|
||||
}
|
||||
return new $className($message, $request, $response, $previous, $handlerContext);
|
||||
}
|
||||
/**
|
||||
* Obfuscates URI if there is a username and a password present
|
||||
*/
|
||||
private static function obfuscateUri(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : \YoastSEO_Vendor\Psr\Http\Message\UriInterface
|
||||
{
|
||||
$userInfo = $uri->getUserInfo();
|
||||
if (\false !== ($pos = \strpos($userInfo, ':'))) {
|
||||
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
/**
|
||||
* Get the request that caused the exception
|
||||
*/
|
||||
|
||||
+91
-20
@@ -11,6 +11,7 @@ use YoastSEO_Vendor\GuzzleHttp\Psr7\LazyOpenStream;
|
||||
use YoastSEO_Vendor\GuzzleHttp\TransferStats;
|
||||
use YoastSEO_Vendor\GuzzleHttp\Utils;
|
||||
use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
|
||||
use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
|
||||
/**
|
||||
* Creates curl resources from a request
|
||||
*
|
||||
@@ -40,6 +41,14 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
}
|
||||
public function create(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options) : \YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle
|
||||
{
|
||||
$protocolVersion = $request->getProtocolVersion();
|
||||
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
|
||||
if (!self::supportsHttp2()) {
|
||||
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
|
||||
}
|
||||
} elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
|
||||
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
|
||||
}
|
||||
if (isset($options['curl']['body_as_string'])) {
|
||||
$options['_body_as_string'] = $options['curl']['body_as_string'];
|
||||
unset($options['curl']['body_as_string']);
|
||||
@@ -61,12 +70,38 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
\curl_setopt_array($easy->handle, $conf);
|
||||
return $easy;
|
||||
}
|
||||
private static function supportsHttp2() : bool
|
||||
{
|
||||
static $supportsHttp2 = null;
|
||||
if (null === $supportsHttp2) {
|
||||
$supportsHttp2 = self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && \CURL_VERSION_HTTP2 & \curl_version()['features'];
|
||||
}
|
||||
return $supportsHttp2;
|
||||
}
|
||||
private static function supportsTls12() : bool
|
||||
{
|
||||
static $supportsTls12 = null;
|
||||
if (null === $supportsTls12) {
|
||||
$supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
|
||||
}
|
||||
return $supportsTls12;
|
||||
}
|
||||
private static function supportsTls13() : bool
|
||||
{
|
||||
static $supportsTls13 = null;
|
||||
if (null === $supportsTls13) {
|
||||
$supportsTls13 = \defined('CURL_SSLVERSION_TLSv1_3') && \CURL_SSLVERSION_TLSv1_3 & \curl_version()['features'];
|
||||
}
|
||||
return $supportsTls13;
|
||||
}
|
||||
public function release(\YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle $easy) : void
|
||||
{
|
||||
$resource = $easy->handle;
|
||||
unset($easy->handle);
|
||||
if (\count($this->handles) >= $this->maxHandles) {
|
||||
\curl_close($resource);
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
\curl_close($resource);
|
||||
}
|
||||
} else {
|
||||
// Remove all callback functions as they can hold onto references
|
||||
// and are not cleaned up by curl_reset. Using curl_setopt_array
|
||||
@@ -118,7 +153,7 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
{
|
||||
// Get error information and release the handle to the factory.
|
||||
$ctx = ['errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME)] + \curl_getinfo($easy->handle);
|
||||
$ctx[self::CURL_VERSION_STR] = \curl_version()['version'];
|
||||
$ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
|
||||
$factory->release($easy);
|
||||
// Retry when nothing is present or when curl failed to rewind.
|
||||
if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
|
||||
@@ -126,6 +161,14 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
}
|
||||
return self::createRejection($easy, $ctx);
|
||||
}
|
||||
private static function getCurlVersion() : string
|
||||
{
|
||||
static $curlVersion = null;
|
||||
if (null === $curlVersion) {
|
||||
$curlVersion = \curl_version()['version'];
|
||||
}
|
||||
return $curlVersion;
|
||||
}
|
||||
private static function createRejection(\YoastSEO_Vendor\GuzzleHttp\Handler\EasyHandle $easy, array $ctx) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
static $connectionErrors = [\CURLE_OPERATION_TIMEOUTED => \true, \CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
|
||||
@@ -137,15 +180,32 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
if ($easy->onHeadersException) {
|
||||
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor(new \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException('An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx));
|
||||
}
|
||||
$message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $ctx['error'], 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
|
||||
$uriString = (string) $easy->request->getUri();
|
||||
if ($uriString !== '' && \false === \strpos($ctx['error'], $uriString)) {
|
||||
$message .= \sprintf(' for %s', $uriString);
|
||||
$uri = $easy->request->getUri();
|
||||
$sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
|
||||
$message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
|
||||
if ('' !== $sanitizedError) {
|
||||
$redactedUriString = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
|
||||
if ($redactedUriString !== '' && \false === \strpos($sanitizedError, $redactedUriString)) {
|
||||
$message .= \sprintf(' for %s', $redactedUriString);
|
||||
}
|
||||
}
|
||||
// Create a connection exception if it was a specific error code.
|
||||
$error = isset($connectionErrors[$easy->errno]) ? new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException($message, $easy->request, null, $ctx) : new \YoastSEO_Vendor\GuzzleHttp\Exception\RequestException($message, $easy->request, $easy->response, null, $ctx);
|
||||
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor($error);
|
||||
}
|
||||
private static function sanitizeCurlError(string $error, \YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : string
|
||||
{
|
||||
if ('' === $error) {
|
||||
return $error;
|
||||
}
|
||||
$baseUri = $uri->withQuery('')->withFragment('');
|
||||
$baseUriString = $baseUri->__toString();
|
||||
if ('' === $baseUriString) {
|
||||
return $error;
|
||||
}
|
||||
$redactedUriString = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
|
||||
return \str_replace($baseUriString, $redactedUriString, $error);
|
||||
}
|
||||
/**
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
@@ -156,10 +216,10 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
$conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
|
||||
}
|
||||
$version = $easy->request->getProtocolVersion();
|
||||
if ($version == 1.1) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
|
||||
} elseif ($version == 2.0) {
|
||||
if ('2' === $version || '2.0' === $version) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
|
||||
} elseif ('1.1' === $version) {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
|
||||
} else {
|
||||
$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
|
||||
}
|
||||
@@ -285,8 +345,10 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
// The empty string enables all available decoders and implicitly
|
||||
// sets a matching 'Accept-Encoding' header.
|
||||
$conf[\CURLOPT_ENCODING] = '';
|
||||
// But as the user did not specify any acceptable encodings we need
|
||||
// to overwrite this implicit header with an empty one.
|
||||
// But as the user did not specify any encoding preference,
|
||||
// let's leave it up to server by preventing curl from sending
|
||||
// the header, which will be interpreted as 'Accept-Encoding: *'.
|
||||
// https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
|
||||
$conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
|
||||
}
|
||||
}
|
||||
@@ -343,23 +405,30 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
}
|
||||
}
|
||||
if (isset($options['crypto_method'])) {
|
||||
if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
|
||||
if (!\defined('CURL_SSLVERSION_TLSv1_0')) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.0 not supported by your version of cURL');
|
||||
$protocolVersion = $easy->request->getProtocolVersion();
|
||||
// If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
|
||||
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
|
||||
if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
|
||||
} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
|
||||
if (!self::supportsTls13()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
|
||||
}
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
|
||||
if (!\defined('CURL_SSLVERSION_TLSv1_1')) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.1 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
|
||||
} elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
|
||||
if (!\defined('CURL_SSLVERSION_TLSv1_2')) {
|
||||
if (!self::supportsTls12()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
|
||||
} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
|
||||
if (!\defined('CURL_SSLVERSION_TLSv1_3')) {
|
||||
if (!self::supportsTls13()) {
|
||||
throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
|
||||
}
|
||||
$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
|
||||
@@ -489,7 +558,9 @@ class CurlFactory implements \YoastSEO_Vendor\GuzzleHttp\Handler\CurlFactoryInte
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->handles as $id => $handle) {
|
||||
\curl_close($handle);
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
unset($this->handles[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-1
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace YoastSEO_Vendor\GuzzleHttp\Handler;
|
||||
|
||||
use Closure;
|
||||
use YoastSEO_Vendor\GuzzleHttp\Promise as P;
|
||||
use YoastSEO_Vendor\GuzzleHttp\Promise\Promise;
|
||||
use YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
|
||||
@@ -129,6 +130,8 @@ class CurlMultiHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run curl_multi_exec in the queue to enable other async tasks to run
|
||||
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->add(\Closure::fromCallable([$this, 'tickInQueue']));
|
||||
// Step through the task queue which may add additional requests.
|
||||
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->run();
|
||||
if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) {
|
||||
@@ -137,9 +140,21 @@ class CurlMultiHandler
|
||||
\usleep(250);
|
||||
}
|
||||
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
|
||||
// Prevent busy looping for slow HTTP requests.
|
||||
\curl_multi_select($this->_mh, $this->selectTimeout);
|
||||
}
|
||||
$this->processMessages();
|
||||
}
|
||||
/**
|
||||
* Runs \curl_multi_exec() inside the event loop, to prevent busy looping
|
||||
*/
|
||||
private function tickInQueue() : void
|
||||
{
|
||||
if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
|
||||
\curl_multi_select($this->_mh, 0);
|
||||
\YoastSEO_Vendor\GuzzleHttp\Promise\Utils::queue()->add(\Closure::fromCallable([$this, 'tickInQueue']));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Runs until all outstanding connections have completed.
|
||||
*/
|
||||
@@ -184,7 +199,9 @@ class CurlMultiHandler
|
||||
$handle = $this->handles[$id]['easy']->handle;
|
||||
unset($this->delays[$id], $this->handles[$id]);
|
||||
\curl_multi_remove_handle($this->_mh, $handle);
|
||||
\curl_close($handle);
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
private function processMessages() : void
|
||||
|
||||
+4
-4
@@ -46,20 +46,20 @@ class MockHandler implements \Countable
|
||||
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
|
||||
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
|
||||
*/
|
||||
public static function createWithMiddleware(array $queue = null, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\HandlerStack
|
||||
public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\HandlerStack
|
||||
{
|
||||
return \YoastSEO_Vendor\GuzzleHttp\HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
|
||||
}
|
||||
/**
|
||||
* The passed in value must be an array of
|
||||
* {@see \Psr\Http\Message\ResponseInterface} objects, Exceptions,
|
||||
* {@see ResponseInterface} objects, Exceptions,
|
||||
* callables, or Promises.
|
||||
*
|
||||
* @param array<int, mixed>|null $queue The parameters to be passed to the append function, as an indexed array.
|
||||
* @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
|
||||
* @param callable|null $onRejected Callback to invoke when the return value is rejected.
|
||||
*/
|
||||
public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null)
|
||||
public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null)
|
||||
{
|
||||
$this->onFulfilled = $onFulfilled;
|
||||
$this->onRejected = $onRejected;
|
||||
@@ -163,7 +163,7 @@ class MockHandler implements \Countable
|
||||
/**
|
||||
* @param mixed $reason Promise or reason.
|
||||
*/
|
||||
private function invokeStats(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, $reason = null) : void
|
||||
private function invokeStats(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, $reason = null) : void
|
||||
{
|
||||
if (isset($options['on_stats'])) {
|
||||
$transferTime = $options['transfer_time'] ?? 0;
|
||||
|
||||
+6
-6
@@ -16,10 +16,10 @@ class Proxy
|
||||
* Sends synchronous requests to a specific handler while sending all other
|
||||
* requests to another handler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync Handler used for synchronous responses.
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $sync Handler used for synchronous responses.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapSync(callable $default, callable $sync) : callable
|
||||
{
|
||||
@@ -35,10 +35,10 @@ class Proxy
|
||||
* performance benefits of curl while still supporting true streaming
|
||||
* through the StreamHandler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $streaming Handler used for streaming responses
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapStreaming(callable $default, callable $streaming) : callable
|
||||
{
|
||||
|
||||
+14
-5
@@ -37,13 +37,17 @@ class StreamHandler
|
||||
if (isset($options['delay'])) {
|
||||
\usleep($options['delay'] * 1000);
|
||||
}
|
||||
$protocolVersion = $request->getProtocolVersion();
|
||||
if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
|
||||
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
|
||||
}
|
||||
$startTime = isset($options['on_stats']) ? \YoastSEO_Vendor\GuzzleHttp\Utils::currentTime() : null;
|
||||
try {
|
||||
// Does not support the expect header.
|
||||
$request = $request->withoutHeader('Expect');
|
||||
// Append a content-length header if body size is zero to match
|
||||
// cURL's behavior.
|
||||
if (0 === $request->getBody()->getSize()) {
|
||||
// the behavior of `CurlHandler`
|
||||
if ((0 === \strcasecmp('PUT', $request->getMethod()) || 0 === \strcasecmp('POST', $request->getMethod())) && 0 === $request->getBody()->getSize()) {
|
||||
$request = $request->withHeader('Content-Length', '0');
|
||||
}
|
||||
return $this->createResponse($request, $options, $this->createStream($request, $options), $startTime);
|
||||
@@ -62,7 +66,7 @@ class StreamHandler
|
||||
return \YoastSEO_Vendor\GuzzleHttp\Promise\Create::rejectionFor($e);
|
||||
}
|
||||
}
|
||||
private function invokeStats(array $options, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?float $startTime, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : void
|
||||
private function invokeStats(array $options, \YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?float $startTime, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : void
|
||||
{
|
||||
if (isset($options['on_stats'])) {
|
||||
$stats = new \YoastSEO_Vendor\GuzzleHttp\TransferStats($request, $response, \YoastSEO_Vendor\GuzzleHttp\Utils::currentTime() - $startTime, $error, []);
|
||||
@@ -210,7 +214,7 @@ class StreamHandler
|
||||
}
|
||||
// HTTP/1.1 streams using the PHP stream wrapper require a
|
||||
// Connection: close header
|
||||
if ($request->getProtocolVersion() == '1.1' && !$request->hasHeader('Connection')) {
|
||||
if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection')) {
|
||||
$request = $request->withHeader('Connection', 'close');
|
||||
}
|
||||
// Ensure SSL is verified by default
|
||||
@@ -244,8 +248,13 @@ class StreamHandler
|
||||
$contextResource = $this->createResource(static function () use($context, $params) {
|
||||
return \stream_context_create($context, $params);
|
||||
});
|
||||
return $this->createResource(function () use($uri, &$http_response_header, $contextResource, $context, $options, $request) {
|
||||
return $this->createResource(function () use($uri, $contextResource, $context, $options, $request) {
|
||||
$resource = @\fopen((string) $uri, 'r', \false, $contextResource);
|
||||
// See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
|
||||
if (\function_exists('YoastSEO_Vendor\\http_get_last_response_headers')) {
|
||||
/** @var array|null */
|
||||
$http_response_header = \YoastSEO_Vendor\http_get_last_response_headers();
|
||||
}
|
||||
$this->lastHeaders = $http_response_header ?? [];
|
||||
if (\false === $resource) {
|
||||
throw new \YoastSEO_Vendor\GuzzleHttp\Exception\ConnectException(\sprintf('Connection refused for URI %s', $uri), $request, null, $context);
|
||||
|
||||
+3
-3
@@ -40,7 +40,7 @@ class HandlerStack
|
||||
* handler is provided, the best handler for your
|
||||
* system will be utilized.
|
||||
*/
|
||||
public static function create(callable $handler = null) : self
|
||||
public static function create(?callable $handler = null) : self
|
||||
{
|
||||
$stack = new self($handler ?: \YoastSEO_Vendor\GuzzleHttp\Utils::chooseHandler());
|
||||
$stack->push(\YoastSEO_Vendor\GuzzleHttp\Middleware::httpErrors(), 'http_errors');
|
||||
@@ -52,7 +52,7 @@ class HandlerStack
|
||||
/**
|
||||
* @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
|
||||
*/
|
||||
public function __construct(callable $handler = null)
|
||||
public function __construct(?callable $handler = null)
|
||||
{
|
||||
$this->handler = $handler;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class HandlerStack
|
||||
* @param callable(callable): callable $middleware Middleware function
|
||||
* @param string $name Name to register for this middleware.
|
||||
*/
|
||||
public function unshift(callable $middleware, string $name = null) : void
|
||||
public function unshift(callable $middleware, ?string $name = null) : void
|
||||
{
|
||||
\array_unshift($this->stack, [$middleware, $name]);
|
||||
$this->cached = null;
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ class MessageFormatter implements \YoastSEO_Vendor\GuzzleHttp\MessageFormatterIn
|
||||
* @param ResponseInterface|null $response Response that was received
|
||||
* @param \Throwable|null $error Exception that was received
|
||||
*/
|
||||
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : string
|
||||
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : string
|
||||
{
|
||||
$cache = [];
|
||||
/** @var string */
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@ interface MessageFormatterInterface
|
||||
* @param ResponseInterface|null $response Response that was received
|
||||
* @param \Throwable|null $error Exception that was received
|
||||
*/
|
||||
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, \Throwable $error = null) : string;
|
||||
public function format(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?\Throwable $error = null) : string;
|
||||
}
|
||||
|
||||
+5
-5
@@ -48,7 +48,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable(callable): callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function httpErrors(\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : callable
|
||||
public static function httpErrors(?\YoastSEO_Vendor\GuzzleHttp\BodySummarizerInterface $bodySummarizer = null) : callable
|
||||
{
|
||||
return static function (callable $handler) use($bodySummarizer) : callable {
|
||||
return static function ($request, array $options) use($handler, $bodySummarizer) {
|
||||
@@ -104,7 +104,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function tap(callable $before = null, callable $after = null) : callable
|
||||
public static function tap(?callable $before = null, ?callable $after = null) : callable
|
||||
{
|
||||
return static function (callable $handler) use($before, $after) : callable {
|
||||
return static function (\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options) use($handler, $before, $after) {
|
||||
@@ -145,7 +145,7 @@ final class Middleware
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function retry(callable $decider, callable $delay = null) : callable
|
||||
public static function retry(callable $decider, ?callable $delay = null) : callable
|
||||
{
|
||||
return static function (callable $handler) use($decider, $delay) : RetryMiddleware {
|
||||
return new \YoastSEO_Vendor\GuzzleHttp\RetryMiddleware($decider, $handler, $delay);
|
||||
@@ -155,12 +155,12 @@ final class Middleware
|
||||
* Middleware that logs requests, responses, and errors using a message
|
||||
* formatter.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @param LoggerInterface $logger Logs messages.
|
||||
* @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
|
||||
* @param string $logLevel Level at which to log requests.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function log(\YoastSEO_Vendor\Psr\Log\LoggerInterface $logger, $formatter, string $logLevel = 'info') : callable
|
||||
|
||||
@@ -79,7 +79,7 @@ class Pool implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromisorInterface
|
||||
* @param ClientInterface $client Client used to send the requests
|
||||
* @param array|\Iterator $requests Requests to send concurrently.
|
||||
* @param array $options Passes through the options available in
|
||||
* {@see \GuzzleHttp\Pool::__construct}
|
||||
* {@see Pool::__construct}
|
||||
*
|
||||
* @return array Returns an array containing the response or an exception
|
||||
* in the same order that the requests were sent.
|
||||
|
||||
+2
-2
@@ -62,8 +62,8 @@ class PrepareBodyMiddleware
|
||||
return;
|
||||
}
|
||||
$expect = $options['expect'] ?? null;
|
||||
// Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
|
||||
if ($expect === \false || $request->getProtocolVersion() < 1.1) {
|
||||
// Return if disabled or using HTTP/1.0
|
||||
if ($expect === \false || $request->getProtocolVersion() === '1.0') {
|
||||
return;
|
||||
}
|
||||
// The expect header is unconditionally enabled
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ final class RequestOptions
|
||||
* Specifies whether or not cookies are used in a request or what cookie
|
||||
* jar to use or what cookies to send. This option only works if your
|
||||
* handler has the `cookie` middleware. Valid values are `false` and
|
||||
* an instance of {@see \GuzzleHttp\Cookie\CookieJarInterface}.
|
||||
* an instance of {@see Cookie\CookieJarInterface}.
|
||||
*/
|
||||
public const COOKIES = 'cookies';
|
||||
/**
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ class RetryMiddleware
|
||||
* and returns the number of
|
||||
* milliseconds to delay.
|
||||
*/
|
||||
public function __construct(callable $decider, callable $nextHandler, callable $delay = null)
|
||||
public function __construct(callable $decider, callable $nextHandler, ?callable $delay = null)
|
||||
{
|
||||
$this->decider = $decider;
|
||||
$this->nextHandler = $nextHandler;
|
||||
@@ -83,7 +83,7 @@ class RetryMiddleware
|
||||
return $this->doRetry($req, $options);
|
||||
};
|
||||
}
|
||||
private function doRetry(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
private function doRetry(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
$options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
|
||||
return $this($request, $options);
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ final class TransferStats
|
||||
* @param mixed $handlerErrorData Handler error data.
|
||||
* @param array $handlerStats Handler specific stats.
|
||||
*/
|
||||
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, float $transferTime = null, $handlerErrorData = null, array $handlerStats = [])
|
||||
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, ?\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response = null, ?float $transferTime = null, $handlerErrorData = null, array $handlerStats = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
|
||||
@@ -71,14 +71,14 @@ final class Utils
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*/
|
||||
public static function chooseHandler() : callable
|
||||
{
|
||||
$handler = null;
|
||||
if (\defined('CURLOPT_CUSTOMREQUEST')) {
|
||||
if (\defined('CURLOPT_CUSTOMREQUEST') && \function_exists('curl_version') && \version_compare(\curl_version()['version'], '7.21.2') >= 0) {
|
||||
if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) {
|
||||
$handler = \YoastSEO_Vendor\GuzzleHttp\Handler\Proxy::wrapSync(new \YoastSEO_Vendor\GuzzleHttp\Handler\CurlMultiHandler(), new \YoastSEO_Vendor\GuzzleHttp\Handler\CurlHandler());
|
||||
} elseif (\function_exists('curl_exec')) {
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ function debug_resource($value = null)
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ final class Coroutine implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInte
|
||||
{
|
||||
return new self($generatorFn);
|
||||
}
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
return $this->result->then($onFulfilled, $onRejected);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ final class Each
|
||||
*
|
||||
* @param mixed $iterable Iterator or array to iterate over.
|
||||
*/
|
||||
public static function of($iterable, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public static function of($iterable, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
return (new \YoastSEO_Vendor\GuzzleHttp\Promise\EachPromise($iterable, ['fulfilled' => $onFulfilled, 'rejected' => $onRejected]))->promise();
|
||||
}
|
||||
@@ -35,7 +35,7 @@ final class Each
|
||||
* @param mixed $iterable
|
||||
* @param int|callable $concurrency
|
||||
*/
|
||||
public static function ofLimit($iterable, $concurrency, callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public static function ofLimit($iterable, $concurrency, ?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
return (new \YoastSEO_Vendor\GuzzleHttp\Promise\EachPromise($iterable, ['fulfilled' => $onFulfilled, 'rejected' => $onRejected, 'concurrency' => $concurrency]))->promise();
|
||||
}
|
||||
@@ -47,7 +47,7 @@ final class Each
|
||||
* @param mixed $iterable
|
||||
* @param int|callable $concurrency
|
||||
*/
|
||||
public static function ofLimitAll($iterable, $concurrency, callable $onFulfilled = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public static function ofLimitAll($iterable, $concurrency, ?callable $onFulfilled = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
return self::ofLimit($iterable, $concurrency, $onFulfilled, function ($reason, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $aggregate) : void {
|
||||
$aggregate->reject($reason);
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class FulfilledPromise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInt
|
||||
}
|
||||
$this->value = $value;
|
||||
}
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
// Return itself if there is no onFulfilled function.
|
||||
if (!$onFulfilled) {
|
||||
|
||||
+2
-2
@@ -22,12 +22,12 @@ class Promise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
* @param callable $waitFn Fn that when invoked resolves the promise.
|
||||
* @param callable $cancelFn Fn that when invoked cancels the promise.
|
||||
*/
|
||||
public function __construct(callable $waitFn = null, callable $cancelFn = null)
|
||||
public function __construct(?callable $waitFn = null, ?callable $cancelFn = null)
|
||||
{
|
||||
$this->waitFn = $waitFn;
|
||||
$this->cancelFn = $cancelFn;
|
||||
}
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
if ($this->state === self::PENDING) {
|
||||
$p = new \YoastSEO_Vendor\GuzzleHttp\Promise\Promise(null, [$this, 'cancel']);
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ interface PromiseInterface
|
||||
* @param callable $onFulfilled Invoked when the promise fulfills.
|
||||
* @param callable $onRejected Invoked when the promise is rejected.
|
||||
*/
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
|
||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
|
||||
/**
|
||||
* Appends a rejection handler callback to the promise, and returns a new
|
||||
* promise resolving to the return value of the callback if it is called,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class RejectedPromise implements \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInte
|
||||
}
|
||||
$this->reason = $reason;
|
||||
}
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface
|
||||
{
|
||||
// If there's no onRejected callback then just return self.
|
||||
if (!$onRejected) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ class RejectionException extends \RuntimeException
|
||||
* @param mixed $reason Rejection reason.
|
||||
* @param string|null $description Optional description.
|
||||
*/
|
||||
public function __construct($reason, string $description = null)
|
||||
public function __construct($reason, ?string $description = null)
|
||||
{
|
||||
$this->reason = $reason;
|
||||
$message = 'The promise was rejected';
|
||||
|
||||
@@ -20,7 +20,7 @@ final class Utils
|
||||
*
|
||||
* @param TaskQueueInterface|null $assign Optionally specify a new queue instance.
|
||||
*/
|
||||
public static function queue(\YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface $assign = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface
|
||||
public static function queue(?\YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface $assign = null) : \YoastSEO_Vendor\GuzzleHttp\Promise\TaskQueueInterface
|
||||
{
|
||||
static $queue;
|
||||
if ($assign) {
|
||||
@@ -127,7 +127,9 @@ final class Utils
|
||||
$promise = \YoastSEO_Vendor\GuzzleHttp\Promise\Each::of($promises, function ($value, $idx) use(&$results) : void {
|
||||
$results[$idx] = $value;
|
||||
}, function ($reason, $idx, \YoastSEO_Vendor\GuzzleHttp\Promise\Promise $aggregate) : void {
|
||||
$aggregate->reject($reason);
|
||||
if (\YoastSEO_Vendor\GuzzleHttp\Promise\Is::pending($aggregate)) {
|
||||
$aggregate->reject($reason);
|
||||
}
|
||||
})->then(function () use(&$results) {
|
||||
\ksort($results);
|
||||
return $results;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ final class CachingStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamInt
|
||||
* @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
|
||||
* @param StreamInterface $target Optionally specify where data is cached
|
||||
*/
|
||||
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, \YoastSEO_Vendor\Psr\Http\Message\StreamInterface $target = null)
|
||||
public function __construct(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $target = null)
|
||||
{
|
||||
$this->remoteStream = $stream;
|
||||
$this->stream = $target ?: new \YoastSEO_Vendor\GuzzleHttp\Psr7\Stream(\YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'r+'));
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
|
||||
*/
|
||||
final class HttpFactory implements \YoastSEO_Vendor\Psr\Http\Message\RequestFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\ResponseFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\ServerRequestFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\StreamFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\UploadedFileFactoryInterface, \YoastSEO_Vendor\Psr\Http\Message\UriFactoryInterface
|
||||
{
|
||||
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
|
||||
public function createUploadedFile(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?int $size = null, int $error = \UPLOAD_ERR_OK, ?string $clientFilename = null, ?string $clientMediaType = null) : \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
|
||||
{
|
||||
if ($size === null) {
|
||||
$size = $stream->getSize();
|
||||
|
||||
@@ -138,9 +138,6 @@ trait MessageTrait
|
||||
if (!\is_array($value)) {
|
||||
return $this->trimAndValidateHeaderValues([$value]);
|
||||
}
|
||||
if (\count($value) === 0) {
|
||||
throw new \InvalidArgumentException('Header value can not be an empty array.');
|
||||
}
|
||||
return $this->trimAndValidateHeaderValues($value);
|
||||
}
|
||||
/**
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ final class MultipartStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamI
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements = [], string $boundary = null)
|
||||
public function __construct(array $elements = [], ?string $boundary = null)
|
||||
{
|
||||
$this->boundary = $boundary ?: \bin2hex(\random_bytes(20));
|
||||
$this->stream = $this->createStream($elements);
|
||||
|
||||
@@ -57,12 +57,15 @@ final class Query
|
||||
* string. This function does not modify the provided keys when an array is
|
||||
* encountered (like `http_build_query()` would).
|
||||
*
|
||||
* @param array $params Query string parameters.
|
||||
* @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
|
||||
* to encode using RFC3986, or PHP_QUERY_RFC1738
|
||||
* to encode using RFC1738.
|
||||
* @param array $params Query string parameters.
|
||||
* @param int|false $encoding Set to false to not encode,
|
||||
* PHP_QUERY_RFC3986 to encode using
|
||||
* RFC3986, or PHP_QUERY_RFC1738 to
|
||||
* encode using RFC1738.
|
||||
* @param bool $treatBoolsAsInts Set to true to encode as 0/1, and
|
||||
* false as false/true.
|
||||
*/
|
||||
public static function build(array $params, $encoding = \PHP_QUERY_RFC3986) : string
|
||||
public static function build(array $params, $encoding = \PHP_QUERY_RFC3986, bool $treatBoolsAsInts = \true) : string
|
||||
{
|
||||
if (!$params) {
|
||||
return '';
|
||||
@@ -78,12 +81,17 @@ final class Query
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid type');
|
||||
}
|
||||
$castBool = $treatBoolsAsInts ? static function ($v) {
|
||||
return (int) $v;
|
||||
} : static function ($v) {
|
||||
return $v ? 'true' : 'false';
|
||||
};
|
||||
$qs = '';
|
||||
foreach ($params as $k => $v) {
|
||||
$k = $encoder((string) $k);
|
||||
if (!\is_array($v)) {
|
||||
$qs .= $k;
|
||||
$v = \is_bool($v) ? (int) $v : $v;
|
||||
$v = \is_bool($v) ? $castBool($v) : $v;
|
||||
if ($v !== null) {
|
||||
$qs .= '=' . $encoder((string) $v);
|
||||
}
|
||||
@@ -91,7 +99,7 @@ final class Query
|
||||
} else {
|
||||
foreach ($v as $vv) {
|
||||
$qs .= $k;
|
||||
$vv = \is_bool($vv) ? (int) $vv : $vv;
|
||||
$vv = \is_bool($vv) ? $castBool($vv) : $vv;
|
||||
if ($vv !== null) {
|
||||
$qs .= '=' . $encoder((string) $vv);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class Response implements \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface
|
||||
* @param string $version Protocol version
|
||||
* @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
|
||||
*/
|
||||
public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', string $reason = null)
|
||||
public function __construct(int $status = 200, array $headers = [], $body = null, string $version = '1.1', ?string $reason = null)
|
||||
{
|
||||
$this->assertStatusCodeRange($status);
|
||||
$this->statusCode = $status;
|
||||
|
||||
+6
-3
@@ -56,7 +56,7 @@ final class StreamWrapper
|
||||
\stream_wrapper_register('guzzle', __CLASS__);
|
||||
}
|
||||
}
|
||||
public function stream_open(string $path, string $mode, int $options, string &$opened_path = null) : bool
|
||||
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null) : bool
|
||||
{
|
||||
$options = \stream_context_get_options($this->context);
|
||||
if (!isset($options['guzzle']['stream'])) {
|
||||
@@ -111,10 +111,13 @@ final class StreamWrapper
|
||||
* ctime: int,
|
||||
* blksize: int,
|
||||
* blocks: int
|
||||
* }
|
||||
* }|false
|
||||
*/
|
||||
public function stream_stat() : array
|
||||
public function stream_stat()
|
||||
{
|
||||
if ($this->stream->getSize() === null) {
|
||||
return \false;
|
||||
}
|
||||
static $modeMap = ['r' => 33060, 'rb' => 33060, 'r+' => 33206, 'w' => 33188, 'wb' => 33188];
|
||||
return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0];
|
||||
}
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ use YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface;
|
||||
use RuntimeException;
|
||||
class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface
|
||||
{
|
||||
private const ERRORS = [\UPLOAD_ERR_OK, \UPLOAD_ERR_INI_SIZE, \UPLOAD_ERR_FORM_SIZE, \UPLOAD_ERR_PARTIAL, \UPLOAD_ERR_NO_FILE, \UPLOAD_ERR_NO_TMP_DIR, \UPLOAD_ERR_CANT_WRITE, \UPLOAD_ERR_EXTENSION];
|
||||
private const ERROR_MAP = [\UPLOAD_ERR_OK => 'UPLOAD_ERR_OK', \UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE', \UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE', \UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL', \UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE', \UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR', \UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE', \UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION'];
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
@@ -41,7 +41,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
|
||||
/**
|
||||
* @param StreamInterface|string|resource $streamOrFile
|
||||
*/
|
||||
public function __construct($streamOrFile, ?int $size, int $errorStatus, string $clientFilename = null, string $clientMediaType = null)
|
||||
public function __construct($streamOrFile, ?int $size, int $errorStatus, ?string $clientFilename = null, ?string $clientMediaType = null)
|
||||
{
|
||||
$this->setError($errorStatus);
|
||||
$this->size = $size;
|
||||
@@ -75,7 +75,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
|
||||
*/
|
||||
private function setError(int $error) : void
|
||||
{
|
||||
if (\false === \in_array($error, \YoastSEO_Vendor\GuzzleHttp\Psr7\UploadedFile::ERRORS, \true)) {
|
||||
if (!isset(\YoastSEO_Vendor\GuzzleHttp\Psr7\UploadedFile::ERROR_MAP[$error])) {
|
||||
throw new \InvalidArgumentException('Invalid error status for UploadedFile');
|
||||
}
|
||||
$this->error = $error;
|
||||
@@ -101,7 +101,7 @@ class UploadedFile implements \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInte
|
||||
private function validateActive() : void
|
||||
{
|
||||
if (\false === $this->isOk()) {
|
||||
throw new \RuntimeException('Cannot retrieve stream due to upload error');
|
||||
throw new \RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error]));
|
||||
}
|
||||
if ($this->isMoved()) {
|
||||
throw new \RuntimeException('Cannot retrieve stream after it has already been moved');
|
||||
|
||||
@@ -80,7 +80,7 @@ class Uri implements \YoastSEO_Vendor\Psr\Http\Message\UriInterface, \JsonSerial
|
||||
{
|
||||
// If IPv6
|
||||
$prefix = '';
|
||||
if (\preg_match('%^(.*://\\[[0-9:a-f]+\\])(.*?)$%', $url, $matches)) {
|
||||
if (\preg_match('%^(.*://\\[[0-9:a-fA-F]+\\])(.*?)$%', $url, $matches)) {
|
||||
/** @var array{0:string, 1:string, 2:string} $matches */
|
||||
$prefix = $matches[1];
|
||||
$url = $matches[2];
|
||||
@@ -216,7 +216,7 @@ class Uri implements \YoastSEO_Vendor\Psr\Http\Message\UriInterface, \JsonSerial
|
||||
*
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
|
||||
*/
|
||||
public static function isSameDocumentReference(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri, \YoastSEO_Vendor\Psr\Http\Message\UriInterface $base = null) : bool
|
||||
public static function isSameDocumentReference(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri, ?\YoastSEO_Vendor\Psr\Http\Message\UriInterface $base = null) : bool
|
||||
{
|
||||
if ($base !== null) {
|
||||
$uri = \YoastSEO_Vendor\GuzzleHttp\Psr7\UriResolver::resolve($base, $uri);
|
||||
|
||||
@@ -185,7 +185,7 @@ final class Utils
|
||||
* @param StreamInterface $stream Stream to read from
|
||||
* @param int|null $maxLength Maximum buffer length
|
||||
*/
|
||||
public static function readLine(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, int $maxLength = null) : string
|
||||
public static function readLine(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream, ?int $maxLength = null) : string
|
||||
{
|
||||
$buffer = '';
|
||||
$size = 0;
|
||||
@@ -201,6 +201,17 @@ final class Utils
|
||||
}
|
||||
return $buffer;
|
||||
}
|
||||
/**
|
||||
* Redact the password in the user info part of a URI.
|
||||
*/
|
||||
public static function redactUserInfo(\YoastSEO_Vendor\Psr\Http\Message\UriInterface $uri) : \YoastSEO_Vendor\Psr\Http\Message\UriInterface
|
||||
{
|
||||
$userInfo = $uri->getUserInfo();
|
||||
if (\false !== ($pos = \strpos($userInfo, ':'))) {
|
||||
return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
/**
|
||||
* Create a new stream based on the input type.
|
||||
*
|
||||
@@ -312,7 +323,7 @@ final class Utils
|
||||
}
|
||||
\restore_error_handler();
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
return $handle;
|
||||
@@ -346,7 +357,7 @@ final class Utils
|
||||
}
|
||||
\restore_error_handler();
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
return $contents;
|
||||
|
||||
Reference in New Issue
Block a user