提交的内容

This commit is contained in:
2025-05-12 15:45:02 +08:00
parent 629c4750da
commit b48c692775
3043 changed files with 34732 additions and 60810 deletions

67
vendor/guzzlehttp/guzzle/CHANGELOG.md vendored Executable file → Normal file
View File

@ -3,6 +3,68 @@
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
## 7.9.3 - 2025-03-27
### Changed
- Remove explicit content-length header for GET requests
- Improve compatibility with bad servers for boolean cookie values
## 7.9.2 - 2024-07-24
### Fixed
- Adjusted handler selection to use cURL if its version is 7.21.2 or higher, rather than 7.34.0
## 7.9.1 - 2024-07-19
### Fixed
- Fix TLS 1.3 check for HTTP/2 requests
## 7.9.0 - 2024-07-18
### Changed
- Improve protocol version checks to provide feedback around unsupported protocols
- Only select the cURL handler by default if 7.34.0 or higher is linked
- Improved `CurlMultiHandler` to avoid busy wait if possible
- Dropped support for EOL `guzzlehttp/psr7` v1
- Improved URI user info redaction in errors
## 7.8.2 - 2024-07-18
### Added
- Support for PHP 8.4
## 7.8.1 - 2023-12-03
### Changed
- Updated links in docs to their canonical versions
- Replaced `call_user_func*` with native calls
## 7.8.0 - 2023-08-27
### Added
- Support for PHP 8.3
- Added automatic closing of handles on `CurlFactory` object destruction
## 7.7.1 - 2023-08-27
### Changed
- Remove the need for `AllowDynamicProperties` in `CurlMultiHandler`
## 7.7.0 - 2023-05-21
### Added
@ -628,7 +690,8 @@ object).
* Note: This has been changed in 5.0.3 to now encode query string values by
default unless the `rawString` argument is provided when setting the query
string on a URL: Now allowing many more characters to be present in the
query string without being percent encoded. See https://tools.ietf.org/html/rfc3986#appendix-A
query string without being percent encoded. See
https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
## 5.0.1 - 2014-10-16
@ -1167,7 +1230,7 @@ interfaces.
## 3.4.0 - 2013-04-11
* Bug fix: URLs are now resolved correctly based on https://tools.ietf.org/html/rfc3986#section-5.2. #289
* Bug fix: URLs are now resolved correctly based on https://datatracker.ietf.org/doc/html/rfc3986#section-5.2. #289
* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.

0
vendor/guzzlehttp/guzzle/LICENSE vendored Executable file → Normal file
View File

12
vendor/guzzlehttp/guzzle/README.md vendored Executable file → Normal file
View File

@ -3,7 +3,7 @@
# Guzzle, PHP HTTP client
[![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases)
[![Build Status](https://img.shields.io/github/workflow/status/guzzle/guzzle/CI?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI)
[![Build Status](https://img.shields.io/github/actions/workflow/status/guzzle/guzzle/ci.yml?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI)
[![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle)
Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
@ -62,11 +62,11 @@ composer require guzzlehttp/guzzle
| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version |
|---------|---------------------|---------------------|--------------|---------------------|---------------------|-------|--------------|
| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 |
| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 |
| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 |
| 6.x | Security fixes only | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 |
| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.3 |
| 3.x | EOL (2016-10-31) | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 |
| 4.x | EOL (2016-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 |
| 5.x | EOL (2019-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 |
| 6.x | EOL (2023-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 |
| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.5 |
[guzzle-3-repo]: https://github.com/guzzle/guzzle3
[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x

16
vendor/guzzlehttp/guzzle/UPGRADING.md vendored Executable file → Normal file
View File

@ -27,7 +27,7 @@ Please make sure:
- Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed.
Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative.
- Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed.
- Request option `exception` is removed. Please use `http_errors`.
- Request option `exceptions` is removed. Please use `http_errors`.
- Request option `save_to` is removed. Please use `sink`.
- Pool option `pool_size` is removed. Please use `concurrency`.
- We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility.
@ -189,11 +189,11 @@ $client = new GuzzleHttp\Client(['handler' => $handler]);
## POST Requests
This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params)
This version added the [`form_params`](https://docs.guzzlephp.org/en/latest/request-options.html#form_params)
and `multipart` request options. `form_params` is an associative array of
strings or array of strings and is used to serialize an
`application/x-www-form-urlencoded` POST request. The
[`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart)
[`multipart`](https://docs.guzzlephp.org/en/latest/request-options.html#multipart)
option is now used to send a multipart/form-data POST request.
`GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
@ -209,7 +209,7 @@ The `base_url` option has been renamed to `base_uri`.
## Rewritten Adapter Layer
Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send
Guzzle now uses [RingPHP](https://ringphp.readthedocs.org/en/latest) to send
HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
is still supported, but it has now been renamed to `handler`. Instead of
passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
@ -575,7 +575,7 @@ You can intercept a request and inject a response using the `intercept()` event
of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
`GuzzleHttp\Event\ErrorEvent` event.
See: http://docs.guzzlephp.org/en/latest/events.html
See: https://docs.guzzlephp.org/en/latest/events.html
## Inflection
@ -668,9 +668,9 @@ in separate repositories:
The service description layer of Guzzle has moved into two separate packages:
- http://github.com/guzzle/command Provides a high level abstraction over web
- https://github.com/guzzle/command Provides a high level abstraction over web
services by representing web service operations using commands.
- http://github.com/guzzle/guzzle-services Provides an implementation of
- https://github.com/guzzle/guzzle-services Provides an implementation of
guzzle/command that provides request serialization and response parsing using
Guzzle service descriptions.
@ -870,7 +870,7 @@ HeaderInterface (e.g. toArray(), getAll(), etc.).
3.3 to 3.4
----------
Base URLs of a client now follow the rules of https://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
Base URLs of a client now follow the rules of https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 when merging URLs.
3.2 to 3.3
----------

38
vendor/guzzlehttp/guzzle/composer.json vendored Executable file → Normal file
View File

@ -50,11 +50,39 @@
"homepage": "https://github.com/Tobion"
}
],
"repositories": [
{
"type": "package",
"package": {
"name": "guzzle/client-integration-tests",
"version": "v3.0.2",
"dist": {
"url": "https://codeload.github.com/guzzle/client-integration-tests/zip/2c025848417c1135031fdf9c728ee53d0a7ceaee",
"type": "zip"
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.11",
"php-http/message": "^1.0 || ^2.0",
"guzzlehttp/psr7": "^1.7 || ^2.0",
"th3n3rd/cartesian-product": "^0.3"
},
"autoload": {
"psr-4": {
"Http\\Client\\Tests\\": "src/"
}
},
"bin": [
"bin/http_test_server"
]
}
}
],
"require": {
"php": "^7.2.5 || ^8.0",
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0",
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
@ -63,10 +91,10 @@
},
"require-dev": {
"ext-curl": "*",
"bamarni/composer-bin-plugin": "^1.8.1",
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
"bamarni/composer-bin-plugin": "^1.8.2",
"guzzle/client-integration-tests": "3.0.2",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.29 || ^9.5.23",
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {

6
vendor/guzzlehttp/guzzle/src/BodySummarizer.php vendored Executable file → Normal file
View File

@ -11,7 +11,7 @@ final class BodySummarizer implements BodySummarizerInterface
*/
private $truncateAt;
public function __construct(int $truncateAt = null)
public function __construct(?int $truncateAt = null)
{
$this->truncateAt = $truncateAt;
}
@ -22,7 +22,7 @@ final class BodySummarizer implements BodySummarizerInterface
public function summarize(MessageInterface $message): ?string
{
return $this->truncateAt === null
? \GuzzleHttp\Psr7\Message::bodySummary($message)
: \GuzzleHttp\Psr7\Message::bodySummary($message, $this->truncateAt);
? Psr7\Message::bodySummary($message)
: Psr7\Message::bodySummary($message, $this->truncateAt);
}
}

0
vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php vendored Executable file → Normal file
View File

2
vendor/guzzlehttp/guzzle/src/Client.php vendored Executable file → Normal file
View File

@ -52,7 +52,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
*
* @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 = [])
{

0
vendor/guzzlehttp/guzzle/src/ClientInterface.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/ClientTrait.php vendored Executable file → Normal file
View File

38
vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php vendored Executable file → Normal file
View File

@ -96,9 +96,6 @@ class CookieJar implements CookieJarInterface
return null;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return \array_map(static function (SetCookie $cookie): array {
@ -106,9 +103,6 @@ class CookieJar implements CookieJarInterface
}, $this->getIterator()->getArrayCopy());
}
/**
* {@inheritDoc}
*/
public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void
{
if (!$domain) {
@ -126,25 +120,22 @@ class CookieJar implements CookieJarInterface
$this->cookies = \array_filter(
$this->cookies,
static function (SetCookie $cookie) use ($path, $domain): bool {
return !($cookie->matchesPath($path) &&
$cookie->matchesDomain($domain));
return !($cookie->matchesPath($path)
&& $cookie->matchesDomain($domain));
}
);
} else {
$this->cookies = \array_filter(
$this->cookies,
static function (SetCookie $cookie) use ($path, $domain, $name) {
return !($cookie->getName() == $name &&
$cookie->matchesPath($path) &&
$cookie->matchesDomain($domain));
return !($cookie->getName() == $name
&& $cookie->matchesPath($path)
&& $cookie->matchesDomain($domain));
}
);
}
}
/**
* {@inheritDoc}
*/
public function clearSessionCookies(): void
{
$this->cookies = \array_filter(
@ -155,9 +146,6 @@ class CookieJar implements CookieJarInterface
);
}
/**
* {@inheritDoc}
*/
public function setCookie(SetCookie $cookie): bool
{
// If the name string is empty (but not 0), ignore the set-cookie
@ -182,9 +170,9 @@ class CookieJar implements CookieJarInterface
foreach ($this->cookies as $i => $c) {
// Two cookies are identical, when their path, and domain are
// identical.
if ($c->getPath() != $cookie->getPath() ||
$c->getDomain() != $cookie->getDomain() ||
$c->getName() != $cookie->getName()
if ($c->getPath() != $cookie->getPath()
|| $c->getDomain() != $cookie->getDomain()
|| $c->getName() != $cookie->getName()
) {
continue;
}
@ -255,7 +243,7 @@ class CookieJar implements CookieJarInterface
/**
* Computes cookie path following RFC 6265 section 5.1.4
*
* @see https://tools.ietf.org/html/rfc6265#section-5.1.4
* @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
*/
private function getCookiePathFromRequest(RequestInterface $request): string
{
@ -286,10 +274,10 @@ class CookieJar implements CookieJarInterface
$path = $uri->getPath() ?: '/';
foreach ($this->cookies as $cookie) {
if ($cookie->matchesPath($path) &&
$cookie->matchesDomain($host) &&
!$cookie->isExpired() &&
(!$cookie->getSecure() || $scheme === 'https')
if ($cookie->matchesPath($path)
&& $cookie->matchesDomain($host)
&& !$cookie->isExpired()
&& (!$cookie->getSecure() || $scheme === 'https')
) {
$values[] = $cookie->getName().'='
.$cookie->getValue();

1
vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php vendored Executable file → Normal file
View File

@ -14,6 +14,7 @@ use Psr\Http\Message\ResponseInterface;
* cookies from a file, database, etc.
*
* @see https://docs.python.org/2/library/cookielib.html Inspiration
*
* @extends \IteratorAggregate<SetCookie>
*/
interface CookieJarInterface extends \Countable, \IteratorAggregate

0
vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php vendored Executable file → Normal file
View File

8
vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php vendored Executable file → Normal file
View File

@ -62,6 +62,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;
}
@ -420,7 +424,7 @@ class SetCookie
}
// Remove the leading '.' as per spec in RFC 6265.
// https://tools.ietf.org/html/rfc6265#section-5.2.3
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
$cookieDomain = \ltrim(\strtolower($cookieDomain), '.');
$domain = \strtolower($domain);
@ -431,7 +435,7 @@ class SetCookie
}
// Matching the subdomain according to RFC 6265.
// https://tools.ietf.org/html/rfc6265#section-5.1.3
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3
if (\filter_var($domain, \FILTER_VALIDATE_IP)) {
return false;
}

2
vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php vendored Executable file → Normal file
View File

@ -14,7 +14,7 @@ class BadResponseException extends RequestException
string $message,
RequestInterface $request,
ResponseInterface $response,
\Throwable $previous = null,
?\Throwable $previous = null,
array $handlerContext = []
) {
parent::__construct($message, $request, $response, $previous, $handlerContext);

0
vendor/guzzlehttp/guzzle/src/Exception/ClientException.php vendored Executable file → Normal file
View File

2
vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php vendored Executable file → Normal file
View File

@ -25,7 +25,7 @@ class ConnectException extends TransferException implements NetworkExceptionInte
public function __construct(
string $message,
RequestInterface $request,
\Throwable $previous = null,
?\Throwable $previous = null,
array $handlerContext = []
) {
parent::__construct($message, 0, $previous);

0
vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php vendored Executable file → Normal file
View File

28
vendor/guzzlehttp/guzzle/src/Exception/RequestException.php vendored Executable file → Normal file
View File

@ -7,7 +7,6 @@ use GuzzleHttp\BodySummarizerInterface;
use Psr\Http\Client\RequestExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
/**
* HTTP Request exception
@ -32,8 +31,8 @@ class RequestException extends TransferException implements RequestExceptionInte
public function __construct(
string $message,
RequestInterface $request,
ResponseInterface $response = null,
\Throwable $previous = null,
?ResponseInterface $response = null,
?\Throwable $previous = null,
array $handlerContext = []
) {
// Set the code of the exception if the response is set and not future.
@ -63,10 +62,10 @@ class RequestException extends TransferException implements RequestExceptionInte
*/
public static function create(
RequestInterface $request,
ResponseInterface $response = null,
\Throwable $previous = null,
?ResponseInterface $response = null,
?\Throwable $previous = null,
array $handlerContext = [],
BodySummarizerInterface $bodySummarizer = null
?BodySummarizerInterface $bodySummarizer = null
): self {
if (!$response) {
return new self(
@ -90,8 +89,7 @@ class RequestException extends TransferException implements RequestExceptionInte
$className = __CLASS__;
}
$uri = $request->getUri();
$uri = static::obfuscateUri($uri);
$uri = \GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
// Client Error: `GET /` resulted in a `404 Not Found` response:
// <html> ... (truncated)
@ -113,20 +111,6 @@ class RequestException extends TransferException implements RequestExceptionInte
return new $className($message, $request, $response, $previous, $handlerContext);
}
/**
* Obfuscates URI if there is a username and a password present
*/
private static function obfuscateUri(UriInterface $uri): 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
*/

0
vendor/guzzlehttp/guzzle/src/Exception/ServerException.php vendored Executable file → Normal file
View File

View File

0
vendor/guzzlehttp/guzzle/src/Exception/TransferException.php vendored Executable file → Normal file
View File

154
vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php vendored Executable file → Normal file
View File

@ -11,6 +11,7 @@ use GuzzleHttp\Psr7\LazyOpenStream;
use GuzzleHttp\TransferStats;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
/**
* Creates curl resources from a request
@ -46,6 +47,16 @@ class CurlFactory implements CurlFactoryInterface
public function create(RequestInterface $request, array $options): EasyHandle
{
$protocolVersion = $request->getProtocolVersion();
if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
if (!self::supportsHttp2()) {
throw new 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 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']);
@ -72,6 +83,42 @@ class CurlFactory implements CurlFactoryInterface
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(EasyHandle $easy): void
{
$resource = $easy->handle;
@ -147,7 +194,7 @@ class CurlFactory implements CurlFactoryInterface
'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.
@ -158,6 +205,17 @@ class CurlFactory implements CurlFactoryInterface
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(EasyHandle $easy, array $ctx): PromiseInterface
{
static $connectionErrors = [
@ -194,15 +252,22 @@ class CurlFactory implements CurlFactoryInterface
);
}
$uri = $easy->request->getUri();
$sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
$message = \sprintf(
'cURL error %s: %s (%s)',
$ctx['errno'],
$ctx['error'],
$sanitizedError,
'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);
if ('' !== $sanitizedError) {
$redactedUriString = \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.
@ -213,6 +278,24 @@ class CurlFactory implements CurlFactoryInterface
return P\Create::rejectionFor($error);
}
private static function sanitizeCurlError(string $error, UriInterface $uri): string
{
if ('' === $error) {
return $error;
}
$baseUri = $uri->withQuery('')->withFragment('');
$baseUriString = $baseUri->__toString();
if ('' === $baseUriString) {
return $error;
}
$redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
return str_replace($baseUriString, $redactedUriString, $error);
}
/**
* @return array<int|string, mixed>
*/
@ -232,10 +315,11 @@ class CurlFactory implements CurlFactoryInterface
}
$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;
}
@ -256,7 +340,7 @@ class CurlFactory implements CurlFactoryInterface
$method = $easy->request->getMethod();
if ($method === 'PUT' || $method === 'POST') {
// See https://tools.ietf.org/html/rfc7230#section-3.3.2
// See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
if (!$easy->request->hasHeader('Content-Length')) {
$conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
}
@ -367,11 +451,11 @@ class CurlFactory implements CurlFactoryInterface
// If it's a directory or a link to a directory use CURLOPT_CAPATH.
// If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
if (
\is_dir($options['verify']) ||
(
\is_link($options['verify']) === true &&
($verifyLink = \readlink($options['verify'])) !== false &&
\is_dir($verifyLink)
\is_dir($options['verify'])
|| (
\is_link($options['verify']) === true
&& ($verifyLink = \readlink($options['verify'])) !== false
&& \is_dir($verifyLink)
)
) {
$conf[\CURLOPT_CAPATH] = $options['verify'];
@ -390,8 +474,10 @@ class CurlFactory implements CurlFactoryInterface
// 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:';
}
}
@ -455,23 +541,35 @@ class CurlFactory implements CurlFactoryInterface
}
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;
@ -627,4 +725,12 @@ class CurlFactory implements CurlFactoryInterface
return \strlen($h);
};
}
public function __destruct()
{
foreach ($this->handles as $id => $handle) {
\curl_close($handle);
unset($this->handles[$id]);
}
}
}

0
vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php vendored Executable file → Normal file
View File

27
vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php vendored Executable file → Normal file
View File

@ -2,6 +2,7 @@
namespace GuzzleHttp\Handler;
use Closure;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\PromiseInterface;
@ -15,11 +16,8 @@ use Psr\Http\Message\RequestInterface;
* associative array of curl option constants mapping to values in the
* **curl** key of the provided request options.
*
* @property resource|\CurlMultiHandle $_mh Internal use only. Lazy loaded multi-handle.
*
* @final
*/
#[\AllowDynamicProperties]
class CurlMultiHandler
{
/**
@ -56,6 +54,9 @@ class CurlMultiHandler
*/
private $options = [];
/** @var resource|\CurlMultiHandle */
private $_mh;
/**
* This handler accepts the following options:
*
@ -79,6 +80,10 @@ class CurlMultiHandler
}
$this->options = $options['options'] ?? [];
// unsetting the property forces the first access to go through
// __get().
unset($this->_mh);
}
/**
@ -155,6 +160,9 @@ class CurlMultiHandler
}
}
// Run curl_multi_exec in the queue to enable other async tasks to run
P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
// Step through the task queue which may add additional requests.
P\Utils::queue()->run();
@ -165,11 +173,24 @@ class CurlMultiHandler
}
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);
P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
}
}
/**
* Runs until all outstanding connections have completed.
*/

0
vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php vendored Executable file → Normal file
View File

8
vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php vendored Executable file → Normal file
View File

@ -52,21 +52,21 @@ 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): HandlerStack
public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null): HandlerStack
{
return 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;
@ -200,7 +200,7 @@ class MockHandler implements \Countable
private function invokeStats(
RequestInterface $request,
array $options,
ResponseInterface $response = null,
?ResponseInterface $response = null,
$reason = null
): void {
if (isset($options['on_stats'])) {

12
vendor/guzzlehttp/guzzle/src/Handler/Proxy.php vendored Executable file → Normal file
View File

@ -17,10 +17,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
{
@ -37,10 +37,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
{

22
vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php vendored Executable file → Normal file
View File

@ -40,6 +40,12 @@ class StreamHandler
\usleep($options['delay'] * 1000);
}
$protocolVersion = $request->getProtocolVersion();
if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
throw new ConnectException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
}
$startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
try {
@ -47,8 +53,14 @@ class StreamHandler
$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');
}
@ -83,8 +95,8 @@ class StreamHandler
array $options,
RequestInterface $request,
?float $startTime,
ResponseInterface $response = null,
\Throwable $error = null
?ResponseInterface $response = null,
?\Throwable $error = null
): void {
if (isset($options['on_stats'])) {
$stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []);
@ -273,7 +285,7 @@ class StreamHandler
// HTTP/1.1 streams using the PHP stream wrapper require a
// Connection: close header
if ($request->getProtocolVersion() == '1.1'
if ($request->getProtocolVersion() === '1.1'
&& !$request->hasHeader('Connection')
) {
$request = $request->withHeader('Connection', 'close');

2
vendor/guzzlehttp/guzzle/src/HandlerStack.php vendored Executable file → Normal file
View File

@ -58,7 +58,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;
}

0
vendor/guzzlehttp/guzzle/src/MessageFormatter.php vendored Executable file → Normal file
View File

0
vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php vendored Executable file → Normal file
View File

6
vendor/guzzlehttp/guzzle/src/Middleware.php vendored Executable file → Normal file
View File

@ -55,7 +55,7 @@ final class Middleware
*
* @return callable(callable): callable Returns a function that accepts the next handler.
*/
public static function httpErrors(BodySummarizerInterface $bodySummarizer = null): callable
public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null): callable
{
return static function (callable $handler) use ($bodySummarizer): callable {
return static function ($request, array $options) use ($handler, $bodySummarizer) {
@ -132,7 +132,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 (RequestInterface $request, array $options) use ($handler, $before, $after) {
@ -176,7 +176,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 RetryMiddleware($decider, $handler, $delay);

2
vendor/guzzlehttp/guzzle/src/Pool.php vendored Executable file → Normal file
View File

@ -86,7 +86,7 @@ class Pool implements 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.

4
vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php vendored Executable file → Normal file
View File

@ -76,8 +76,8 @@ class PrepareBodyMiddleware
$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;
}

4
vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php vendored Executable file → Normal file
View File

@ -166,8 +166,8 @@ class RedirectMiddleware
// not forcing RFC compliance, but rather emulating what all browsers
// would do.
$statusCode = $response->getStatusCode();
if ($statusCode == 303 ||
($statusCode <= 302 && !$options['allow_redirects']['strict'])
if ($statusCode == 303
|| ($statusCode <= 302 && !$options['allow_redirects']['strict'])
) {
$safeMethods = ['GET', 'HEAD', 'OPTIONS'];
$requestMethod = $request->getMethod();

6
vendor/guzzlehttp/guzzle/src/RequestOptions.php vendored Executable file → Normal file
View File

@ -5,9 +5,7 @@ namespace GuzzleHttp;
/**
* This class contains a list of built-in Guzzle request options.
*
* More documentation for each option can be found at http://guzzlephp.org/.
*
* @see http://docs.guzzlephp.org/en/v6/request-options.html
* @see https://docs.guzzlephp.org/en/latest/request-options.html
*/
final class RequestOptions
{
@ -63,7 +61,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';

4
vendor/guzzlehttp/guzzle/src/RetryMiddleware.php vendored Executable file → Normal file
View File

@ -40,7 +40,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;
@ -110,7 +110,7 @@ class RetryMiddleware
};
}
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface
private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface
{
$options['delay'] = ($this->delay)(++$options['retries'], $response, $request);

0
vendor/guzzlehttp/guzzle/src/TransferStats.php vendored Executable file → Normal file
View File

21
vendor/guzzlehttp/guzzle/src/Utils.php vendored Executable file → Normal file
View File

@ -71,7 +71,7 @@ final class Utils
return \STDOUT;
}
return \GuzzleHttp\Psr7\Utils::tryFopen('php://output', 'w');
return Psr7\Utils::tryFopen('php://output', 'w');
}
/**
@ -79,7 +79,7 @@ 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.
*/
@ -87,7 +87,7 @@ final class Utils
{
$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 = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
} elseif (\function_exists('curl_exec')) {
@ -176,14 +176,13 @@ No system CA bundle could be found in any of the the common system locations.
PHP versions earlier than 5.6 are not properly configured to use the system's
CA bundle by default. In order to verify peer certificates, you will need to
supply the path on disk to a certificate bundle to the 'verify' request
option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
need a specific certificate bundle, then Mozilla provides a commonly used CA
bundle which can be downloaded here (provided by the maintainer of cURL):
https://curl.haxx.se/ca/cacert.pem. Once
you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
ini setting to point to the path to the file, allowing you to omit the 'verify'
request option. See https://curl.haxx.se/docs/sslcerts.html for more
information.
option: https://docs.guzzlephp.org/en/latest/request-options.html#verify. If
you do not need a specific certificate bundle, then Mozilla provides a commonly
used CA bundle which can be downloaded here (provided by the maintainer of
cURL): https://curl.haxx.se/ca/cacert.pem. Once you have a CA bundle available
on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path
to the file, allowing you to omit the 'verify' request option. See
https://curl.haxx.se/docs/sslcerts.html for more information.
EOT
);
}

2
vendor/guzzlehttp/guzzle/src/functions.php vendored Executable file → Normal file
View File

@ -50,7 +50,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.
*

0
vendor/guzzlehttp/guzzle/src/functions_include.php vendored Executable file → Normal file
View File