]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: cache: Vary not working properly on anything other than accept-encoding
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Wed, 24 Apr 2024 12:32:19 +0000 (14:32 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 29 Apr 2024 08:41:46 +0000 (10:41 +0200)
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.

src/cache.c

index 25f20a7829aa9a0d11dde81626177564ed33312d..c7198cd1a0edd488b74a457b98187874d798c4c5 100644 (file)
@@ -1138,7 +1138,7 @@ static int http_check_vary_header(struct htx *htx, unsigned int *vary_signature)
  * "vary" on the accept-encoding value.
  * 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;
        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;
        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. */
        while (count < hash_info_count && info->value != VARY_ACCEPT_ENCODING) {
                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
         * explicitly supported in parse_encoding_value function). */
        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;
 
        if (!shctx_row_reserve_hot(shctx, first, trash.data)) {