]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cache: Check cache entry is complete in case of Vary
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Tue, 21 Feb 2023 16:42:04 +0000 (17:42 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Feb 2023 17:35:48 +0000 (18:35 +0100)
Before looking for a secondary cache entry for a given request we
checked that the first entry was complete, which might prevent us from
using a valid entry if the first one with the same primary key is not
full yet.
Likewise, if the primary entry is complete but not the secondary entry
we try to use, we might end up using a partial entry from the cache as
a response.

This bug was raised in GitHub #2048.
It can be backported up to branch 2.4.

src/cache.c

index c7a231bbeb4c57de2201e2d11ee8cf3ec10e0478..9683c088af694c357c272a73350e2f24c2814d16 100644 (file)
@@ -1802,8 +1802,10 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
 
        shctx_lock(shctx_ptr(cache));
        res = entry_exist(cache, s->txn->cache_hash);
-       /* We must not use an entry that is not complete. */
-       if (res && res->complete) {
+       /* We must not use an entry that is not complete but the check will be
+        * performed after we look for a potential secondary entry (in case of
+        * Vary). */
+       if (res) {
                struct appctx *appctx;
                entry_block = block_ptr(res);
                shctx_row_inc_hot(shctx_ptr(cache), entry_block);
@@ -1830,9 +1832,11 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
                                res = NULL;
                }
 
-               /* We looked for a valid secondary entry and could not find one,
-                * the request must be forwarded to the server. */
-               if (!res) {
+               /* We either looked for a valid secondary entry and could not
+                * find one, or the entry we want to use is not complete. We
+                * can't use the cache's entry and must forward the request to
+                * the server. */
+               if (!res || !res->complete) {
                        shctx_lock(shctx_ptr(cache));
                        shctx_row_dec_hot(shctx_ptr(cache), entry_block);
                        shctx_unlock(shctx_ptr(cache));