| 1 |
<?php |
| 2 |
|
| 3 |
namespace YoastSEO_Vendor\GuzzleHttp\Handler; |
| 4 |
|
| 5 |
/** |
| 6 |
* @internal |
| 7 |
*/ |
| 8 |
final class CurlVersion |
| 9 |
{ |
| 10 |
private const MIN_VERSION = '7.21.2'; |
| 11 |
private const TLS_12_VERSION = '7.34.0'; |
| 12 |
private const TLS_13_VERSION = '7.52.0'; |
| 13 |
// curl 7.52.0 introduced HTTPS proxy support, advertised by a feature bit |
| 14 |
// (a build can meet the version yet lack the feature). Earlier libcurl |
| 15 |
// mishandles an https:// proxy: before 7.50.2 it silently downgrades to a |
| 16 |
// plaintext HTTP proxy, and 7.50.2 through 7.51 reject it at connect time. |
| 17 |
private const HTTPS_PROXY_VERSION = '7.52.0'; |
| 18 |
private const HANDLER_SHARING_VERSION = '7.35.0'; |
| 19 |
private const SSL_SESSION_SHARING_VERSION = '8.6.0'; |
| 20 |
/** |
| 21 |
* @var array{version: string, features: int}|false|null |
| 22 |
*/ |
| 23 |
private static $versionInfo; |
| 24 |
private function __construct() |
| 25 |
{ |
| 26 |
} |
| 27 |
public static function supportsCurlHandler() : bool |
| 28 |
{ |
| 29 |
$version = self::getVersion(); |
| 30 |
return $version !== null && \version_compare($version, self::MIN_VERSION, '>='); |
| 31 |
} |
| 32 |
public static function supportsTls12() : bool |
| 33 |
{ |
| 34 |
$version = self::getVersion(); |
| 35 |
return self::supportsSsl() && \defined('CURL_SSLVERSION_TLSv1_2') && $version !== null && \version_compare($version, self::TLS_12_VERSION, '>='); |
| 36 |
} |
| 37 |
public static function supportsTls13() : bool |
| 38 |
{ |
| 39 |
$version = self::getVersion(); |
| 40 |
return self::supportsSsl() && \defined('CURL_SSLVERSION_TLSv1_3') && $version !== null && \version_compare($version, self::TLS_13_VERSION, '>='); |
| 41 |
} |
| 42 |
public static function supportsHttp2() : bool |
| 43 |
{ |
| 44 |
$versionInfo = self::getVersionInfo(); |
| 45 |
return self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && $versionInfo !== null && 0 !== (\CURL_VERSION_HTTP2 & $versionInfo['features']); |
| 46 |
} |
| 47 |
public static function supportsHttpsProxy() : bool |
| 48 |
{ |
| 49 |
$versionInfo = self::getVersionInfo(); |
| 50 |
// CURL_VERSION_HTTPS_PROXY is not defined on every supported PHP |
| 51 |
// version; fall back to the curl.h bit value. |
| 52 |
$httpsProxyFeature = \defined('CURL_VERSION_HTTPS_PROXY') ? \CURL_VERSION_HTTPS_PROXY : 1 << 21; |
| 53 |
return $versionInfo !== null && \version_compare($versionInfo['version'], self::HTTPS_PROXY_VERSION, '>=') && 0 !== ($httpsProxyFeature & $versionInfo['features']); |
| 54 |
} |
| 55 |
public static function supportsHandlerSharing() : bool |
| 56 |
{ |
| 57 |
$version = self::getVersion(); |
| 58 |
return $version !== null && \version_compare($version, self::HANDLER_SHARING_VERSION, '>='); |
| 59 |
} |
| 60 |
public static function ensureHandlerSharingSupported() : void |
| 61 |
{ |
| 62 |
if (!self::supportsHandlerSharing()) { |
| 63 |
throw new \InvalidArgumentException(\sprintf('The "transport_sharing" option requires libcurl %s or higher for cURL share handles.', self::HANDLER_SHARING_VERSION)); |
| 64 |
} |
| 65 |
} |
| 66 |
public static function supportsSslSessionSharing() : bool |
| 67 |
{ |
| 68 |
$version = self::getVersion(); |
| 69 |
return self::supportsSsl() && $version !== null && \version_compare($version, self::SSL_SESSION_SHARING_VERSION, '>='); |
| 70 |
} |
| 71 |
public static function ensureSslSessionSharingSupported() : void |
| 72 |
{ |
| 73 |
if (!self::supportsSslSessionSharing()) { |
| 74 |
throw new \InvalidArgumentException(\sprintf('The "transport_sharing" option requires libcurl %s or higher with SSL support for SSL session sharing.', self::SSL_SESSION_SHARING_VERSION)); |
| 75 |
} |
| 76 |
} |
| 77 |
private static function supportsSsl() : bool |
| 78 |
{ |
| 79 |
$versionInfo = self::getVersionInfo(); |
| 80 |
return \defined('CURL_VERSION_SSL') && $versionInfo !== null && 0 !== (\CURL_VERSION_SSL & $versionInfo['features']); |
| 81 |
} |
| 82 |
public static function getVersion() : ?string |
| 83 |
{ |
| 84 |
$versionInfo = self::getVersionInfo(); |
| 85 |
return $versionInfo === null ? null : $versionInfo['version']; |
| 86 |
} |
| 87 |
/** |
| 88 |
* @return array{version: string, features: int}|null |
| 89 |
*/ |
| 90 |
private static function getVersionInfo() : ?array |
| 91 |
{ |
| 92 |
if (self::$versionInfo === null) { |
| 93 |
if (!\function_exists('curl_version')) { |
| 94 |
self::$versionInfo = \false; |
| 95 |
} else { |
| 96 |
$versionInfo = \curl_version(); |
| 97 |
self::$versionInfo = \is_array($versionInfo) && isset($versionInfo['version'], $versionInfo['features']) && \is_string($versionInfo['version']) && \is_int($versionInfo['features']) ? ['version' => $versionInfo['version'], 'features' => $versionInfo['features']] : \false; |
| 98 |
} |
| 99 |
} |
| 100 |
return self::$versionInfo === \false ? null : self::$versionInfo; |
| 101 |
} |
| 102 |
} |
| 103 |
|