PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / vendor_prefixed / guzzlehttp / guzzle / src / Handler / CurlShareHandleState.php

CurlShareHandleState.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlShareHandleState.php

141 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace YoastSEO_Vendor\GuzzleHttp\Handler;
4
5 use YoastSEO_Vendor\GuzzleHttp\TransportSharing;
6 /**
7 * @internal
8 */
9 final class CurlShareHandleState
10 {
11 /**
12 * @var resource|\CurlShareHandle|null
13 */
14 public $handle;
15 /**
16 * @var string
17 */
18 public $mode;
19 /**
20 * @param resource|\CurlShareHandle|null $handle
21 */
22 private function __construct(string $mode, $handle)
23 {
24 $this->mode = $mode;
25 $this->handle = $handle;
26 }
27 /**
28 * @param mixed $sharing
29 */
30 public static function fromOption($sharing) : ?self
31 {
32 if ($sharing instanceof self) {
33 return $sharing;
34 }
35 $mode = self::normalizeMode($sharing, 'transport_sharing');
36 if ($mode === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::NONE) {
37 return null;
38 }
39 if ($mode === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::HANDLER_PREFER) {
40 return self::createHandlerShareOrNull($mode);
41 }
42 return self::createHandlerShare($mode);
43 }
44 /**
45 * @param mixed $sharing
46 */
47 public static function normalizeMode($sharing, string $option) : string
48 {
49 if ($sharing instanceof self) {
50 return $sharing->mode;
51 }
52 if ($sharing === null || $sharing === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::NONE) {
53 return \YoastSEO_Vendor\GuzzleHttp\TransportSharing::NONE;
54 }
55 if ($sharing === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::HANDLER_PREFER || $sharing === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::HANDLER_REQUIRE) {
56 return $sharing;
57 }
58 throw new \InvalidArgumentException(\sprintf('The "%s" option must be null or a GuzzleHttp\\TransportSharing::* constant; received %s.', $option, \get_debug_type($sharing)));
59 }
60 public static function assertNoRequiredSharingCustomFactoryConflict(array $options, string $handlerName) : void
61 {
62 if (!\array_key_exists('handle_factory', $options) || $options['handle_factory'] === null) {
63 return;
64 }
65 $mode = self::normalizeMode($options['transport_sharing'] ?? null, 'transport_sharing');
66 if ($mode !== \YoastSEO_Vendor\GuzzleHttp\TransportSharing::HANDLER_REQUIRE) {
67 return;
68 }
69 throw new \InvalidArgumentException(\sprintf('The "transport_sharing" %s option cannot require sharing with a custom "handle_factory" because Guzzle cannot ensure that the custom factory applies CURLOPT_SHARE.', $handlerName));
70 }
71 private static function createHandlerShareOrNull(string $mode) : ?self
72 {
73 try {
74 return self::createHandlerShare($mode);
75 } catch (\Throwable $e) {
76 return null;
77 }
78 }
79 private static function createHandlerShare(string $mode) : self
80 {
81 if (!\function_exists('curl_share_init') || !\function_exists('curl_share_setopt')) {
82 throw new \InvalidArgumentException('The "transport_sharing" option requires cURL share support.');
83 }
84 self::requireCurlConstant('CURLOPT_SHARE');
85 $shareOption = self::requireCurlConstant('CURLSHOPT_SHARE');
86 $locks = self::handlerLocks($mode);
87 $handle = \curl_share_init();
88 try {
89 foreach ($locks as $lock) {
90 try {
91 $success = \curl_share_setopt($handle, $shareOption, $lock);
92 } catch (\Throwable $e) {
93 throw new \InvalidArgumentException('Unable to configure cURL share handle: ' . $e->getMessage(), 0, $e);
94 }
95 if (!$success) {
96 throw new \InvalidArgumentException(\sprintf('Unable to configure cURL share handle with lock data %d.', $lock));
97 }
98 }
99 } catch (\Throwable $e) {
100 self::closeHandlerShareHandleOnPhp7($handle);
101 throw $e;
102 }
103 return new self($mode, $handle);
104 }
105 /**
106 * @return int[]
107 */
108 private static function handlerLocks(string $mode) : array
109 {
110 \YoastSEO_Vendor\GuzzleHttp\Handler\CurlVersion::ensureHandlerSharingSupported();
111 if ($mode === \YoastSEO_Vendor\GuzzleHttp\TransportSharing::HANDLER_REQUIRE) {
112 \YoastSEO_Vendor\GuzzleHttp\Handler\CurlVersion::ensureSslSessionSharingSupported();
113 }
114 $locks = [self::requireCurlConstant('CURL_LOCK_DATA_DNS')];
115 if (\YoastSEO_Vendor\GuzzleHttp\Handler\CurlVersion::supportsSslSessionSharing()) {
116 $locks[] = self::requireCurlConstant('CURL_LOCK_DATA_SSL_SESSION');
117 }
118 return $locks;
119 }
120 private static function requireCurlConstant(string $constant) : int
121 {
122 if (!\defined($constant)) {
123 throw new \InvalidArgumentException(\sprintf('The "transport_sharing" option requires %s, but it is not available in the installed PHP cURL extension.', $constant));
124 }
125 $value = \constant($constant);
126 if (!\is_int($value)) {
127 throw new \InvalidArgumentException(\sprintf('The cURL constant %s must resolve to an integer.', $constant));
128 }
129 return $value;
130 }
131 /**
132 * @param resource|\CurlShareHandle $handle
133 */
134 private static function closeHandlerShareHandleOnPhp7($handle) : void
135 {
136 if (\PHP_VERSION_ID < 80000 && \is_resource($handle)) {
137 \curl_share_close($handle);
138 }
139 }
140 }
141