Aggiornato Composer

This commit is contained in:
Paolo A
2024-05-17 12:24:19 +00:00
parent 4ac62108b5
commit ec201d75b2
2238 changed files with 38684 additions and 59785 deletions

View File

@@ -51,7 +51,7 @@ class CurlFactory implements CurlFactoryInterface
unset($options['curl']['body_as_string']);
}
$easy = new EasyHandle;
$easy = new EasyHandle();
$easy->request = $request;
$easy->options = $options;
$conf = $this->getDefaultConf($easy);
@@ -161,11 +161,11 @@ class CurlFactory implements CurlFactoryInterface
private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
{
static $connectionErrors = [
\CURLE_OPERATION_TIMEOUTED => true,
\CURLE_OPERATION_TIMEOUTED => true,
\CURLE_COULDNT_RESOLVE_HOST => true,
\CURLE_COULDNT_CONNECT => true,
\CURLE_SSL_CONNECT_ERROR => true,
\CURLE_GOT_NOTHING => true,
\CURLE_COULDNT_CONNECT => true,
\CURLE_SSL_CONNECT_ERROR => true,
\CURLE_GOT_NOTHING => true,
];
if ($easy->createResponseException) {
@@ -219,12 +219,12 @@ class CurlFactory implements CurlFactoryInterface
private function getDefaultConf(EasyHandle $easy): array
{
$conf = [
'_headers' => $easy->request->getHeaders(),
\CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
\CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
'_headers' => $easy->request->getHeaders(),
\CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
\CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
\CURLOPT_RETURNTRANSFER => false,
\CURLOPT_HEADER => false,
\CURLOPT_CONNECTTIMEOUT => 150,
\CURLOPT_HEADER => false,
\CURLOPT_CONNECTTIMEOUT => 300,
];
if (\defined('CURLOPT_PROTOCOLS')) {
@@ -250,12 +250,13 @@ class CurlFactory implements CurlFactoryInterface
if ($size === null || $size > 0) {
$this->applyBody($easy->request, $easy->options, $conf);
return;
}
$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';
}
@@ -341,6 +342,7 @@ class CurlFactory implements CurlFactoryInterface
foreach (\array_keys($options['_headers']) as $key) {
if (!\strcasecmp($key, $name)) {
unset($options['_headers'][$key]);
return;
}
}
@@ -365,11 +367,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'];
@@ -443,13 +445,41 @@ class CurlFactory implements CurlFactoryInterface
$scheme = $easy->request->getUri()->getScheme();
if (isset($options['proxy'][$scheme])) {
$host = $easy->request->getUri()->getHost();
if (!isset($options['proxy']['no']) || !Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
unset($conf[\CURLOPT_PROXY]);
} else {
$conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
}
}
}
}
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');
}
$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')) {
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')) {
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');
}
}
if (isset($options['cert'])) {
$cert = $options['cert'];
if (\is_array($cert)) {
@@ -459,8 +489,8 @@ class CurlFactory implements CurlFactoryInterface
if (!\file_exists($cert)) {
throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
}
# OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
# see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
// OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
// see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
$ext = pathinfo($cert, \PATHINFO_EXTENSION);
if (preg_match('#^(der|p12)$#i', $ext)) {
$conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext);
@@ -523,9 +553,10 @@ class CurlFactory implements CurlFactoryInterface
}
} catch (\RuntimeException $e) {
$ctx['error'] = 'The connection unexpectedly failed without '
. 'providing an error. The request would have been retried, '
. 'but attempting to rewind the request body failed. '
. 'Exception: ' . $e;
.'providing an error. The request would have been retried, '
.'but attempting to rewind the request body failed. '
.'Exception: '.$e;
return self::createRejection($easy, $ctx);
}
@@ -534,14 +565,15 @@ class CurlFactory implements CurlFactoryInterface
$easy->options['_curl_retries'] = 1;
} elseif ($easy->options['_curl_retries'] == 2) {
$ctx['error'] = 'The cURL request was retried 3 times '
. 'and did not succeed. The most likely reason for the failure '
. 'is that cURL was unable to rewind the body of the request '
. 'and subsequent retries resulted in the same error. Turn on '
. 'the debug option to see what went wrong. See '
. 'https://bugs.php.net/bug.php?id=47204 for more information.';
.'and did not succeed. The most likely reason for the failure '
.'is that cURL was unable to rewind the body of the request '
.'and subsequent retries resulted in the same error. Turn on '
.'the debug option to see what went wrong. See '
.'https://bugs.php.net/bug.php?id=47204 for more information.';
return self::createRejection($easy, $ctx);
} else {
$easy->options['_curl_retries']++;
++$easy->options['_curl_retries'];
}
return $handler($easy->request, $easy->options);
@@ -571,6 +603,7 @@ class CurlFactory implements CurlFactoryInterface
$easy->createResponse();
} catch (\Exception $e) {
$easy->createResponseException = $e;
return -1;
}
if ($onHeaders !== null) {
@@ -580,6 +613,7 @@ class CurlFactory implements CurlFactoryInterface
// Associate the exception with the handle and trigger
// a curl header write error by returning 0.
$easy->onHeadersException = $e;
return -1;
}
}
@@ -589,7 +623,16 @@ class CurlFactory implements CurlFactoryInterface
} else {
$easy->headers[] = $value;
}
return \strlen($h);
};
}
public function __destruct()
{
foreach ($this->handles as $id => $handle) {
\curl_close($handle);
unset($this->handles[$id]);
}
}
}

View File

@@ -15,8 +15,6 @@ 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
*/
class CurlMultiHandler
@@ -55,6 +53,9 @@ class CurlMultiHandler
*/
private $options = [];
/** @var resource|\CurlMultiHandle */
private $_mh;
/**
* This handler accepts the following options:
*
@@ -78,6 +79,10 @@ class CurlMultiHandler
}
$this->options = $options['options'] ?? [];
// unsetting the property forces the first access to go through
// __get().
unset($this->_mh);
}
/**
@@ -163,7 +168,8 @@ class CurlMultiHandler
\usleep(250);
}
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM);
while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
}
$this->processMessages();
}

View File

@@ -106,7 +106,7 @@ final class EasyHandle
*/
public function __get($name)
{
$msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: ' . $name;
$msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: '.$name;
throw new \BadMethodCallException($msg);
}
}

View File

@@ -14,9 +14,9 @@ final class HeaderProcessor
*
* @param string[] $headers
*
* @throws \RuntimeException
*
* @return array{0:string, 1:int, 2:?string, 3:array}
*
* @throws \RuntimeException
*/
public static function parseHeaders(array $headers): array
{

View File

@@ -138,6 +138,7 @@ class MockHandler implements \Countable
if ($this->onRejected) {
($this->onRejected)($reason);
}
return P\Create::rejectionFor($reason);
}
);
@@ -159,7 +160,7 @@ class MockHandler implements \Countable
) {
$this->queue[] = $value;
} else {
throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found ' . Utils::describeType($value));
throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found '.Utils::describeType($value));
}
}
}

View File

@@ -67,7 +67,7 @@ class StreamHandler
if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed
|| false !== \strpos($message, 'Connection refused')
|| false !== \strpos($message, "couldn't connect to host") // error on HHVM
|| false !== \strpos($message, "connection attempt failed")
|| false !== \strpos($message, 'connection attempt failed')
) {
$e = new ConnectException($e->getMessage(), $request, $e);
} else {
@@ -231,9 +231,10 @@ class StreamHandler
\set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool {
$errors[] = [
'message' => $msg,
'file' => $file,
'line' => $line
'file' => $file,
'line' => $line,
];
return true;
});
@@ -247,7 +248,7 @@ class StreamHandler
$message = 'Error creating resource: ';
foreach ($errors as $err) {
foreach ($err as $key => $value) {
$message .= "[$key] $value" . \PHP_EOL;
$message .= "[$key] $value".\PHP_EOL;
}
}
throw new \RuntimeException(\trim($message));
@@ -350,6 +351,7 @@ class StreamHandler
if (false === $records || !isset($records[0]['ip'])) {
throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
}
return $uri->withHost($records[0]['ip']);
}
if ('v6' === $options['force_ip_resolve']) {
@@ -357,7 +359,8 @@ class StreamHandler
if (false === $records || !isset($records[0]['ipv6'])) {
throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
}
return $uri->withHost('[' . $records[0]['ipv6'] . ']');
return $uri->withHost('['.$records[0]['ipv6'].']');
}
}
@@ -375,11 +378,11 @@ class StreamHandler
$context = [
'http' => [
'method' => $request->getMethod(),
'header' => $headers,
'method' => $request->getMethod(),
'header' => $headers,
'protocol_version' => $request->getProtocolVersion(),
'ignore_errors' => true,
'follow_location' => 0,
'ignore_errors' => true,
'follow_location' => 0,
],
'ssl' => [
'peer_name' => $request->getUri()->getHost(),
@@ -388,7 +391,7 @@ class StreamHandler
$body = (string) $request->getBody();
if (!empty($body)) {
if ('' !== $body) {
$context['http']['content'] = $body;
// Prevent the HTTP handler from adding a Content-Type header.
if (!$request->hasHeader('Content-Type')) {
@@ -472,6 +475,25 @@ class StreamHandler
}
}
/**
* @param mixed $value as passed via Request transfer options.
*/
private function add_crypto_method(RequestInterface $request, array &$options, $value, array &$params): void
{
if (
$value === \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
|| $value === \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
|| $value === \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
|| (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && $value === \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT)
) {
$options['http']['crypto_method'] = $value;
return;
}
throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
}
/**
* @param mixed $value as passed via Request transfer options.
*/
@@ -542,27 +564,27 @@ class StreamHandler
}
static $map = [
\STREAM_NOTIFY_CONNECT => 'CONNECT',
\STREAM_NOTIFY_CONNECT => 'CONNECT',
\STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
\STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
\STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
\STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
\STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
\STREAM_NOTIFY_PROGRESS => 'PROGRESS',
\STREAM_NOTIFY_FAILURE => 'FAILURE',
\STREAM_NOTIFY_COMPLETED => 'COMPLETED',
\STREAM_NOTIFY_RESOLVE => 'RESOLVE',
\STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
\STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
\STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
\STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
\STREAM_NOTIFY_PROGRESS => 'PROGRESS',
\STREAM_NOTIFY_FAILURE => 'FAILURE',
\STREAM_NOTIFY_COMPLETED => 'COMPLETED',
\STREAM_NOTIFY_RESOLVE => 'RESOLVE',
];
static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max'];
$value = Utils::debugResource($value);
$ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
$ident = $request->getMethod().' '.$request->getUri()->withFragment('');
self::addNotification(
$params,
static function (int $code, ...$passed) use ($ident, $value, $map, $args): void {
\fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
foreach (\array_filter($passed) as $i => $v) {
\fwrite($value, $args[$i] . ': "' . $v . '" ');
\fwrite($value, $args[$i].': "'.$v.'" ');
}
\fwrite($value, "\n");
}
@@ -577,7 +599,7 @@ class StreamHandler
} else {
$params['notification'] = self::callArray([
$params['notification'],
$notify
$notify,
]);
}
}