diff --git a/doc/admin-guide/configuration/cache-basics.en.rst b/doc/admin-guide/configuration/cache-basics.en.rst index b03d2bdae00..db5fdc8520b 100644 --- a/doc/admin-guide/configuration/cache-basics.en.rst +++ b/doc/admin-guide/configuration/cache-basics.en.rst @@ -247,17 +247,17 @@ For example, an origin server might send:: Cache-Control: max-age=60 CDN-Cache-Control: max-age=3600 -When targeted cache control is enabled (via -:ts:cv:`proxy.config.http.cache.targeted_cache_control_headers`), Traffic -Server will use the ``CDN-Cache-Control`` directives instead of the standard -``Cache-Control`` directives for caching decisions. The browser receiving the -response will see both headers and use the standard ``Cache-Control``, allowing -the object to be cached for 60 seconds in the browser but 3600 seconds in the CDN. +By default, Traffic Server checks ``CDN-Cache-Control`` first (via +:ts:cv:`proxy.config.http.cache.targeted_cache_control_headers`) and uses +those directives instead of the standard ``Cache-Control`` directives for +caching decisions. The browser receiving the response will see both headers and +use the standard ``Cache-Control``, allowing the object to be cached for +60 seconds in the browser but 3600 seconds in the CDN. Configuration ~~~~~~~~~~~~~ -To enable targeted cache control, set +To customize targeted cache control, set :ts:cv:`proxy.config.http.cache.targeted_cache_control_headers` to a comma-separated list of header names to check in priority order:: @@ -268,6 +268,10 @@ Or with multiple targeted headers in priority order:: proxy.config.http.cache.targeted_cache_control_headers: ATS-Cache-Control,CDN-Cache-Control +To disable targeted cache control entirely, set the value to an empty string:: + + proxy.config.http.cache.targeted_cache_control_headers: "" + This configuration is overridable per-remap, allowing different rules for different origins:: diff --git a/doc/admin-guide/files/records.yaml.en.rst b/doc/admin-guide/files/records.yaml.en.rst index 590f2912d00..77c1d2f54f1 100644 --- a/doc/admin-guide/files/records.yaml.en.rst +++ b/doc/admin-guide/files/records.yaml.en.rst @@ -2518,15 +2518,16 @@ Cache Control ``Cache-Control: max-age``. ===== ====================================================================== -.. ts:cv:: CONFIG proxy.config.http.cache.targeted_cache_control_headers STRING "" +.. ts:cv:: CONFIG proxy.config.http.cache.targeted_cache_control_headers STRING "CDN-Cache-Control" :reloadable: :overridable: - Comma-separated list of targeted cache control header names to check in priority - order before falling back to the standard ``Cache-Control`` header. This implements - `RFC 9213 `_ Targeted HTTP Cache Control. - When empty (the default), targeted cache control is disabled and only the standard - ``Cache-Control`` header is used. + Comma-separated list of targeted cache control header names to check in + priority order before falling back to the standard ``Cache-Control`` + header. This implements `RFC 9213 `_ + Targeted HTTP Cache Control. The default value is ``CDN-Cache-Control``. + Set this to an empty string to disable targeted cache control and use only + the standard ``Cache-Control`` header. Example values: diff --git a/doc/release-notes/whats-new.en.rst b/doc/release-notes/whats-new.en.rst index 9e8f813aad5..346e877ff05 100644 --- a/doc/release-notes/whats-new.en.rst +++ b/doc/release-notes/whats-new.en.rst @@ -108,6 +108,9 @@ Configuration * Added :ts:cv:`proxy.config.http.negative_revalidating_list` to configure the list of status codes that apply to the negative revalidating feature +* :ts:cv:`proxy.config.http.cache.targeted_cache_control_headers` now defaults + to ``CDN-Cache-Control``. Set it to an empty string to disable targeted cache + control. * The ``ssl_multicert.config`` file has been replaced with :file:`ssl_multicert.yaml`. Use ``traffic_ctl config convert ssl_multicert`` to convert existing configuration files. @@ -225,4 +228,3 @@ HTTP UI Removed The stats and cache inspector pages were unmaintained and removed in this release. - diff --git a/src/records/RecordsConfig.cc b/src/records/RecordsConfig.cc index 07328b76739..a0d9e6f7497 100644 --- a/src/records/RecordsConfig.cc +++ b/src/records/RecordsConfig.cc @@ -643,7 +643,7 @@ static constexpr RecordElement RecordsConfig[] = , {RECT_CONFIG, "proxy.config.http.cache.range.write", RECD_INT, "0", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , - {RECT_CONFIG, "proxy.config.http.cache.targeted_cache_control_headers", RECD_STRING, "", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} + {RECT_CONFIG, "proxy.config.http.cache.targeted_cache_control_headers", RECD_STRING, "CDN-Cache-Control", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , // ######################## diff --git a/tests/gold_tests/cache/replay/targeted-cache-control.replay.yaml b/tests/gold_tests/cache/replay/targeted-cache-control.replay.yaml index 90300f79e30..fd6e1bfcb97 100644 --- a/tests/gold_tests/cache/replay/targeted-cache-control.replay.yaml +++ b/tests/gold_tests/cache/replay/targeted-cache-control.replay.yaml @@ -42,11 +42,14 @@ autest: proxy.config.diags.debug.tags: 'http|cache' proxy.config.http.cache.http: 1 proxy.config.http.cache.required_headers: 0 - proxy.config.http.cache.targeted_cache_control_headers: 'ATS-Cache-Control,CDN-Cache-Control' remap_config: - from: "http://example.com/" to: "http://backend.example.com:{SERVER_HTTP_PORT}/" + plugins: + - name: "conf_remap.so" + args: + - "proxy.config.http.cache.targeted_cache_control_headers=ATS-Cache-Control,CDN-Cache-Control" - from: "http://acme.com/" to: "http://backend.acme.com:{SERVER_HTTP_PORT}/" @@ -55,9 +58,41 @@ autest: args: - "proxy.config.http.cache.targeted_cache_control_headers=ACME-Cache-Control" + - from: "http://default.com/" + to: "http://backend.default.com:{SERVER_HTTP_PORT}/" + sessions: - transactions: + ############################################################################# + # Test 0: default config checks CDN-Cache-Control by default. + ############################################################################# + - client-request: + method: GET + url: /default/test1 + version: '1.1' + headers: + fields: + - [Host, default.com] + - [uuid, default-test1-request1] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [Content-Type, text/plain] + - [Content-Length, "14"] + - [Cache-Control, "no-store"] + - [CDN-Cache-Control, "max-age=30"] # Should be used by default. + - [Connection, close] + + proxy-response: + status: 200 + headers: + fields: + - [ Cache-Control, { value: "no-store", as: equal } ] + - [ CDN-Cache-Control, { value: "max-age=30", as: equal } ] ############################################################################# # Test 1: CDN-Cache-Control with higher max-age overrides Cache-Control @@ -249,6 +284,28 @@ sessions: ############################################################################# # Now verify the correct cache behavior from above. ############################################################################# + - client-request: + method: GET + url: /default/test1 + version: '1.1' + headers: + fields: + - [Host, default.com] + - [uuid, default-test1-request2] + + # Should not reach the origin. + server-response: + status: 404 + reason: Not Found + + # Expect the cached 200 response due to default CDN-Cache-Control handling. + proxy-response: + status: 200 + headers: + fields: + - [ Cache-Control, { value: "no-store", as: equal } ] + - [ CDN-Cache-Control, { value: "max-age=30", as: equal } ] + - client-request: # Delay to exceed Cache-Control but not CDN-Cache-Control. delay: 2s diff --git a/tests/gold_tests/cache/targeted-cache-control.test.py b/tests/gold_tests/cache/targeted-cache-control.test.py index 3bcd84047b8..4c6efc174f5 100644 --- a/tests/gold_tests/cache/targeted-cache-control.test.py +++ b/tests/gold_tests/cache/targeted-cache-control.test.py @@ -18,8 +18,8 @@ Test.Summary = ''' Test targeted cache control headers per RFC 9213. -Verifies that CDN-Cache-Control and other targeted headers can override -standard Cache-Control when properly configured. +Verifies that CDN-Cache-Control is applied by default, and that remap-level +targeted header overrides still work. ''' Test.ATSReplayTest(replay_file="replay/targeted-cache-control.replay.yaml")