Skip to content

Commit

Permalink
fix logic for 304 workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
Alkarex committed Sep 20, 2024
1 parent ecee8d4 commit 2a60217
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
18 changes: 18 additions & 0 deletions src/HTTP/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@
*/
final class Utils
{

/**
* Extracts `max-age` from the `Cache-Control` HTTP headers
*
* @param array<string,mixed> $http_headers HTTP headers of the response
* @return int|null The `max-age` value or `null` if not found
*
* FreshRSS
*/
public static function get_http_max_age(array $http_headers): ?int
{
$cache_control = $http_headers['cache-control'] ?? '';
if (is_string($cache_control) && $cache_control !== '' && preg_match('/\bmax-age=(\d+)\b/', $cache_control, $matches)) {
return (int) $matches[1];
}
return null;
}

/**
* Negotiate the cache expiration time based on the HTTP response headers.
* Return the cache duration time in number of seconds since the Unix Epoch, accounting for:
Expand Down
12 changes: 6 additions & 6 deletions src/SimplePie.php
Original file line number Diff line number Diff line change
Expand Up @@ -2019,20 +2019,20 @@ protected function fetch_data(&$cache)
$this->raw_data = false;
if (isset($file)) { // FreshRSS
$old_cache_control = $this->data['headers']['cache-control'] ?? '';
$old_max_age = \SimplePie\HTTP\Utils::get_http_max_age($this->data['headers']);

// Update cache metadata
$this->data['headers'] = array_map(function (array $values): string {
return implode(',', $values);
}, $file->get_headers());

// Workaround for buggy servers returning wrong cache-control headers for 304 responses
if (is_numeric($old_cache_control)) {
$new_cache_control = $this->data['headers']['cache-control'] ?? '';
if (!is_numeric($new_cache_control)) {
$new_cache_control = $this->cache_duration;
if ($old_max_age !== null) {
$new_max_age = \SimplePie\HTTP\Utils::get_http_max_age($this->data['headers']);
if ($new_max_age === null || $new_max_age > $old_max_age) {
// Allow servers to return a shorter cache duration for 304 responses, but not longer
$this->data['headers']['cache-control'] = $old_cache_control;
}
// Allow servers to return a shorter cache duration for 304 responses, but not longer
$this->data['headers']['cache-control'] = min((int)$old_cache_control, (int)$new_cache_control);
}

$this->data['cache_expiration_time'] = \SimplePie\HTTP\Utils::negociate_cache_expiration_time($this->data['headers'] ?? [], $this->cache_duration, $this->cache_duration_min, $this->cache_duration_max);
Expand Down

0 comments on commit 2a60217

Please sign in to comment.