diff options
| author | 2025-11-04 12:48:31 +0100 | |
|---|---|---|
| committer | 2025-11-04 12:48:31 +0100 | |
| commit | 7d4854a0a4f5665db599f18c34035786465639f3 (patch) | |
| tree | ed69305612249a91080d42e3fe39021cab15dda2 /lib/lib_rss.php | |
| parent | 5535067f64fe4285b414a48ae6d16b85fb26f97f (diff) | |
Create separate `Retry-After` files for proxies (#8029)
* Create separate `Retry-After` files for proxies
Bad proxies are able to send a false `Retry-After` header and affect the availability of feeds (domain-wide) for other users.
This PR starts including the address of the proxy if present in filenames for `Retry-After` to mitigate the issue.
* Reduce code changes
* Sync SimplePie fork
https://github.com/FreshRSS/simplepie/pull/62
---------
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Diffstat (limited to 'lib/lib_rss.php')
| -rw-r--r-- | lib/lib_rss.php | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 5e19ec628..e7503ffe4 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -735,7 +735,24 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a cleanCache(CLEANCACHE_HOURS); } - if (($retryAfter = FreshRSS_http_Util::getRetryAfter($url)) > 0) { + $options = []; + $accept = ''; + $proxy = is_string(FreshRSS_Context::systemConf()->curl_options[CURLOPT_PROXY] ?? null) ? FreshRSS_Context::systemConf()->curl_options[CURLOPT_PROXY] : ''; + if (is_array($attributes['curl_params'] ?? null)) { + $options = sanitizeCurlParams($attributes['curl_params']); + $proxy = is_string($options[CURLOPT_PROXY]) ? $options[CURLOPT_PROXY] : ''; + if (is_array($options[CURLOPT_HTTPHEADER] ?? null)) { + // Remove headers problematic for security + $options[CURLOPT_HTTPHEADER] = array_filter($options[CURLOPT_HTTPHEADER], + fn($header) => is_string($header) && !preg_match('/^(Remote-User|X-WebAuth-User)\\s*:/i', $header)); + // Add Accept header if it is not set + if (preg_grep('/^Accept\\s*:/i', $options[CURLOPT_HTTPHEADER]) === false) { + $options[CURLOPT_HTTPHEADER][] = 'Accept: ' . $accept; + } + } + } + + if (($retryAfter = FreshRSS_http_Util::getRetryAfter($url, $proxy)) > 0) { Minz_Log::warning('For that domain, will first retry after ' . date('c', $retryAfter) . '. ' . \SimplePie\Misc::url_remove_credentials($url)); return ['body' => '', 'effective_url' => $url, 'redirect_count' => 0, 'fail' => true]; } @@ -744,7 +761,6 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a syslog(LOG_INFO, 'FreshRSS GET ' . $type . ' ' . \SimplePie\Misc::url_remove_credentials($url)); } - $accept = ''; switch ($type) { case 'json': $accept = 'application/json,application/feed+json,application/javascript;q=0.9,text/javascript;q=0.8,*/*;q=0.7'; @@ -782,6 +798,9 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a //CURLOPT_VERBOSE => 1, // To debug sent HTTP headers ]); + curl_setopt_array($ch, $options); + curl_setopt_array($ch, FreshRSS_Context::systemConf()->curl_options); + $responseHeaders = ''; curl_setopt($ch, CURLOPT_HEADERFUNCTION, function (\CurlHandle $ch, string $header) use (&$responseHeaders) { if (trim($header) !== '') { // Skip e.g. separation with trailer headers @@ -790,22 +809,6 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a return strlen($header); }); - curl_setopt_array($ch, FreshRSS_Context::systemConf()->curl_options); - - if (is_array($attributes['curl_params'] ?? null)) { - $options = sanitizeCurlParams($attributes['curl_params']); - if (is_array($options[CURLOPT_HTTPHEADER] ?? null)) { - // Remove headers problematic for security - $options[CURLOPT_HTTPHEADER] = array_filter($options[CURLOPT_HTTPHEADER], - fn($header) => is_string($header) && !preg_match('/^(Remote-User|X-WebAuth-User)\\s*:/i', $header)); - // Add Accept header if it is not set - if (preg_grep('/^Accept\\s*:/i', $options[CURLOPT_HTTPHEADER]) === false) { - $options[CURLOPT_HTTPHEADER][] = 'Accept: ' . $accept; - } - } - curl_setopt_array($ch, $options); - } - if (isset($attributes['ssl_verify'])) { curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, empty($attributes['ssl_verify']) ? 0 : 2); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (bool)$attributes['ssl_verify']); @@ -838,7 +841,7 @@ function httpGet(string $url, string $cachePath, string $type = 'html', array $a $body = ''; Minz_Log::warning('Error fetching content: HTTP code ' . $c_status . ': ' . $c_error . ' ' . $url); if (in_array($c_status, [429, 503], true)) { - $retryAfter = FreshRSS_http_Util::setRetryAfter($url, $headers['retry-after'] ?? ''); + $retryAfter = FreshRSS_http_Util::setRetryAfter($url, $proxy, $headers['retry-after'] ?? ''); if ($c_status === 429) { $errorMessage = 'HTTP 429 Too Many Requests! [' . \SimplePie\Misc::url_remove_credentials($url) . ']'; } elseif ($c_status === 503) { |
