Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 9... Línea 9...
9
use GuzzleHttp\Promise\PromiseInterface;
9
use GuzzleHttp\Promise\PromiseInterface;
10
use GuzzleHttp\Psr7\LazyOpenStream;
10
use GuzzleHttp\Psr7\LazyOpenStream;
11
use GuzzleHttp\TransferStats;
11
use GuzzleHttp\TransferStats;
12
use GuzzleHttp\Utils;
12
use GuzzleHttp\Utils;
13
use Psr\Http\Message\RequestInterface;
13
use Psr\Http\Message\RequestInterface;
-
 
14
use Psr\Http\Message\UriInterface;
Línea 14... Línea 15...
14
 
15
 
15
/**
16
/**
16
 * Creates curl resources from a request
17
 * Creates curl resources from a request
17
 *
18
 *
Línea 44... Línea 45...
44
        $this->maxHandles = $maxHandles;
45
        $this->maxHandles = $maxHandles;
45
    }
46
    }
Línea 46... Línea 47...
46
 
47
 
47
    public function create(RequestInterface $request, array $options): EasyHandle
48
    public function create(RequestInterface $request, array $options): EasyHandle
-
 
49
    {
-
 
50
        $protocolVersion = $request->getProtocolVersion();
-
 
51
 
-
 
52
        if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
-
 
53
            if (!self::supportsHttp2()) {
-
 
54
                throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
-
 
55
            }
-
 
56
        } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
-
 
57
            throw new ConnectException(sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
-
 
58
        }
48
    {
59
 
49
        if (isset($options['curl']['body_as_string'])) {
60
        if (isset($options['curl']['body_as_string'])) {
50
            $options['_body_as_string'] = $options['curl']['body_as_string'];
61
            $options['_body_as_string'] = $options['curl']['body_as_string'];
51
            unset($options['curl']['body_as_string']);
62
            unset($options['curl']['body_as_string']);
Línea 52... Línea 63...
52
        }
63
        }
53
 
64
 
54
        $easy = new EasyHandle;
65
        $easy = new EasyHandle();
55
        $easy->request = $request;
66
        $easy->request = $request;
56
        $easy->options = $options;
67
        $easy->options = $options;
57
        $conf = $this->getDefaultConf($easy);
68
        $conf = $this->getDefaultConf($easy);
Línea 70... Línea 81...
70
        curl_setopt_array($easy->handle, $conf);
81
        curl_setopt_array($easy->handle, $conf);
Línea 71... Línea 82...
71
 
82
 
72
        return $easy;
83
        return $easy;
Línea -... Línea 84...
-
 
84
    }
-
 
85
 
-
 
86
    private static function supportsHttp2(): bool
-
 
87
    {
-
 
88
        static $supportsHttp2 = null;
-
 
89
 
-
 
90
        if (null === $supportsHttp2) {
-
 
91
            $supportsHttp2 = self::supportsTls12()
-
 
92
                && defined('CURL_VERSION_HTTP2')
-
 
93
                && (\CURL_VERSION_HTTP2 & \curl_version()['features']);
-
 
94
        }
-
 
95
 
-
 
96
        return $supportsHttp2;
-
 
97
    }
-
 
98
 
-
 
99
    private static function supportsTls12(): bool
-
 
100
    {
-
 
101
        static $supportsTls12 = null;
-
 
102
 
-
 
103
        if (null === $supportsTls12) {
-
 
104
            $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
-
 
105
        }
-
 
106
 
-
 
107
        return $supportsTls12;
-
 
108
    }
-
 
109
 
-
 
110
    private static function supportsTls13(): bool
-
 
111
    {
-
 
112
        static $supportsTls13 = null;
-
 
113
 
-
 
114
        if (null === $supportsTls13) {
-
 
115
            $supportsTls13 = defined('CURL_SSLVERSION_TLSv1_3')
-
 
116
                && (\CURL_SSLVERSION_TLSv1_3 & \curl_version()['features']);
-
 
117
        }
-
 
118
 
-
 
119
        return $supportsTls13;
73
    }
120
    }
74
 
121
 
75
    public function release(EasyHandle $easy): void
122
    public function release(EasyHandle $easy): void
76
    {
123
    {
Línea 145... Línea 192...
145
        $ctx = [
192
        $ctx = [
146
            'errno' => $easy->errno,
193
            'errno' => $easy->errno,
147
            'error' => \curl_error($easy->handle),
194
            'error' => \curl_error($easy->handle),
148
            'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME),
195
            'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME),
149
        ] + \curl_getinfo($easy->handle);
196
        ] + \curl_getinfo($easy->handle);
150
        $ctx[self::CURL_VERSION_STR] = \curl_version()['version'];
197
        $ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
151
        $factory->release($easy);
198
        $factory->release($easy);
Línea 152... Línea 199...
152
 
199
 
153
        // Retry when nothing is present or when curl failed to rewind.
200
        // Retry when nothing is present or when curl failed to rewind.
154
        if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
201
        if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
155
            return self::retryFailedRewind($handler, $easy, $ctx);
202
            return self::retryFailedRewind($handler, $easy, $ctx);
Línea 156... Línea 203...
156
        }
203
        }
157
 
204
 
Línea -... Línea 205...
-
 
205
        return self::createRejection($easy, $ctx);
-
 
206
    }
-
 
207
 
-
 
208
    private static function getCurlVersion(): string
-
 
209
    {
-
 
210
        static $curlVersion = null;
-
 
211
 
-
 
212
        if (null === $curlVersion) {
-
 
213
            $curlVersion = \curl_version()['version'];
-
 
214
        }
-
 
215
 
158
        return self::createRejection($easy, $ctx);
216
        return $curlVersion;
159
    }
217
    }
160
 
218
 
161
    private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
219
    private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
162
    {
220
    {
163
        static $connectionErrors = [
221
        static $connectionErrors = [
164
            \CURLE_OPERATION_TIMEOUTED  => true,
222
            \CURLE_OPERATION_TIMEOUTED => true,
165
            \CURLE_COULDNT_RESOLVE_HOST => true,
223
            \CURLE_COULDNT_RESOLVE_HOST => true,
166
            \CURLE_COULDNT_CONNECT      => true,
224
            \CURLE_COULDNT_CONNECT => true,
Línea 167... Línea 225...
167
            \CURLE_SSL_CONNECT_ERROR    => true,
225
            \CURLE_SSL_CONNECT_ERROR => true,
168
            \CURLE_GOT_NOTHING          => true,
226
            \CURLE_GOT_NOTHING => true,
169
        ];
227
        ];
Línea 192... Línea 250...
192
                    $ctx
250
                    $ctx
193
                )
251
                )
194
            );
252
            );
195
        }
253
        }
Línea -... Línea 254...
-
 
254
 
-
 
255
        $uri = $easy->request->getUri();
-
 
256
 
-
 
257
        $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
196
 
258
 
197
        $message = \sprintf(
259
        $message = \sprintf(
198
            'cURL error %s: %s (%s)',
260
            'cURL error %s: %s (%s)',
199
            $ctx['errno'],
261
            $ctx['errno'],
200
            $ctx['error'],
262
            $sanitizedError,
201
            'see https://curl.haxx.se/libcurl/c/libcurl-errors.html'
263
            'see https://curl.haxx.se/libcurl/c/libcurl-errors.html'
-
 
264
        );
-
 
265
 
202
        );
266
        if ('' !== $sanitizedError) {
203
        $uriString = (string) $easy->request->getUri();
267
            $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
204
        if ($uriString !== '' && false === \strpos($ctx['error'], $uriString)) {
268
            if ($redactedUriString !== '' && false === \strpos($sanitizedError, $redactedUriString)) {
-
 
269
                $message .= \sprintf(' for %s', $redactedUriString);
205
            $message .= \sprintf(' for %s', $uriString);
270
            }
Línea 206... Línea 271...
206
        }
271
        }
207
 
272
 
208
        // Create a connection exception if it was a specific error code.
273
        // Create a connection exception if it was a specific error code.
209
        $error = isset($connectionErrors[$easy->errno])
274
        $error = isset($connectionErrors[$easy->errno])
Línea 210... Línea 275...
210
            ? new ConnectException($message, $easy->request, null, $ctx)
275
            ? new ConnectException($message, $easy->request, null, $ctx)
211
            : new RequestException($message, $easy->request, $easy->response, null, $ctx);
276
            : new RequestException($message, $easy->request, $easy->response, null, $ctx);
Línea -... Línea 277...
-
 
277
 
-
 
278
        return P\Create::rejectionFor($error);
-
 
279
    }
-
 
280
 
-
 
281
    private static function sanitizeCurlError(string $error, UriInterface $uri): string
-
 
282
    {
-
 
283
        if ('' === $error) {
-
 
284
            return $error;
-
 
285
        }
-
 
286
 
-
 
287
        $baseUri = $uri->withQuery('')->withFragment('');
-
 
288
        $baseUriString = $baseUri->__toString();
-
 
289
 
-
 
290
        if ('' === $baseUriString) {
-
 
291
            return $error;
-
 
292
        }
-
 
293
 
-
 
294
        $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
212
 
295
 
213
        return P\Create::rejectionFor($error);
296
        return str_replace($baseUriString, $redactedUriString, $error);
214
    }
297
    }
215
 
298
 
216
    /**
299
    /**
217
     * @return array<int|string, mixed>
300
     * @return array<int|string, mixed>
218
     */
301
     */
219
    private function getDefaultConf(EasyHandle $easy): array
302
    private function getDefaultConf(EasyHandle $easy): array
220
    {
303
    {
221
        $conf = [
304
        $conf = [
222
            '_headers'              => $easy->request->getHeaders(),
305
            '_headers' => $easy->request->getHeaders(),
223
            \CURLOPT_CUSTOMREQUEST  => $easy->request->getMethod(),
306
            \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
224
            \CURLOPT_URL            => (string) $easy->request->getUri()->withFragment(''),
307
            \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
Línea 225... Línea 308...
225
            \CURLOPT_RETURNTRANSFER => false,
308
            \CURLOPT_RETURNTRANSFER => false,
226
            \CURLOPT_HEADER         => false,
309
            \CURLOPT_HEADER => false,
227
            \CURLOPT_CONNECTTIMEOUT => 150,
310
            \CURLOPT_CONNECTTIMEOUT => 300,
Línea 228... Línea 311...
228
        ];
311
        ];
-
 
312
 
229
 
313
        if (\defined('CURLOPT_PROTOCOLS')) {
230
        if (\defined('CURLOPT_PROTOCOLS')) {
-
 
231
            $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
-
 
232
        }
314
            $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
-
 
315
        }
-
 
316
 
233
 
317
        $version = $easy->request->getProtocolVersion();
234
        $version = $easy->request->getProtocolVersion();
318
 
235
        if ($version == 1.1) {
319
        if ('2' === $version || '2.0' === $version) {
Línea 236... Línea 320...
236
            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
320
            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
Línea 248... Línea 332...
248
        $body = $easy->request->getBody();
332
        $body = $easy->request->getBody();
249
        $size = $body->getSize();
333
        $size = $body->getSize();
Línea 250... Línea 334...
250
 
334
 
251
        if ($size === null || $size > 0) {
335
        if ($size === null || $size > 0) {
-
 
336
            $this->applyBody($easy->request, $easy->options, $conf);
252
            $this->applyBody($easy->request, $easy->options, $conf);
337
 
253
            return;
338
            return;
Línea 254... Línea 339...
254
        }
339
        }
255
 
340
 
256
        $method = $easy->request->getMethod();
341
        $method = $easy->request->getMethod();
257
        if ($method === 'PUT' || $method === 'POST') {
342
        if ($method === 'PUT' || $method === 'POST') {
258
            // See https://tools.ietf.org/html/rfc7230#section-3.3.2
343
            // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
259
            if (!$easy->request->hasHeader('Content-Length')) {
344
            if (!$easy->request->hasHeader('Content-Length')) {
260
                $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
345
                $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
261
            }
346
            }
Línea 339... Línea 424...
339
    private function removeHeader(string $name, array &$options): void
424
    private function removeHeader(string $name, array &$options): void
340
    {
425
    {
341
        foreach (\array_keys($options['_headers']) as $key) {
426
        foreach (\array_keys($options['_headers']) as $key) {
342
            if (!\strcasecmp($key, $name)) {
427
            if (!\strcasecmp($key, $name)) {
343
                unset($options['_headers'][$key]);
428
                unset($options['_headers'][$key]);
-
 
429
 
344
                return;
430
                return;
345
            }
431
            }
346
        }
432
        }
347
    }
433
    }
Línea 363... Línea 449...
363
                        throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
449
                        throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
364
                    }
450
                    }
365
                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
451
                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
366
                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
452
                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
367
                    if (
453
                    if (
368
                        \is_dir($options['verify']) ||
454
                        \is_dir($options['verify'])
369
                        (
455
                        || (
370
                            \is_link($options['verify']) === true &&
456
                            \is_link($options['verify']) === true
371
                            ($verifyLink = \readlink($options['verify'])) !== false &&
457
                            && ($verifyLink = \readlink($options['verify'])) !== false
372
                            \is_dir($verifyLink)
458
                            && \is_dir($verifyLink)
373
                        )
459
                        )
374
                    ) {
460
                    ) {
375
                        $conf[\CURLOPT_CAPATH] = $options['verify'];
461
                        $conf[\CURLOPT_CAPATH] = $options['verify'];
376
                    } else {
462
                    } else {
377
                        $conf[\CURLOPT_CAINFO] = $options['verify'];
463
                        $conf[\CURLOPT_CAINFO] = $options['verify'];
Línea 386... Línea 472...
386
                $conf[\CURLOPT_ENCODING] = $accept;
472
                $conf[\CURLOPT_ENCODING] = $accept;
387
            } else {
473
            } else {
388
                // The empty string enables all available decoders and implicitly
474
                // The empty string enables all available decoders and implicitly
389
                // sets a matching 'Accept-Encoding' header.
475
                // sets a matching 'Accept-Encoding' header.
390
                $conf[\CURLOPT_ENCODING] = '';
476
                $conf[\CURLOPT_ENCODING] = '';
391
                // But as the user did not specify any acceptable encodings we need
477
                // But as the user did not specify any encoding preference,
-
 
478
                // let's leave it up to server by preventing curl from sending
392
                // to overwrite this implicit header with an empty one.
479
                // the header, which will be interpreted as 'Accept-Encoding: *'.
-
 
480
                // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
393
                $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
481
                $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
394
            }
482
            }
395
        }
483
        }
Línea 396... Línea 484...
396
 
484
 
Línea 441... Línea 529...
441
                $conf[\CURLOPT_PROXY] = $options['proxy'];
529
                $conf[\CURLOPT_PROXY] = $options['proxy'];
442
            } else {
530
            } else {
443
                $scheme = $easy->request->getUri()->getScheme();
531
                $scheme = $easy->request->getUri()->getScheme();
444
                if (isset($options['proxy'][$scheme])) {
532
                if (isset($options['proxy'][$scheme])) {
445
                    $host = $easy->request->getUri()->getHost();
533
                    $host = $easy->request->getUri()->getHost();
446
                    if (!isset($options['proxy']['no']) || !Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
534
                    if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
-
 
535
                        unset($conf[\CURLOPT_PROXY]);
-
 
536
                    } else {
447
                        $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
537
                        $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
448
                    }
538
                    }
449
                }
539
                }
450
            }
540
            }
451
        }
541
        }
Línea -... Línea 542...
-
 
542
 
-
 
543
        if (isset($options['crypto_method'])) {
-
 
544
            $protocolVersion = $easy->request->getProtocolVersion();
-
 
545
 
-
 
546
            // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
-
 
547
            if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
-
 
548
                if (
-
 
549
                    \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']
-
 
550
                    || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']
-
 
551
                    || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']
-
 
552
                ) {
-
 
553
                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
-
 
554
                } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
-
 
555
                    if (!self::supportsTls13()) {
-
 
556
                        throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
-
 
557
                    }
-
 
558
                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
-
 
559
                } else {
-
 
560
                    throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
-
 
561
                }
-
 
562
            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
-
 
563
                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
-
 
564
            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
-
 
565
                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
-
 
566
            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
-
 
567
                if (!self::supportsTls12()) {
-
 
568
                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
-
 
569
                }
-
 
570
                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
-
 
571
            } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
-
 
572
                if (!self::supportsTls13()) {
-
 
573
                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
-
 
574
                }
-
 
575
                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
-
 
576
            } else {
-
 
577
                throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
-
 
578
            }
-
 
579
        }
452
 
580
 
453
        if (isset($options['cert'])) {
581
        if (isset($options['cert'])) {
454
            $cert = $options['cert'];
582
            $cert = $options['cert'];
455
            if (\is_array($cert)) {
583
            if (\is_array($cert)) {
456
                $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
584
                $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
457
                $cert = $cert[0];
585
                $cert = $cert[0];
458
            }
586
            }
459
            if (!\file_exists($cert)) {
587
            if (!\file_exists($cert)) {
460
                throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
588
                throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
461
            }
589
            }
462
            # OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
590
            // OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
463
            # see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
591
            // see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
464
            $ext = pathinfo($cert, \PATHINFO_EXTENSION);
592
            $ext = pathinfo($cert, \PATHINFO_EXTENSION);
465
            if (preg_match('#^(der|p12)$#i', $ext)) {
593
            if (preg_match('#^(der|p12)$#i', $ext)) {
466
                $conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext);
594
                $conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext);
467
            }
595
            }
Línea 521... Línea 649...
521
            if ($body->tell() > 0) {
649
            if ($body->tell() > 0) {
522
                $body->rewind();
650
                $body->rewind();
523
            }
651
            }
524
        } catch (\RuntimeException $e) {
652
        } catch (\RuntimeException $e) {
525
            $ctx['error'] = 'The connection unexpectedly failed without '
653
            $ctx['error'] = 'The connection unexpectedly failed without '
526
                . 'providing an error. The request would have been retried, '
654
                .'providing an error. The request would have been retried, '
527
                . 'but attempting to rewind the request body failed. '
655
                .'but attempting to rewind the request body failed. '
528
                . 'Exception: ' . $e;
656
                .'Exception: '.$e;
-
 
657
 
529
            return self::createRejection($easy, $ctx);
658
            return self::createRejection($easy, $ctx);
530
        }
659
        }
Línea 531... Línea 660...
531
 
660
 
532
        // Retry no more than 3 times before giving up.
661
        // Retry no more than 3 times before giving up.
533
        if (!isset($easy->options['_curl_retries'])) {
662
        if (!isset($easy->options['_curl_retries'])) {
534
            $easy->options['_curl_retries'] = 1;
663
            $easy->options['_curl_retries'] = 1;
535
        } elseif ($easy->options['_curl_retries'] == 2) {
664
        } elseif ($easy->options['_curl_retries'] == 2) {
536
            $ctx['error'] = 'The cURL request was retried 3 times '
665
            $ctx['error'] = 'The cURL request was retried 3 times '
537
                . 'and did not succeed. The most likely reason for the failure '
666
                .'and did not succeed. The most likely reason for the failure '
538
                . 'is that cURL was unable to rewind the body of the request '
667
                .'is that cURL was unable to rewind the body of the request '
539
                . 'and subsequent retries resulted in the same error. Turn on '
668
                .'and subsequent retries resulted in the same error. Turn on '
540
                . 'the debug option to see what went wrong. See '
669
                .'the debug option to see what went wrong. See '
-
 
670
                .'https://bugs.php.net/bug.php?id=47204 for more information.';
541
                . 'https://bugs.php.net/bug.php?id=47204 for more information.';
671
 
542
            return self::createRejection($easy, $ctx);
672
            return self::createRejection($easy, $ctx);
543
        } else {
673
        } else {
544
            $easy->options['_curl_retries']++;
674
            ++$easy->options['_curl_retries'];
Línea 545... Línea 675...
545
        }
675
        }
546
 
676
 
Línea 569... Línea 699...
569
                $startingResponse = true;
699
                $startingResponse = true;
570
                try {
700
                try {
571
                    $easy->createResponse();
701
                    $easy->createResponse();
572
                } catch (\Exception $e) {
702
                } catch (\Exception $e) {
573
                    $easy->createResponseException = $e;
703
                    $easy->createResponseException = $e;
-
 
704
 
574
                    return -1;
705
                    return -1;
575
                }
706
                }
576
                if ($onHeaders !== null) {
707
                if ($onHeaders !== null) {
577
                    try {
708
                    try {
578
                        $onHeaders($easy->response);
709
                        $onHeaders($easy->response);
579
                    } catch (\Exception $e) {
710
                    } catch (\Exception $e) {
580
                        // Associate the exception with the handle and trigger
711
                        // Associate the exception with the handle and trigger
581
                        // a curl header write error by returning 0.
712
                        // a curl header write error by returning 0.
582
                        $easy->onHeadersException = $e;
713
                        $easy->onHeadersException = $e;
-
 
714
 
583
                        return -1;
715
                        return -1;
584
                    }
716
                    }
585
                }
717
                }
586
            } elseif ($startingResponse) {
718
            } elseif ($startingResponse) {
587
                $startingResponse = false;
719
                $startingResponse = false;
588
                $easy->headers = [$value];
720
                $easy->headers = [$value];
589
            } else {
721
            } else {
590
                $easy->headers[] = $value;
722
                $easy->headers[] = $value;
591
            }
723
            }
-
 
724
 
592
            return \strlen($h);
725
            return \strlen($h);
593
        };
726
        };
594
    }
727
    }
-
 
728
 
-
 
729
    public function __destruct()
-
 
730
    {
-
 
731
        foreach ($this->handles as $id => $handle) {
-
 
732
            \curl_close($handle);
-
 
733
            unset($this->handles[$id]);
-
 
734
        }
-
 
735
    }
595
}
736
}