BUG/MEDIUM: cache: Vary not working properly on anything other than accept-encoding

If a response varies on anything other than accept-encoding (origin or
referer) but still contains an 'Encoding' header, the cached responses
were never sent back.
This is because of the 'set_secondary_key_encoding' call that always
filled the accept-encoding part of the secondary signature with the
response's actual encoding, regardless of whether the response varies on
this or not. This meant that the accept-encoding part of the signature
could be non-null in the cached entry which made the
'get_secondary_entry' calls in 'http_action_req_cache_use' always fail
because in those cases the request's secondary signature always had a
null accept-encoding part.

This patch can be backported up to branch 2.4.
This commit is contained in:
Remi Tricot-Le Breton 2024-04-24 14:32:19 +02:00 committed by William Lallemand
parent ba0f8b5330
commit 0610f52bcd

View File

@ -1138,7 +1138,7 @@ static int http_check_vary_header(struct htx *htx, unsigned int *vary_signature)
* "vary" on the accept-encoding value. * "vary" on the accept-encoding value.
* Returns 0 if we found a known encoding in the response, -1 otherwise. * Returns 0 if we found a known encoding in the response, -1 otherwise.
*/ */
static int set_secondary_key_encoding(struct htx *htx, char *secondary_key) static int set_secondary_key_encoding(struct htx *htx, unsigned int vary_signature, char *secondary_key)
{ {
unsigned int resp_encoding_bitmap = 0; unsigned int resp_encoding_bitmap = 0;
const struct vary_hashing_information *info = vary_information; const struct vary_hashing_information *info = vary_information;
@ -1148,6 +1148,11 @@ static int set_secondary_key_encoding(struct htx *htx, char *secondary_key)
unsigned int encoding_value; unsigned int encoding_value;
struct http_hdr_ctx ctx = { .blk = NULL }; struct http_hdr_ctx ctx = { .blk = NULL };
/* We must not set the accept encoding part of the secondary signature
* if the response does not vary on 'Accept Encoding'. */
if (!(vary_signature & VARY_ACCEPT_ENCODING))
return 0;
/* Look for the accept-encoding part of the secondary_key. */ /* Look for the accept-encoding part of the secondary_key. */
while (count < hash_info_count && info->value != VARY_ACCEPT_ENCODING) { while (count < hash_info_count && info->value != VARY_ACCEPT_ENCODING) {
offset += info->hash_length; offset += info->hash_length;
@ -1409,7 +1414,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
* We will not cache a response that has an unknown encoding (not * We will not cache a response that has an unknown encoding (not
* explicitly supported in parse_encoding_value function). */ * explicitly supported in parse_encoding_value function). */
if (cache->vary_processing_enabled && vary_signature) if (cache->vary_processing_enabled && vary_signature)
if (set_secondary_key_encoding(htx, object->secondary_key)) if (set_secondary_key_encoding(htx, vary_signature, object->secondary_key))
goto out; goto out;
if (!shctx_row_reserve_hot(shctx, first, trash.data)) { if (!shctx_row_reserve_hot(shctx, first, trash.data)) {