MEDIUM: cache: Change caching conditions
Do not cache responses that do not have an explicit expiration time
(s-maxage or max-age Cache-Control directives or Expires header) or a
validator (ETag or Last-Modified headers) anymore, as suggested in
RFC 7234#3.
The TX_FLAG_IGNORE flag is used instead of the TX_FLAG_CACHEABLE so as
not to change the behavior of the checkcache option.
(cherry picked from commit cc9bf2e5fe1fe6f15de9e78b6aaea2cd6be5ca4f)
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
diff --git a/src/cache.c b/src/cache.c
index f86c96f..4f8fad9 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -664,7 +664,7 @@
http_check_response_for_cacheability(s, &s->res);
- if (!(txn->flags & TX_CACHEABLE) || !(txn->flags & TX_CACHE_COOK))
+ if (!(txn->flags & TX_CACHEABLE) || !(txn->flags & TX_CACHE_COOK) || (txn->flags & TX_CACHE_IGNORE))
goto out;
age = 0;
diff --git a/src/http_ana.c b/src/http_ana.c
index deec220..7a9cd0b 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -3916,6 +3916,8 @@
struct http_txn *txn = s->txn;
struct http_hdr_ctx ctx = { .blk = NULL };
struct htx *htx;
+ int has_freshness_info = 0;
+ int has_validator = 0;
if (txn->status < 200) {
/* do not try to cache interim responses! */
@@ -3953,7 +3955,37 @@
txn->flags &= ~TX_CACHE_COOK;
continue;
}
+
+ if (istmatchi(ctx.value, ist("s-maxage")) ||
+ istmatchi(ctx.value, ist("max-age"))) {
+ has_freshness_info = 1;
+ continue;
+ }
+ }
+
+ /* If no freshness information could be found in Cache-Control values,
+ * look for an Expires header. */
+ if (!has_freshness_info) {
+ ctx.blk = NULL;
+ has_freshness_info = http_find_header(htx, ist("expires"), &ctx, 0);
}
+
+ /* If no freshness information could be found in Cache-Control or Expires
+ * values, look for an explicit validator. */
+ if (!has_freshness_info) {
+ ctx.blk = NULL;
+ has_validator = 1;
+ if (!http_find_header(htx, ist("etag"), &ctx, 0)) {
+ ctx.blk = NULL;
+ if (!http_find_header(htx, ist("last-modified"), &ctx, 0))
+ has_validator = 0;
+ }
+ }
+
+ /* We won't store an entry that has neither a cache validator nor an
+ * explicit expiration time, as suggested in RFC 7234#3. */
+ if (!has_freshness_info && !has_validator)
+ txn->flags |= TX_CACHE_IGNORE;
}
/*