This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 764f2ddcaf Fixes Accept-Encoding cache variance behavior (#12618)
764f2ddcaf is described below
commit 764f2ddcaf3a64515c58046b9b6769d9c71fb0f6
Author: Jake Champion <[email protected]>
AuthorDate: Mon Nov 17 19:18:25 2025 +0000
Fixes Accept-Encoding cache variance behavior (#12618)
Changes the condition to only ignore Accept-Encoding variance when
explicitly set to 1, preserving proper Vary header semantics for the default
value of 2.
Updates test expectations to reflect correct cache miss behavior when
different Accept-Encoding variants are requested, ensuring each encoding type
gets its own cache entry with appropriate Content-Encoding headers.
---
src/iocore/cache/HttpTransactCache.cc | 6 ++-
.../headers/normalized_ae_match_vary_cache.test.py | 31 ++++++++++++
.../normalized_ae_varied_transactions.replay.yaml | 59 ++++++++++++----------
3 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/src/iocore/cache/HttpTransactCache.cc
b/src/iocore/cache/HttpTransactCache.cc
index 021985fff4..47117ad90e 100644
--- a/src/iocore/cache/HttpTransactCache.cc
+++ b/src/iocore/cache/HttpTransactCache.cc
@@ -1244,7 +1244,11 @@ HttpTransactCache::CalcVariability(const
HttpConfigAccessor *http_config_params,
// Disable Vary mismatch checking for Accept-Encoding. This is only
safe to
// set if you are promising to fix any
Accept-Encoding/Content-Encoding mismatches.
- if (http_config_params->get_ignore_accept_encoding_mismatch() &&
+ // Only suppress variability checks when the operator explicitly set
+ // proxy.config.http.cache.ignore_accept_encoding_mismatch to 1. The
+ // documented default value of 2 should continue to enforce Vary header
+ // semantics whenever the origin sends one.
+ if ((http_config_params->get_ignore_accept_encoding_mismatch() == 1) &&
!strcasecmp(const_cast<char *>(field->str), "Accept-Encoding")) {
continue;
}
diff --git a/tests/gold_tests/headers/normalized_ae_match_vary_cache.test.py
b/tests/gold_tests/headers/normalized_ae_match_vary_cache.test.py
index 991d2fda32..f8a70b6cc3 100644
--- a/tests/gold_tests/headers/normalized_ae_match_vary_cache.test.py
+++ b/tests/gold_tests/headers/normalized_ae_match_vary_cache.test.py
@@ -31,6 +31,37 @@ testName = "NORMALIZE_AE_MATCH_VARY"
replay_file = "replays/normalized_ae_varied_transactions.replay.yaml"
server = Test.MakeVerifierServerProcess("server", replay_file)
+# Verify that cache hit requests never reach the server
+# Case 2 (normalize_ae:1) cache hits
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 12", "Verify empty Accept-Encoding (uuid 12) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 13", "Verify deflate request (uuid 13) is a cache hit and doesn't
reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 14", "Verify br,compress request (uuid 14) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 16", "Verify br,compress,gzip request (uuid 16) is a cache hit and
doesn't reach the server.")
+# Case 3 (normalize_ae:2) cache hits
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 22", "Verify empty Accept-Encoding (uuid 22) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 23", "Verify deflate request (uuid 23) is a cache hit and doesn't
reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 26", "Verify br,compress,gzip request (uuid 26) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 27", "Verify compress,gzip request (uuid 27) is a cache hit and
doesn't reach the server.")
+# Case 4 (normalize_ae:3) cache hits
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 32", "Verify empty Accept-Encoding (uuid 32) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 33", "Verify deflate request (uuid 33) is a cache hit and doesn't
reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 37", "Verify compress,gzip request (uuid 37) is a cache hit and
doesn't reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 38", "Verify br;q=1.1 request (uuid 38) is a cache hit and doesn't
reach the server.")
+server.Streams.stdout += Testers.ExcludesExpression(
+ "uuid: 39", "Verify br,gzip;q=0.8 request (uuid 39) is a cache hit and
doesn't reach the server.")
+
ts = Test.MakeATSProcess("ts", enable_cache=True)
ts.Disk.remap_config.AddLine(
f"map http://www.ae-0.com http://127.0.0.1:{server.Variables.http_port}" +
diff --git
a/tests/gold_tests/headers/replays/normalized_ae_varied_transactions.replay.yaml
b/tests/gold_tests/headers/replays/normalized_ae_varied_transactions.replay.yaml
index 57842341a5..8582152b7f 100644
---
a/tests/gold_tests/headers/replays/normalized_ae_varied_transactions.replay.yaml
+++
b/tests/gold_tests/headers/replays/normalized_ae_varied_transactions.replay.yaml
@@ -96,7 +96,7 @@ sessions:
- [ X-Response-Identifier, { value: Empty-Accept-Encoding, as: equal }
]
- [ X-Cache, { value: miss, as: equal } ]
- # Accept-Encoding header deflate would match the alternate of empty
Accept-Encoding header
+ # request deflate Accept-Encoding when origin lacks that variant
- client-request:
method: "GET"
version: "1.1"
@@ -113,13 +113,12 @@ sessions:
<<: *404_response
proxy-response:
- status: 200
+ status: 404
headers:
fields:
- - [ X-Response-Identifier, { value: Empty-Accept-Encoding, as: equal }
]
- - [ X-Cache, { value: hit-fresh, as: equal } ]
+ - [ X-Cache, { value: miss, as: equal } ]
- # Accept-Encoding header br, compress would match the alternate of empty
Accept-Encoding header
+ # load an alternate of br Accept-Encoding header
- client-request:
method: "GET"
version: "1.1"
@@ -133,14 +132,23 @@ sessions:
delay: 100ms
server-response:
- <<: *404_response
+ status: 200
+ reason: OK
+ headers:
+ fields:
+ - [ Transfer-Encoding, chunked ]
+ - [ Cache-Control, max-age=300 ]
+ - [ Content-Encoding, br ]
+ - [ Vary, Accept-Encoding ]
+ - [ Connection, close ]
+ - [ X-Response-Identifier, Br-Accept-Encoding ]
proxy-response:
status: 200
headers:
fields:
- - [ X-Response-Identifier, { value: Empty-Accept-Encoding, as: equal }
]
- - [ X-Cache, { value: hit-fresh, as: equal } ]
+ - [ X-Response-Identifier, { value: Br-Accept-Encoding, as: equal } ]
+ - [ X-Cache, { value: miss, as: equal } ]
# load an alternate of gzip Accept-Encoding header
- client-request:
@@ -176,7 +184,7 @@ sessions:
- [ X-Response-Identifier, { value: Gzip-Accept-Encoding, as: equal } ]
- [ X-Cache, { value: miss, as: equal } ]
- # Accept-Encoding header br, compress, gzip would match the alternate of
gzip Accept-Encoding header
+ # load an alternate of br Accept-Encoding header
- client-request:
method: "GET"
version: "1.1"
@@ -190,14 +198,23 @@ sessions:
delay: 100ms
server-response:
- <<: *404_response
+ status: 200
+ reason: OK
+ headers:
+ fields:
+ - [ Transfer-Encoding, chunked ]
+ - [ Cache-Control, max-age=300 ]
+ - [ Content-Encoding, br ]
+ - [ Vary, Accept-Encoding ]
+ - [ Connection, close ]
+ - [ X-Response-Identifier, Br-Accept-Encoding ]
proxy-response:
status: 200
headers:
fields:
- - [ X-Response-Identifier, { value: Gzip-Accept-Encoding, as: equal } ]
- - [ X-Cache, { value: hit-fresh, as: equal } ]
+ - [ X-Response-Identifier, { value: Br-Accept-Encoding, as: equal } ]
+ - [ X-Cache, { value: miss, as: equal } ]
# Case 2 proxy.config.http.normalize_ae:1
@@ -699,10 +716,6 @@ sessions:
- [ X-Response-Identifier, { value: Gzip-Accept-Encoding, as: equal } ]
- [ X-Cache, { value: miss, as: equal } ]
- # NOTICE: This case should load an alternate of br, gzip Accept-Encoding
header.
- # However, due to the implementation of calculate_quality_of_match(),
- # ATS matches the alternate of gzip Accept-Encoding header.
- # The result is DIFFERENT from the description of
proxy.config.http.normalize_ae: 3
- client-request:
method: "GET"
version: "1.1"
@@ -733,10 +746,8 @@ sessions:
status: 200
headers:
fields:
- # - [ X-Response-Identifier, { value: Br-Gzip-Accept-Encoding, as:
equal } ]
- # - [ X-Cache, { value: miss, as: equal } ]
- - [ X-Response-Identifier, { value: Gzip-Accept-Encoding, as: equal } ]
- - [ X-Cache, { value: hit-fresh, as: equal } ]
+ - [ X-Response-Identifier, { value: Br-Gzip-Accept-Encoding, as: equal
} ]
+ - [ X-Cache, { value: miss, as: equal } ]
# Accept-Encoding header compress, gzip would match the alternate of gzip
Accept-Encoding header
- client-request:
@@ -784,11 +795,6 @@ sessions:
- [ X-Response-Identifier, { value: Br-Accept-Encoding, as: equal } ]
- [ X-Cache, { value: hit-fresh, as: equal } ]
- # NOTICE: This case should make Accept-Encoding header br, gzip;q=0.8 match
- # the alternate of br, gzip Accept-Encoding header.
- # However, due to the implementation of calculate_quality_of_match(),
- # ATS matches the alternate of gzip Accept-Encoding header.
- # The result is DIFFERENT from the description of
proxy.config.http.normalize_ae: 3
- client-request:
method: "GET"
version: "1.1"
@@ -808,6 +814,5 @@ sessions:
status: 200
headers:
fields:
- # - [ X-Response-Identifier, { value: Br-Gzip-Accept-Encoding, as:
equal } ]
- - [ X-Response-Identifier, { value: Gzip-Accept-Encoding, as: equal } ]
+ - [ X-Response-Identifier, { value: Br-Gzip-Accept-Encoding, as: equal
} ]
- [ X-Cache, { value: hit-fresh, as: equal } ]