Skip to content

Commit a7cf9b4

Browse files
committed
File: extract curl initialization to separate function
On PHP < 8.1.21, we will not be able to disable `CURLOPT_ACCEPT_ENCODING` by setting it to `NULL`: php/php-src#11433 `curl_setopt` with such values will be a no-op so the secound `curl_exec` will still fail with `CURLE_BAD_CONTENT_ENCODING` and return an empty body. Even worse, it will still report 200 in `CURLINFO_HTTP_CODE` so `FileClient` will not throw an exception because the `status_code` property is not 0. Let’s extract the code so that we can create a fresh `CurlHandle` and later make the `CURLOPT_ACCEPT_ENCODING` conditional.
1 parent d060f04 commit a7cf9b4

3 files changed

Lines changed: 64 additions & 30 deletions

File tree

‎src/File.php‎

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -110,36 +110,7 @@ public function __construct(string $url, int $timeout = 10, int $redirects = 5,
110110
}
111111
if (!$force_fsockopen && function_exists('curl_exec')) {
112112
$this->method = \SimplePie\SimplePie::FILE_SOURCE_REMOTE | \SimplePie\SimplePie::FILE_SOURCE_CURL;
113-
$fp = curl_init();
114-
$headers2 = [];
115-
foreach ($headers as $key => $value) {
116-
$headers2[] = "$key: $value";
117-
}
118-
if (isset($curl_options[CURLOPT_HTTPHEADER])) {
119-
if (is_array($curl_options[CURLOPT_HTTPHEADER])) {
120-
$headers2 = array_merge($headers2, $curl_options[CURLOPT_HTTPHEADER]);
121-
}
122-
unset($curl_options[CURLOPT_HTTPHEADER]);
123-
}
124-
if (version_compare(\SimplePie\Misc::get_curl_version(), '7.21.6', '>=')) {
125-
curl_setopt($fp, CURLOPT_ACCEPT_ENCODING, '');
126-
} else {
127-
curl_setopt($fp, CURLOPT_ENCODING, '');
128-
}
129-
/** @var non-empty-string $url */
130-
curl_setopt($fp, CURLOPT_URL, $url);
131-
curl_setopt($fp, CURLOPT_HEADER, true);
132-
curl_setopt($fp, CURLOPT_RETURNTRANSFER, true);
133-
curl_setopt($fp, CURLOPT_FAILONERROR, true);
134-
curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
135-
curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
136-
curl_setopt($fp, CURLOPT_REFERER, \SimplePie\Misc::url_remove_credentials($url));
137-
curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
138-
curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
139-
foreach ($curl_options as $curl_param => $curl_value) {
140-
curl_setopt($fp, $curl_param, $curl_value);
141-
}
142-
113+
$fp = self::curlInit($url, $timeout, $headers, $useragent, $curl_options);
143114
$responseHeaders = curl_exec($fp);
144115
if (curl_errno($fp) === CURLE_WRITE_ERROR || curl_errno($fp) === CURLE_BAD_CONTENT_ENCODING) {
145116
if (version_compare(\SimplePie\Misc::get_curl_version(), '7.21.6', '>=')) {
@@ -444,6 +415,52 @@ final public static function fromResponse(Response $response): self
444415

445416
return $file;
446417
}
418+
419+
/**
420+
* @param array<string, string> $headers
421+
* @param array<int, mixed> $curl_options
422+
* @return \CurlHandle
423+
*/
424+
private static function curlInit(
425+
string $url,
426+
int $timeout,
427+
array $headers,
428+
string $useragent,
429+
array $curl_options
430+
) {
431+
$fp = curl_init();
432+
433+
$headers2 = [];
434+
foreach ($headers as $key => $value) {
435+
$headers2[] = "$key: $value";
436+
}
437+
if (isset($curl_options[CURLOPT_HTTPHEADER])) {
438+
if (is_array($curl_options[CURLOPT_HTTPHEADER])) {
439+
$headers2 = array_merge($headers2, $curl_options[CURLOPT_HTTPHEADER]);
440+
}
441+
unset($curl_options[CURLOPT_HTTPHEADER]);
442+
}
443+
if (version_compare(\SimplePie\Misc::get_curl_version(), '7.21.6', '>=')) {
444+
curl_setopt($fp, CURLOPT_ACCEPT_ENCODING, '');
445+
} else {
446+
curl_setopt($fp, CURLOPT_ENCODING, '');
447+
}
448+
/** @var non-empty-string $url */
449+
curl_setopt($fp, CURLOPT_URL, $url);
450+
curl_setopt($fp, CURLOPT_HEADER, true);
451+
curl_setopt($fp, CURLOPT_RETURNTRANSFER, true);
452+
curl_setopt($fp, CURLOPT_FAILONERROR, true);
453+
curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
454+
curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
455+
curl_setopt($fp, CURLOPT_REFERER, \SimplePie\Misc::url_remove_credentials($url));
456+
curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
457+
curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
458+
foreach ($curl_options as $curl_param => $curl_value) {
459+
curl_setopt($fp, $curl_param, $curl_value);
460+
}
461+
462+
return $fp;
463+
}
447464
}
448465

449466
class_alias('SimplePie\File', 'SimplePie_File');

‎utils/PHPStan/extension.neon‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
includes:
2+
- version_dependent.php
13

24
services:
35
-
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace SimplePieUtils\PHPStan;
4+
5+
$typeAliases = [];
6+
7+
if (PHP_VERSION_ID < 80000) {
8+
$typeAliases['\CurlHandle'] = 'resource';
9+
}
10+
11+
return [
12+
'parameters' => [
13+
'typeAliases' => $typeAliases,
14+
],
15+
];

0 commit comments

Comments
 (0)