From: Christopher Faulet Date: Wed, 21 Oct 2026 09:02:01 +0000 (+0000) Subject: BUG/MINOR: cache: compare the Age to the heuristic lifetime when none is given X-Git-Url: https://git.kaiwu.me/%7Bsubstring-before(@doc,%20'.xml')%7D.html?a=commitdiff_plain;h=6655158623313262064e21897c2b55b56bfd3c38;p=haproxy.git BUG/MINOR: cache: compare the Age to the heuristic lifetime when none is given A response carrying a validator (Last-Modified or ETag) but no explicit lifetime (no max-age, s-maxage nor Expires) is normally stored for the cache's max-age. But as soon as such a response carries an Age header with a non-null value, which is the case of all responses coming through an upstream cache, it is never stored, which only affects performance and the load of the servers. When the response has no explicit lifetime, http_calc_maxage() returns the cache's max-age but leaves the true max age untouched, i.e. zero. The store action then refuses the response because its Age is greater than this "true max age" of zero, as if it was stale. When no explicit lifetime is found, the cache's max-age is used as a heuristic lifetime (RFC 9111#4.2.2), so it is now also reported as the true max age, and as a lifetime relative to the response's generation, like max-age, so that the Age is deducted from it by the previous fix. A response whose Age exceeds the cache's max-age is still refused. This patch may be backported to all supported versions, along with the previous one ("BUG/MINOR: cache: reduce the max-age lifetime by the response's Age") on which it depends. --- diff --git a/src/cache.c b/src/cache.c index 8d3bc03a1..ff75bcfe1 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1041,9 +1041,9 @@ char *directive_value(const char *sample, int slen, const char *word, int wlen) * (cache->maxage) but the actual max age of the response will be set in the * true_maxage parameter. It will be used to determine if a response is already * stale or not. If is not NULL, it is set to 1 when the true max - * age comes from a s-maxage or max-age directive, which is relative to the - * generation of the response and must thus be reduced by its Age, or 0 when it - * comes from an absolute date or the cache's configuration. + * age comes from a s-maxage or max-age directive or from the cache's + * configuration, which are relative to the generation of the response and must + * thus be reduced by its Age, or 0 when it comes from an absolute date. * Compute the maxage using either: * - the assigned max-age of the cache * - the s-maxage directive @@ -1121,7 +1121,7 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage, in if (age_relative) - *age_relative = (smaxage > 0 || maxage > 0); + *age_relative = (smaxage > 0 || maxage > 0 || expires < 0); if (smaxage > 0) { if (true_maxage) @@ -1141,6 +1141,11 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage, in return MIN(expires, cache->maxage); } + /* No explicit lifetime, the cache's one is used as a heuristic + * lifetime (RFC 9111#4.2.2) counting from the response's generation. + */ + if (true_maxage) + *true_maxage = cache->maxage; return cache->maxage; }