PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
← All changes | includes/sdk/s3/GuzzleHttp/Handler/StreamHandler.php +174 -87 1.0.31.4.1 View file →
@@ -3,8 +3,9 @@
3 3 namespace Dudlewebs\WPMCS\s3\GuzzleHttp\Handler;
4 4
5 5 use Dudlewebs\WPMCS\s3\GuzzleHttp\Exception\ConnectException;
6 6 use Dudlewebs\WPMCS\s3\GuzzleHttp\Exception\RequestException;
7 +use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise as P;
7 8 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\FulfilledPromise;
8 9 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\PromiseInterface;
9 10 use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7;
10 11 use Dudlewebs\WPMCS\s3\GuzzleHttp\TransferStats;
@@ -11,13 +12,19 @@
11 12 use Dudlewebs\WPMCS\s3\GuzzleHttp\Utils;
12 13 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
13 14 use Dudlewebs\WPMCS\s3\Psr\Http\Message\ResponseInterface;
14 15 use Dudlewebs\WPMCS\s3\Psr\Http\Message\StreamInterface;
16 +use Dudlewebs\WPMCS\s3\Psr\Http\Message\UriInterface;
15 17 /**
16 18 * HTTP handler that uses PHP's HTTP stream wrapper.
19 + *
20 + * @final
17 21 */
18 22 class StreamHandler
19 23 {
24 + /**
25 + * @var array
26 + */
20 27 private $lastHeaders = [];
21 28 /**
22 29 * Sends an HTTP request.
23 30 *
@@ -22,24 +29,26 @@
22 29 * Sends an HTTP request.
23 30 *
24 31 * @param RequestInterface $request Request to send.
25 32 * @param array $options Request transfer options.
26 - *
27 - * @return PromiseInterface
28 33 */
29 - public function __invoke(RequestInterface $request, array $options)
34 + public function __invoke(RequestInterface $request, array $options) : PromiseInterface
30 35 {
31 36 // Sleep if there is a delay specified.
32 37 if (isset($options['delay'])) {
33 38 \usleep($options['delay'] * 1000);
34 39 }
40 + $protocolVersion = $request->getProtocolVersion();
41 + if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
42 + throw new ConnectException(\sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
43 + }
35 44 $startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
36 45 try {
37 46 // Does not support the expect header.
38 47 $request = $request->withoutHeader('Expect');
39 48 // Append a content-length header if body size is zero to match
40 - // cURL's behavior.
41 - if (0 === $request->getBody()->getSize()) {
49 + // the behavior of `CurlHandler`
50 + if ((0 === \strcasecmp('PUT', $request->getMethod()) || 0 === \strcasecmp('POST', $request->getMethod())) && 0 === $request->getBody()->getSize()) {
42 51 $request = $request->withHeader('Content-Length', '0');
43 52 }
44 53 return $this->createResponse($request, $options, $this->createStream($request, $options), $startTime);
45 54 } catch (\InvalidArgumentException $e) {
@@ -47,46 +56,52 @@
47 56 } catch (\Exception $e) {
48 57 // Determine if the error was a networking error.
49 58 $message = $e->getMessage();
50 59 // This list can probably get more comprehensive.
51 - if (\strpos($message, 'getaddrinfo') || \strpos($message, 'Connection refused') || \strpos($message, "couldn't connect to host") || \strpos($message, "connection attempt failed")) {
60 + if (\false !== \strpos($message, 'getaddrinfo') || \false !== \strpos($message, 'Connection refused') || \false !== \strpos($message, "couldn't connect to host") || \false !== \strpos($message, 'connection attempt failed')) {
52 61 $e = new ConnectException($e->getMessage(), $request, $e);
62 + } else {
63 + $e = RequestException::wrapException($request, $e);
53 64 }
54 - $e = RequestException::wrapException($request, $e);
55 65 $this->invokeStats($options, $request, $startTime, null, $e);
56 - return \Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\rejection_for($e);
66 + return P\Create::rejectionFor($e);
57 67 }
58 68 }
59 - private function invokeStats(array $options, RequestInterface $request, $startTime, ResponseInterface $response = null, $error = null)
69 + private function invokeStats(array $options, RequestInterface $request, ?float $startTime, ?ResponseInterface $response = null, ?\Throwable $error = null) : void
60 70 {
61 71 if (isset($options['on_stats'])) {
62 72 $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []);
63 - \call_user_func($options['on_stats'], $stats);
73 + $options['on_stats']($stats);
64 74 }
65 75 }
66 - private function createResponse(RequestInterface $request, array $options, $stream, $startTime)
76 + /**
77 + * @param resource $stream
78 + */
79 + private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime) : PromiseInterface
67 80 {
68 81 $hdrs = $this->lastHeaders;
69 82 $this->lastHeaders = [];
70 - $parts = \explode(' ', \array_shift($hdrs), 3);
71 - $ver = \explode('/', $parts[0])[1];
72 - $status = $parts[1];
73 - $reason = isset($parts[2]) ? $parts[2] : null;
74 - $headers = \Dudlewebs\WPMCS\s3\GuzzleHttp\headers_from_lines($hdrs);
75 - list($stream, $headers) = $this->checkDecode($options, $headers, $stream);
76 - $stream = Psr7\stream_for($stream);
83 + try {
84 + [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($hdrs);
85 + } catch (\Exception $e) {
86 + return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $request, null, $e));
87 + }
88 + [$stream, $headers] = $this->checkDecode($options, $headers, $stream);
89 + $stream = Psr7\Utils::streamFor($stream);
77 90 $sink = $stream;
78 91 if (\strcasecmp('HEAD', $request->getMethod())) {
79 92 $sink = $this->createSink($stream, $options);
80 93 }
81 - $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
94 + try {
95 + $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
96 + } catch (\Exception $e) {
97 + return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $request, null, $e));
98 + }
82 99 if (isset($options['on_headers'])) {
83 100 try {
84 101 $options['on_headers']($response);
85 102 } catch (\Exception $e) {
86 - $msg = 'An error was encountered during the on_headers event';
87 - $ex = new RequestException($msg, $request, $response, $e);
88 - return \Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\rejection_for($ex);
103 + return P\Create::rejectionFor(new RequestException('An error was encountered during the on_headers event', $request, $response, $e));
89 104 }
90 105 }
91 106 // Do not drain when the request is a HEAD request because they have
92 107 // no body.
@@ -95,25 +110,28 @@
95 110 }
96 111 $this->invokeStats($options, $request, $startTime, $response, null);
97 112 return new FulfilledPromise($response);
98 113 }
99 - private function createSink(StreamInterface $stream, array $options)
114 + private function createSink(StreamInterface $stream, array $options) : StreamInterface
100 115 {
101 116 if (!empty($options['stream'])) {
102 117 return $stream;
103 118 }
104 - $sink = isset($options['sink']) ? $options['sink'] : \fopen('php://temp', 'r+');
105 - return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\stream_for($sink);
119 + $sink = $options['sink'] ?? Psr7\Utils::tryFopen('php://temp', 'r+');
120 + return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink);
106 121 }
107 - private function checkDecode(array $options, array $headers, $stream)
122 + /**
123 + * @param resource $stream
124 + */
125 + private function checkDecode(array $options, array $headers, $stream) : array
108 126 {
109 127 // Automatically decode responses when instructed.
110 128 if (!empty($options['decode_content'])) {
111 - $normalizedKeys = \Dudlewebs\WPMCS\s3\GuzzleHttp\normalize_header_keys($headers);
129 + $normalizedKeys = Utils::normalizeHeaderKeys($headers);
112 130 if (isset($normalizedKeys['content-encoding'])) {
113 131 $encoding = $headers[$normalizedKeys['content-encoding']];
114 132 if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
115 - $stream = new Psr7\InflateStream(Psr7\stream_for($stream));
133 + $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream));
116 134 $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']];
117 135 // Remove content-encoding header
118 136 unset($headers[$normalizedKeys['content-encoding']]);
119 137 // Fix content-length header
@@ -133,23 +151,20 @@
133 151 }
134 152 /**
135 153 * Drains the source stream into the "sink" client option.
136 154 *
137 - * @param StreamInterface $source
138 - * @param StreamInterface $sink
139 - * @param string $contentLength Header specifying the amount of
140 - * data to read.
155 + * @param string $contentLength Header specifying the amount of
156 + * data to read.
141 157 *
142 - * @return StreamInterface
143 158 * @throws \RuntimeException when the sink option is invalid.
144 159 */
145 - private function drain(StreamInterface $source, StreamInterface $sink, $contentLength)
160 + private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength) : StreamInterface
146 161 {
147 162 // If a content-length header is provided, then stop reading once
148 163 // that number of bytes has been read. This can prevent infinitely
149 164 // reading from a stream when dealing with servers that do not honor
150 165 // Connection: Close headers.
151 - Psr7\copy_to_stream($source, $sink, \strlen($contentLength) > 0 && (int) $contentLength > 0 ? (int) $contentLength : -1);
166 + Psr7\Utils::copyToStream($source, $sink, \strlen($contentLength) > 0 && (int) $contentLength > 0 ? (int) $contentLength : -1);
152 167 $sink->seek(0);
153 168 $source->close();
154 169 return $sink;
155 170 }
@@ -158,19 +173,23 @@
158 173 *
159 174 * @param callable $callback Callable that returns stream resource
160 175 *
161 176 * @return resource
177 + *
162 178 * @throws \RuntimeException on error
163 179 */
164 180 private function createResource(callable $callback)
165 181 {
166 - $errors = null;
167 - \set_error_handler(function ($_, $msg, $file, $line) use(&$errors) {
182 + $errors = [];
183 + \set_error_handler(static function ($_, $msg, $file, $line) use(&$errors) : bool {
168 184 $errors[] = ['message' => $msg, 'file' => $file, 'line' => $line];
169 185 return \true;
170 186 });
171 - $resource = $callback();
172 - \restore_error_handler();
187 + try {
188 + $resource = $callback();
189 + } finally {
190 + \restore_error_handler();
191 + }
173 192 if (!$resource) {
174 193 $message = 'Error creating resource: ';
175 194 foreach ($errors as $err) {
176 195 foreach ($err as $key => $value) {
@@ -180,8 +199,11 @@
180 199 throw new \RuntimeException(\trim($message));
181 200 }
182 201 return $resource;
183 202 }
203 + /**
204 + * @return resource
205 + */
184 206 private function createStream(RequestInterface $request, array $options)
185 207 {
186 208 static $methods;
187 209 if (!$methods) {
@@ -186,11 +208,14 @@
186 208 static $methods;
187 209 if (!$methods) {
188 210 $methods = \array_flip(\get_class_methods(__CLASS__));
189 211 }
212 + if (!\in_array($request->getUri()->getScheme(), ['http', 'https'])) {
213 + throw new RequestException(\sprintf("The scheme '%s' is not supported.", $request->getUri()->getScheme()), $request);
214 + }
190 215 // HTTP/1.1 streams using the PHP stream wrapper require a
191 216 // Connection: close header
192 - if ($request->getProtocolVersion() == '1.1' && !$request->hasHeader('Connection')) {
217 + if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection')) {
193 218 $request = $request->withHeader('Connection', 'close');
194 219 }
195 220 // Ensure SSL is verified by default
196 221 if (!isset($options['verify'])) {
@@ -215,18 +240,26 @@
215 240 }
216 241 $context = \array_replace_recursive($context, $options['stream_context']);
217 242 }
218 243 // Microsoft NTLM authentication only supported with curl handler
219 - if (isset($options['auth']) && \is_array($options['auth']) && isset($options['auth'][2]) && 'ntlm' == $options['auth'][2]) {
244 + if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) {
220 245 throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
221 246 }
222 247 $uri = $this->resolveHost($request, $options);
223 - $context = $this->createResource(function () use($context, $params) {
248 + $contextResource = $this->createResource(static function () use($context, $params) {
224 249 return \stream_context_create($context, $params);
225 250 });
226 - return $this->createResource(function () use($uri, &$http_response_header, $context, $options) {
227 - $resource = \fopen((string) $uri, 'r', null, $context);
228 - $this->lastHeaders = $http_response_header;
251 + return $this->createResource(function () use($uri, $contextResource, $context, $options, $request) {
252 + $resource = @\fopen((string) $uri, 'r', \false, $contextResource);
253 + // See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
254 + if (\function_exists('Dudlewebs\\WPMCS\\s3\\http_get_last_response_headers')) {
255 + /** @var array|null */
256 + $http_response_header = \Dudlewebs\WPMCS\s3\http_get_last_response_headers();
257 + }
258 + $this->lastHeaders = $http_response_header ?? [];
259 + if (\false === $resource) {
260 + throw new ConnectException(\sprintf('Connection refused for URI %s', $uri), $request, null, $context);
261 + }
229 262 if (isset($options['read_timeout'])) {
230 263 $readTimeout = $options['read_timeout'];
231 264 $sec = (int) $readTimeout;
232 265 $usec = ($readTimeout - $sec) * 100000;
@@ -234,29 +267,30 @@
234 267 }
235 268 return $resource;
236 269 });
237 270 }
238 - private function resolveHost(RequestInterface $request, array $options)
271 + private function resolveHost(RequestInterface $request, array $options) : UriInterface
239 272 {
240 273 $uri = $request->getUri();
241 274 if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) {
242 275 if ('v4' === $options['force_ip_resolve']) {
243 276 $records = \dns_get_record($uri->getHost(), \DNS_A);
244 - if (!isset($records[0]['ip'])) {
277 + if (\false === $records || !isset($records[0]['ip'])) {
245 278 throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
246 279 }
247 - $uri = $uri->withHost($records[0]['ip']);
248 - } elseif ('v6' === $options['force_ip_resolve']) {
280 + return $uri->withHost($records[0]['ip']);
281 + }
282 + if ('v6' === $options['force_ip_resolve']) {
249 283 $records = \dns_get_record($uri->getHost(), \DNS_AAAA);
250 - if (!isset($records[0]['ipv6'])) {
284 + if (\false === $records || !isset($records[0]['ipv6'])) {
251 285 throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
252 286 }
253 - $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']');
287 + return $uri->withHost('[' . $records[0]['ipv6'] . ']');
254 288 }
255 289 }
256 290 return $uri;
257 291 }
258 - private function getDefaultContext(RequestInterface $request)
292 + private function getDefaultContext(RequestInterface $request) : array
259 293 {
260 294 $headers = '';
261 295 foreach ($request->getHeaders() as $name => $value) {
262 296 foreach ($value as $val) {
@@ -262,11 +296,11 @@
262 296 foreach ($value as $val) {
263 297 $headers .= "{$name}: {$val}\r\n";
264 298 }
265 299 }
266 - $context = ['http' => ['method' => $request->getMethod(), 'header' => $headers, 'protocol_version' => $request->getProtocolVersion(), 'ignore_errors' => \true, 'follow_location' => 0]];
300 + $context = ['http' => ['method' => $request->getMethod(), 'header' => $headers, 'protocol_version' => $request->getProtocolVersion(), 'ignore_errors' => \true, 'follow_location' => 0], 'ssl' => ['peer_name' => $request->getUri()->getHost()]];
267 301 $body = (string) $request->getBody();
268 - if (!empty($body)) {
302 + if ('' !== $body) {
269 303 $context['http']['content'] = $body;
270 304 // Prevent the HTTP handler from adding a Content-Type header.
271 305 if (!$request->hasHeader('Content-Type')) {
272 306 $context['http']['header'] .= "Content-Type:\r\n";
@@ -274,45 +308,90 @@
274 308 }
275 309 $context['http']['header'] = \rtrim($context['http']['header']);
276 310 return $context;
277 311 }
278 - private function add_proxy(RequestInterface $request, &$options, $value, &$params)
312 + /**
313 + * @param mixed $value as passed via Request transfer options.
314 + */
315 + private function add_proxy(RequestInterface $request, array &$options, $value, array &$params) : void
279 316 {
317 + $uri = null;
280 318 if (!\is_array($value)) {
281 - $options['http']['proxy'] = $value;
319 + $uri = $value;
282 320 } else {
283 321 $scheme = $request->getUri()->getScheme();
284 322 if (isset($value[$scheme])) {
285 - if (!isset($value['no']) || !\Dudlewebs\WPMCS\s3\GuzzleHttp\is_host_in_noproxy($request->getUri()->getHost(), $value['no'])) {
286 - $options['http']['proxy'] = $value[$scheme];
323 + if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) {
324 + $uri = $value[$scheme];
287 325 }
288 326 }
289 327 }
328 + if (!$uri) {
329 + return;
330 + }
331 + $parsed = $this->parse_proxy($uri);
332 + $options['http']['proxy'] = $parsed['proxy'];
333 + if ($parsed['auth']) {
334 + if (!isset($options['http']['header'])) {
335 + $options['http']['header'] = [];
336 + }
337 + $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}";
338 + }
290 339 }
291 - private function add_timeout(RequestInterface $request, &$options, $value, &$params)
340 + /**
341 + * Parses the given proxy URL to make it compatible with the format PHP's stream context expects.
342 + */
343 + private function parse_proxy(string $url) : array
292 344 {
345 + $parsed = \parse_url($url);
346 + if ($parsed !== \false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') {
347 + if (isset($parsed['host']) && isset($parsed['port'])) {
348 + $auth = null;
349 + if (isset($parsed['user']) && isset($parsed['pass'])) {
350 + $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}");
351 + }
352 + return ['proxy' => "tcp://{$parsed['host']}:{$parsed['port']}", 'auth' => $auth ? "Basic {$auth}" : null];
353 + }
354 + }
355 + // Return proxy as-is.
356 + return ['proxy' => $url, 'auth' => null];
357 + }
358 + /**
359 + * @param mixed $value as passed via Request transfer options.
360 + */
361 + private function add_timeout(RequestInterface $request, array &$options, $value, array &$params) : void
362 + {
293 363 if ($value > 0) {
294 364 $options['http']['timeout'] = $value;
295 365 }
296 366 }
297 - private function add_verify(RequestInterface $request, &$options, $value, &$params)
367 + /**
368 + * @param mixed $value as passed via Request transfer options.
369 + */
370 + private function add_crypto_method(RequestInterface $request, array &$options, $value, array &$params) : void
298 371 {
299 - if ($value === \true) {
300 - // PHP 5.6 or greater will find the system cert by default. When
301 - // < 5.6, use the Guzzle bundled cacert.
302 - if (\PHP_VERSION_ID < 50600) {
303 - $options['ssl']['cafile'] = \Dudlewebs\WPMCS\s3\GuzzleHttp\default_ca_bundle();
304 - }
305 - } elseif (\is_string($value)) {
372 + 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) {
373 + $options['http']['crypto_method'] = $value;
374 + return;
375 + }
376 + throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
377 + }
378 + /**
379 + * @param mixed $value as passed via Request transfer options.
380 + */
381 + private function add_verify(RequestInterface $request, array &$options, $value, array &$params) : void
382 + {
383 + if ($value === \false) {
384 + $options['ssl']['verify_peer'] = \false;
385 + $options['ssl']['verify_peer_name'] = \false;
386 + return;
387 + }
388 + if (\is_string($value)) {
306 389 $options['ssl']['cafile'] = $value;
307 390 if (!\file_exists($value)) {
308 391 throw new \RuntimeException("SSL CA bundle not found: {$value}");
309 392 }
310 - } elseif ($value === \false) {
311 - $options['ssl']['verify_peer'] = \false;
312 - $options['ssl']['verify_peer_name'] = \false;
313 - return;
314 - } else {
393 + } elseif ($value !== \true) {
315 394 throw new \InvalidArgumentException('Invalid verify request option');
316 395 }
317 396 $options['ssl']['verify_peer'] = \true;
318 397 $options['ssl']['verify_peer_name'] = \true;
@@ -317,9 +396,12 @@
317 396 $options['ssl']['verify_peer'] = \true;
318 397 $options['ssl']['verify_peer_name'] = \true;
319 398 $options['ssl']['allow_self_signed'] = \false;
320 399 }
321 - private function add_cert(RequestInterface $request, &$options, $value, &$params)
400 + /**
401 + * @param mixed $value as passed via Request transfer options.
402 + */
403 + private function add_cert(RequestInterface $request, array &$options, $value, array &$params) : void
322 404 {
323 405 if (\is_array($value)) {
324 406 $options['ssl']['passphrase'] = $value[1];
325 407 $value = $value[0];
@@ -328,17 +410,25 @@
328 410 throw new \RuntimeException("SSL certificate not found: {$value}");
329 411 }
330 412 $options['ssl']['local_cert'] = $value;
331 413 }
332 - private function add_progress(RequestInterface $request, &$options, $value, &$params)
414 + /**
415 + * @param mixed $value as passed via Request transfer options.
416 + */
417 + private function add_progress(RequestInterface $request, array &$options, $value, array &$params) : void
333 418 {
334 - $this->addNotification($params, function ($code, $a, $b, $c, $transferred, $total) use($value) {
419 + self::addNotification($params, static function ($code, $a, $b, $c, $transferred, $total) use($value) {
335 420 if ($code == \STREAM_NOTIFY_PROGRESS) {
336 - $value($total, $transferred, null, null);
421 + // The upload progress cannot be determined. Use 0 for cURL compatibility:
422 + // https://curl.se/libcurl/c/CURLOPT_PROGRESSFUNCTION.html
423 + $value($total, $transferred, 0, 0);
337 424 }
338 425 });
339 426 }
340 - private function add_debug(RequestInterface $request, &$options, $value, &$params)
427 + /**
428 + * @param mixed $value as passed via Request transfer options.
429 + */
430 + private function add_debug(RequestInterface $request, array &$options, $value, array &$params) : void
341 431 {
342 432 if ($value === \false) {
343 433 return;
344 434 }
@@ -343,13 +433,11 @@
343 433 return;
344 434 }
345 435 static $map = [\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'];
346 436 static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max'];
347 - $value = \Dudlewebs\WPMCS\s3\GuzzleHttp\debug_resource($value);
437 + $value = Utils::debugResource($value);
348 438 $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
349 - $this->addNotification($params, function () use($ident, $value, $map, $args) {
350 - $passed = \func_get_args();
351 - $code = \array_shift($passed);
439 + self::addNotification($params, static function (int $code, ...$passed) use($ident, $value, $map, $args) : void {
352 440 \fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
353 441 foreach (\array_filter($passed) as $i => $v) {
354 442 \fwrite($value, $args[$i] . ': "' . $v . '" ');
355 443 }
@@ -355,23 +443,22 @@
355 443 }
356 444 \fwrite($value, "\n");
357 445 });
358 446 }
359 - private function addNotification(array &$params, callable $notify)
447 + private static function addNotification(array &$params, callable $notify) : void
360 448 {
361 449 // Wrap the existing function if needed.
362 450 if (!isset($params['notification'])) {
363 451 $params['notification'] = $notify;
364 452 } else {
365 - $params['notification'] = $this->callArray([$params['notification'], $notify]);
453 + $params['notification'] = self::callArray([$params['notification'], $notify]);
366 454 }
367 455 }
368 - private function callArray(array $functions)
456 + private static function callArray(array $functions) : callable
369 457 {
370 - return function () use($functions) {
371 - $args = \func_get_args();
458 + return static function (...$args) use($functions) {
372 459 foreach ($functions as $fn) {
373 - \call_user_func_array($fn, $args);
460 + $fn(...$args);
374 461 }
375 462 };
376 463 }
377 464 }