This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit cbaceb52546873d7579b8b78e853f81d851504ae Author: Masaori Koshiba <masa...@apache.org> AuthorDate: Mon Aug 25 09:37:58 2025 +0900 [cache_promote] Add --disable-on-redirect option (#12457) (cherry picked from commit fc2031dfc8682fcae9408ec18089c290e1acfde2) --- doc/admin-guide/plugins/cache_promote.en.rst | 5 + plugins/cache_promote/cache_promote.cc | 5 + plugins/cache_promote/configs.cc | 3 + plugins/cache_promote/configs.h | 7 + .../pluginTest/cache_promote/cache_promote.test.py | 77 ++++++++++ .../replay/cache_promote.replay.yaml.tmpl | 166 +++++++++++++++++++++ 6 files changed, 263 insertions(+) diff --git a/doc/admin-guide/plugins/cache_promote.en.rst b/doc/admin-guide/plugins/cache_promote.en.rst index 62da01ca06..975894f05c 100644 --- a/doc/admin-guide/plugins/cache_promote.en.rst +++ b/doc/admin-guide/plugins/cache_promote.en.rst @@ -39,6 +39,11 @@ are available: The sampling rate for the request to be considered +.. option:: --disable-on-redirect + + Disables running on ``TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK`` again when a transaction follows redirect. + This option is recommended when this plugin is used with the :program:`cachekey` plugin. + If :option:`--policy` is set to ``lru`` the following options are also available: .. option:: --label diff --git a/plugins/cache_promote/cache_promote.cc b/plugins/cache_promote/cache_promote.cc index 21cba7cadc..4c3fccbe9c 100644 --- a/plugins/cache_promote/cache_promote.cc +++ b/plugins/cache_promote/cache_promote.cc @@ -52,6 +52,11 @@ cont_handle_policy(TSCont contp, TSEvent event, void *edata) switch (event) { // After the cache lookups check if it should be promoted on cache misses case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: + if (TSHttpTxnRedirectRetries(txnp) > 0 && config->is_disabled_on_redirect()) { + // do nothing when following redirect if it's configured + break; + } + if (!TSHttpTxnIsInternal(txnp) || config->getPolicy()->isInternalEnabled()) { int obj_status; diff --git a/plugins/cache_promote/configs.cc b/plugins/cache_promote/configs.cc index 58907125c3..a9d8b96092 100644 --- a/plugins/cache_promote/configs.cc +++ b/plugins/cache_promote/configs.cc @@ -27,6 +27,7 @@ static const struct option longopt[] = { {const_cast<char *>("policy"), required_argument, nullptr, 'p' }, {const_cast<char *>("stats-enable-with-id"), required_argument, nullptr, 'e' }, + {const_cast<char *>("disable-on-redirect"), no_argument, nullptr, 'd' }, // This is for both Chance and LRU (optional) policy {const_cast<char *>("sample"), required_argument, nullptr, 's' }, // For the LRU policy @@ -78,6 +79,8 @@ PromotionConfig::factory(int argc, char *argv[]) DBG("stats collection is enabled"); } } + } else if (opt == 'd') { + _disable_on_redirect = true; } else { if (_policy) { // The --sample (-s) option is allowed for all configs, but only after --policy is specified. diff --git a/plugins/cache_promote/configs.h b/plugins/cache_promote/configs.h index bbb9170497..f61f16b22c 100644 --- a/plugins/cache_promote/configs.h +++ b/plugins/cache_promote/configs.h @@ -38,7 +38,14 @@ public: bool factory(int argc, char *argv[]); + bool + is_disabled_on_redirect() + { + return _disable_on_redirect; + } + private: PromotionPolicy *_policy = nullptr; PolicyManager *_manager; + bool _disable_on_redirect = false; }; diff --git a/tests/gold_tests/pluginTest/cache_promote/cache_promote.test.py b/tests/gold_tests/pluginTest/cache_promote/cache_promote.test.py new file mode 100644 index 0000000000..7f4096171d --- /dev/null +++ b/tests/gold_tests/pluginTest/cache_promote/cache_promote.test.py @@ -0,0 +1,77 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +Test.Summary = ''' +Test cache_promote plugin +''' + +Test.SkipUnless(Condition.PluginExists('cache_promote.so')) + + +class CachePromotePluginTest: + + def __init__(self): + self._tr = Test.AddTestRun("cache_promote") + self.__setupOriginServer() + self.__setupTS() + self.__setupClient() + + def __setupClient(self): + # Eval template file to set origin server port to redirect + template_file_path = os.path.join(self._tr.TestDirectory, "replay/cache_promote.replay.yaml.tmpl") + with open(template_file_path, 'r') as f: + template = f.read() + + replay_yaml_path = os.path.join(self._tr.RunDirectory, "cache_promote.replay.yaml") + with open(replay_yaml_path, 'w') as f: + f.write(template.format(httpbin_port=self._httpbin.Variables.Port)) + + self._tr.AddVerifierClientProcess("verifier-client", replay_yaml_path, http_ports=[self._ts.Variables.port]) + + def __setupOriginServer(self): + self._httpbin = Test.MakeHttpBinServer("httpbin") + + def __setupTS(self): + self._ts = Test.MakeATSProcess("ts", enable_cache=True) + self._ts.Disk.records_config.update( + { + "proxy.config.diags.debug.enabled": 1, + "proxy.config.diags.debug.tags": "http|cache_promote", + "proxy.config.http.number_of_redirections": 1, # follow redirect + "proxy.config.http.redirect.actions": "self:follow", # redirects to self are not followed by default + }) + self._ts.Disk.plugin_config.AddLine("xdebug.so --enable=x-cache,x-cache-key") + self._ts.Disk.remap_config.AddLines( + { + f""" +map /test_0/ http://127.0.0.1:{self._httpbin.Variables.Port}/ \ + @plugin=cache_promote.so @pparam=--policy=lru @pparam=--hits=2 @pparam=--buckets=15000000 + +map /test_1/ http://127.0.0.1:{self._httpbin.Variables.Port}/ \ + @plugin=cache_promote.so @pparam=--policy=lru @pparam=--hits=2 @pparam=--buckets=15000000 @pparam=--disable-on-redirect \ + @plugin=cachekey.so @pparam=--static-prefix=trafficserver.apache.org/443 +""" + }) + + def run(self): + self._tr.Processes.Default.StartBefore(self._ts) + self._tr.Processes.Default.StartBefore(self._httpbin) + self._tr.StillRunningAfter = self._ts + self._tr.StillRunningAfter = self._httpbin + + +CachePromotePluginTest().run() diff --git a/tests/gold_tests/pluginTest/cache_promote/replay/cache_promote.replay.yaml.tmpl b/tests/gold_tests/pluginTest/cache_promote/replay/cache_promote.replay.yaml.tmpl new file mode 100644 index 0000000000..422da45cdf --- /dev/null +++ b/tests/gold_tests/pluginTest/cache_promote/replay/cache_promote.replay.yaml.tmpl @@ -0,0 +1,166 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# This is a template file to generate "cache_promote.replay.yaml" needs to be evaluated. +# +meta: + version: "1.0" + +sessions: +- protocol: + - name: http + version: 1 + - name: tcp + - name: ip + + transactions: + # + # test case 0-0 : simple LRU policy case - 3rd request is expected to hit the cache + # + - client-request: + method: "GET" + url: /test_0/cache/2 + headers: + fields: + - [ uuid, 0-0-0 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + - client-request: + method: "GET" + url: /test_0/cache/2 + headers: + fields: + - [ uuid, 0-0-1 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + - client-request: + method: "GET" + url: /test_0/cache/2 + headers: + fields: + - [ uuid, 0-0-2 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "hit-fresh", as: equal }} ] + + # + # test case 0-1 : following redirect + # + - client-request: + method: "GET" + url: /test_0/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/3 + headers: + fields: + - [ uuid, 0-1-0 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + - client-request: + method: "GET" + url: /test_0/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/3 + headers: + fields: + - [ uuid, 0-1-1 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + + - client-request: + method: "GET" + url: /test_0/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/3 + headers: + fields: + - [ uuid, 0-1-2 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "hit-fresh", as: equal }} ] + + # + # test case 1 : following redirect with cachekey plugin + # + - client-request: + method: "GET" + url: /test_1/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/4 + headers: + fields: + - [ uuid, 1-0 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + - client-request: + method: "GET" + url: /test_1/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/4 + headers: + fields: + - [ uuid, 1-1 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "miss", as: equal }} ] + + + - client-request: + method: "GET" + url: /test_1/redirect-to?url=http://127.0.0.1:{httpbin_port}/cache/4 + headers: + fields: + - [ uuid, 1-2 ] + - [ x-debug, x-cache ] + + proxy-response: + status: 200 + headers: + fields: + - [ x-cache, {{value: "hit-fresh", as: equal }} ]