Aggiornato Composer
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user