BUG/MINOR: cache: Check cache entry is complete in case of Vary

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.

(cherry picked from commit 25917cdb12412378a80e755ffc18b5cb67c36fd2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4208eb8c0fdf6fae47f10e38c9aeeba6b811cfc1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit ab90e1cbd4cfcaeb0598c2935fbec71ceafa6c59)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 6be1b9ac45ef35fd7ed721b097b01ea4b48038a4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/cache.c b/src/cache.c
index 0b310ae..30e0b7d 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1776,8 +1776,10 @@
 
 	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);
@@ -1804,9 +1806,11 @@
 				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));