Skip to content

Commit 6ca8916

Browse files
rlebretonwlallemand
authored andcommitted
MINOR: cache: Do not store responses with an unknown encoding
If a server varies on the accept-encoding header and it sends a response with an encoding we do not know (see parse_encoding_value function), we will not store it. This will prevent unexpected errors caused by cache collisions that could happen in accept_encoding_hash_cmp.
1 parent b62b78b commit 6ca8916

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

doc/configuration.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14616,6 +14616,9 @@ The cache won't store and won't deliver objects in these cases:
1461614616
headers)
1461714617
- If the process-vary option is enabled and there are already max-secondary-entries
1461814618
entries with the same primary key as the current response
14619+
- If the process-vary option is enabled and the response has an unknown encoding (not
14620+
mentioned in https://www.iana.org/assignments/http-parameters/http-parameters.xhtml)
14621+
while varying on the accept-encoding client header
1461914622

1462014623
- If the request is not a GET
1462114624
- If the HTTP version of the request is smaller than 1.1

reg-tests/cache/vary_accept_encoding.vtc

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ client c1 -connect ${h1_fe_sock} {
292292

293293
#
294294
# Unknown content-encoding
295+
# The response should not be cached since it has an unknown content encoding
295296
#
296297
txreq -url "/unknown-content-encoding" -hdr "Accept-Encoding: gzip;q=0.8, deflate, first_encoding"
297298
rxresp
@@ -305,14 +306,6 @@ client c1 -connect ${h1_fe_sock} {
305306
expect resp.status == 200
306307
expect resp.http.content-encoding == "unknown_encoding"
307308
expect resp.bodylen == 119
308-
expect resp.http.X-Cache-Hit == 1
309-
310-
# Different set of accepted encodings
311-
txreq -url "/unknown-content-encoding" -hdr "Accept-Encoding: deflate, first_encoding"
312-
rxresp
313-
expect resp.status == 200
314-
expect resp.http.content-encoding == "unknown_encoding"
315-
expect resp.bodylen == 119
316309
expect resp.http.X-Cache-Hit == 0
317310

318311
#

src/cache.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -933,8 +933,11 @@ static int http_check_vary_header(struct htx *htx, unsigned int *vary_signature)
933933
* Look for the accept-encoding part of the secondary_key and replace the
934934
* encoding bitmap part of the hash with the actual encoding of the response,
935935
* extracted from the content-encoding header value.
936+
* Responses that have an unknown encoding will not be cached if they also
937+
* "vary" on the accept-encoding value.
938+
* Returns 0 if we found a known encoding in the response, -1 otherwise.
936939
*/
937-
static void set_secondary_key_encoding(struct htx *htx, char *secondary_key)
940+
static int set_secondary_key_encoding(struct htx *htx, char *secondary_key)
938941
{
939942
unsigned int resp_encoding_bitmap = 0;
940943
const struct vary_hashing_information *info = vary_information;
@@ -952,13 +955,12 @@ static void set_secondary_key_encoding(struct htx *htx, char *secondary_key)
952955
}
953956

954957
if (count == hash_info_count)
955-
return;
958+
return -1;
956959

957960
while (http_find_header(htx, ist("content-encoding"), &ctx, 0)) {
958-
if (!parse_encoding_value(ctx.value, &encoding_value, NULL))
959-
resp_encoding_bitmap |= encoding_value;
960-
else
961-
resp_encoding_bitmap |= VARY_ENCODING_OTHER;
961+
if (parse_encoding_value(ctx.value, &encoding_value, NULL))
962+
return -1; /* Do not store responses with an unknown encoding */
963+
resp_encoding_bitmap |= encoding_value;
962964
}
963965

964966
if (!resp_encoding_bitmap)
@@ -967,6 +969,8 @@ static void set_secondary_key_encoding(struct htx *htx, char *secondary_key)
967969
/* Rewrite the bitmap part of the hash with the new bitmap that only
968970
* corresponds the the response's encoding. */
969971
write_u32(secondary_key + offset, resp_encoding_bitmap);
972+
973+
return 0;
970974
}
971975

972976

@@ -1197,9 +1201,12 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
11971201
/* If the response has a secondary_key, fill its key part related to
11981202
* encodings with the actual encoding of the response. This way any
11991203
* subsequent request having the same primary key will have its accepted
1200-
* encodings tested upon the cached response's one. */
1204+
* encodings tested upon the cached response's one.
1205+
* We will not cache a response that has an unknown encoding (not
1206+
* explicitely supported in parse_encoding_value function). */
12011207
if (cache->vary_processing_enabled && vary_signature)
1202-
set_secondary_key_encoding(htx, object->secondary_key);
1208+
if (set_secondary_key_encoding(htx, object->secondary_key))
1209+
goto out;
12031210

12041211
shctx_lock(shctx);
12051212
if (!shctx_row_reserve_hot(shctx, first, trash.data)) {

0 commit comments

Comments
 (0)