This is an automated email from the ASF dual-hosted git repository.

wkaras 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 94dfd0e0f5 Cleanup of header_rewrite redirect operator when invoked 
globally. (#11551)
94dfd0e0f5 is described below

commit 94dfd0e0f571a4e91bb0bcaa49af1c039db94e31
Author: Walt Karas <[email protected]>
AuthorDate: Mon Aug 5 15:03:59 2024 -0400

    Cleanup of header_rewrite redirect operator when invoked globally. (#11551)
    
    Also includes new Au test coverage.
---
 doc/admin-guide/plugins/header_rewrite.en.rst      |  6 +-
 plugins/header_rewrite/operators.cc                | 51 +++--------------
 plugins/header_rewrite/operators.h                 |  2 +
 .../header_rewrite/gold/set-redirect-glob.gold     |  8 +++
 .../header_rewrite/header_rewrite_url_glob.test.py | 64 ++++++++++++++++++++++
 .../header_rewrite/rules/glob_set_redirect.conf    | 24 ++++++++
 6 files changed, 111 insertions(+), 44 deletions(-)

diff --git a/doc/admin-guide/plugins/header_rewrite.en.rst 
b/doc/admin-guide/plugins/header_rewrite.en.rst
index 7d971a0f4d..97431776b6 100644
--- a/doc/admin-guide/plugins/header_rewrite.en.rst
+++ b/doc/admin-guide/plugins/header_rewrite.en.rst
@@ -839,8 +839,10 @@ set-redirect
 When invoked, sends a redirect response to the client, with HTTP status
 ``<code>``, and a new location of ``<destination>``. If the ``QSA`` flag is
 enabled, the original query string will be preserved and added to the new
-location automatically. This operator supports
-`String concatenations`_ for ``<destination>``.
+location automatically. This operator supports `String concatenations`_ for
+``<destination>``.  This operator can only execute on the
+``READ_RESPONSE_HDR_HOOK`` (the default when the plugin is global), the
+``SEND_RESPONSE_HDR_HOOK``, or the ``REMAP_PSEUDO_HOOK``.
 
 set-status
 ~~~~~~~~~~
diff --git a/plugins/header_rewrite/operators.cc 
b/plugins/header_rewrite/operators.cc
index 0bb87f89c3..7729a82a52 100644
--- a/plugins/header_rewrite/operators.cc
+++ b/plugins/header_rewrite/operators.cc
@@ -488,6 +488,14 @@ OperatorSetRedirect::initialize(Parser &p)
   require_resources(RSRC_RESPONSE_STATUS);
 }
 
+void
+OperatorSetRedirect::initialize_hooks()
+{
+  add_allowed_hook(TS_HTTP_READ_RESPONSE_HDR_HOOK);
+  add_allowed_hook(TS_HTTP_SEND_RESPONSE_HDR_HOOK);
+  add_allowed_hook(TS_REMAP_PSEUDO_HOOK);
+}
+
 void
 EditRedirectResponse(TSHttpTxn txnp, const std::string &location, TSHttpStatus 
status, TSMBuffer bufp, TSMLoc hdr_loc)
 {
@@ -515,35 +523,6 @@ EditRedirectResponse(TSHttpTxn txnp, const std::string 
&location, TSHttpStatus s
   TSHttpTxnErrorBodySet(txnp, TSstrdup(msg.c_str()), msg.length(), 
TSstrdup("text/html"));
 }
 
-static int
-cont_add_location(TSCont contp, TSEvent event, void *edata)
-{
-  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
-
-  OperatorSetRedirect *osd = static_cast<OperatorSetRedirect 
*>(TSContDataGet(contp));
-  // Set the new status code and reason.
-  TSHttpStatus status = osd->get_status();
-  switch (event) {
-  case TS_EVENT_HTTP_SEND_RESPONSE_HDR: {
-    TSMBuffer bufp;
-    TSMLoc    hdr_loc;
-    if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) == TS_SUCCESS) {
-      EditRedirectResponse(txnp, osd->get_location(), status, bufp, hdr_loc);
-    } else {
-      Dbg(pi_dbg_ctl, "Could not retrieve the response header");
-    }
-
-  } break;
-
-  case TS_EVENT_HTTP_TXN_CLOSE:
-    TSContDestroy(contp);
-    break;
-  default:
-    break;
-  }
-  return 0;
-}
-
 void
 OperatorSetRedirect::exec(const Resources &res) const
 {
@@ -610,21 +589,9 @@ OperatorSetRedirect::exec(const Resources &res) const
       const_cast<Resources &>(res).changed_url = true;
       res._rri->redirect                       = 1;
     } else {
+      Dbg(pi_dbg_ctl, "OperatorSetRedirect::exec() hook=%d", int(get_hook()));
       // Set the new status code and reason.
       TSHttpStatus status = static_cast<TSHttpStatus>(_status.get_int_value());
-      switch (get_hook()) {
-      case TS_HTTP_PRE_REMAP_HOOK: {
-        TSHttpTxnStatusSet(res.txnp, status);
-        TSCont contp = TSContCreate(cont_add_location, nullptr);
-        TSContDataSet(contp, const_cast<OperatorSetRedirect *>(this));
-        TSHttpTxnHookAdd(res.txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
-        TSHttpTxnHookAdd(res.txnp, TS_HTTP_TXN_CLOSE_HOOK, contp);
-        TSHttpTxnReenable(res.txnp, TS_EVENT_HTTP_CONTINUE);
-        return;
-      } break;
-      default:
-        break;
-      }
       TSHttpHdrStatusSet(res.bufp, res.hdr_loc, status);
       EditRedirectResponse(res.txnp, value, status, res.bufp, res.hdr_loc);
     }
diff --git a/plugins/header_rewrite/operators.h 
b/plugins/header_rewrite/operators.h
index 2c4712a67b..25debe1d7e 100644
--- a/plugins/header_rewrite/operators.h
+++ b/plugins/header_rewrite/operators.h
@@ -159,6 +159,8 @@ public:
   }
 
 protected:
+  void initialize_hooks() override;
+
   void exec(const Resources &res) const override;
 
 private:
diff --git 
a/tests/gold_tests/pluginTest/header_rewrite/gold/set-redirect-glob.gold 
b/tests/gold_tests/pluginTest/header_rewrite/gold/set-redirect-glob.gold
new file mode 100644
index 0000000000..8e7c106ff6
--- /dev/null
+++ b/tests/gold_tests/pluginTest/header_rewrite/gold/set-redirect-glob.gold
@@ -0,0 +1,8 @@
+``
+> HEAD / HTTP/1.1
+> Host: 127.0.0.1:``
+``
+< HTTP/1.1 301 Moved Permanently
+``
+< Location: http://redirect.com/here
+``
diff --git 
a/tests/gold_tests/pluginTest/header_rewrite/header_rewrite_url_glob.test.py 
b/tests/gold_tests/pluginTest/header_rewrite/header_rewrite_url_glob.test.py
new file mode 100644
index 0000000000..006acaabb3
--- /dev/null
+++ b/tests/gold_tests/pluginTest/header_rewrite/header_rewrite_url_glob.test.py
@@ -0,0 +1,64 @@
+'''
+Test global header_rewrite with set-redirect operator.
+'''
+#  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.
+
+Test.Summary = '''
+Test global header_rewrite with set-redirect operator.
+'''
+
+Test.ContinueOnFail = True
+ts = Test.MakeATSProcess("ts", block_for_debug=False)
+server = Test.MakeOriginServer("server")
+
+# Configure the server to return 200 responses. The rewrite rules below set a
+# non-200 status, so if curl gets a 200 response something went wrong.
+Test.testName = ""
+request_header = {"headers": "GET / HTTP/1.1\r\nHost: no_path.com\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+server.addResponse("sessionfile.log", request_header, response_header)
+
+ts.Disk.records_config.update(
+    {
+        'proxy.config.url_remap.remap_required': 0,
+        'proxy.config.diags.debug.enabled': 1,
+        'proxy.config.diags.show_location': 0,
+        'proxy.config.diags.debug.tags': 'header',
+    })
+ts.Setup.CopyAs('rules/glob_set_redirect.conf', Test.RunDirectory)
+
+ts.Disk.plugin_config.AddLine(f'header_rewrite.so 
{Test.RunDirectory}/glob_set_redirect.conf')
+
+# Run operator on Read Response Hdr hook (ID:REQUEST == 0).
+tr = Test.AddTestRun()
+tr.Processes.Default.StartBefore(ts)
+tr.Processes.Default.StartBefore(server)
+tr.Processes.Default.Command = (f'curl --head 127.0.0.1:{ts.Variables.port} -H 
"Host: 127.0.0.1:{server.Variables.Port}" --verbose')
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stderr = "gold/set-redirect-glob.gold"
+tr.StillRunningAfter = server
+tr.StillRunningAfter = ts
+ts.Disk.traffic_out.Content = "gold/header_rewrite-tag.gold"
+
+# Run operator on Send Response Hdr hook (ID:REQUEST == 1).
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = (f'curl --head 127.0.0.1:{ts.Variables.port} -H 
"Host: 127.0.0.1:{server.Variables.Port}" --verbose')
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stderr = "gold/set-redirect-glob.gold"
+tr.StillRunningAfter = server
+tr.StillRunningAfter = ts
+ts.Disk.traffic_out.Content = "gold/header_rewrite-tag.gold"
diff --git 
a/tests/gold_tests/pluginTest/header_rewrite/rules/glob_set_redirect.conf 
b/tests/gold_tests/pluginTest/header_rewrite/rules/glob_set_redirect.conf
new file mode 100644
index 0000000000..7dfa502693
--- /dev/null
+++ b/tests/gold_tests/pluginTest/header_rewrite/rules/glob_set_redirect.conf
@@ -0,0 +1,24 @@
+#
+# 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.
+
+cond %{READ_RESPONSE_HDR_HOOK} [AND]
+cond %{ID:REQUEST} =0
+    set-redirect 301 http://redirect.com/here
+
+cond %{SEND_RESPONSE_HDR_HOOK} [AND]
+cond %{ID:REQUEST} =1
+    set-redirect 301 http://redirect.com/here

Reply via email to