From d04b5ecbb51d2a5b9160c96eb6b38a9554ccae9f Mon Sep 17 00:00:00 2001 From: Leif Hedstrom Date: Mon, 4 Oct 2021 13:21:19 -0600 Subject: [PATCH] Adds the set-http-cntl operator for header_rewrite This supports all the controllers that the InkAPI supports, unclear if all or any of them are useful here. But the LOGGING controller definitely is. LOGGING TS_HTTP_CNTL_LOGGING_MODE INTERCEPT_RETRY TS_HTTP_CNTL_INTERCEPT_RETRY_MODE RESP_CACHEABLE TS_HTTP_CNTL_RESPONSE_CACHEABLE REQ_CACHEABLE TS_HTTP_CNTL_REQUEST_CACHEABLE SERVER_NO_STORE TS_HTTP_CNTL_SERVER_NO_STORE TXN_DEBUG TS_HTTP_CNTL_TXN_DEBUG SKIP_REMAP TS_HTTP_CNTL_SKIP_REMAPPING --- doc/admin-guide/plugins/header_rewrite.en.rst | 30 +++++++- plugins/header_rewrite/factory.cc | 3 + plugins/header_rewrite/operators.cc | 69 +++++++++++++++++++ plugins/header_rewrite/operators.h | 20 ++++++ plugins/header_rewrite/parser.h | 7 ++ 5 files changed, 128 insertions(+), 1 deletion(-) diff --git a/doc/admin-guide/plugins/header_rewrite.en.rst b/doc/admin-guide/plugins/header_rewrite.en.rst index b759ebe2571..554228a5ddf 100644 --- a/doc/admin-guide/plugins/header_rewrite.en.rst +++ b/doc/admin-guide/plugins/header_rewrite.en.rst @@ -703,6 +703,9 @@ the appropriate logs even when the debug tag has not been enabled. For additional information on |TS| debugging statements, refer to :ref:`developer-debug-tags` in the developer's documentation. ++**Note**: This operator is deprecated, use the ``set-http-cntl`` operator instead, ++with the ``TXN_DEBUG`` control. + set-destination ~~~~~~~~~~~~~~~ :: @@ -794,6 +797,9 @@ When invoked, and when ```` is any of ``1``, ``true``, or ``TRUE``, this operator causes |TS| to abort further request remapping. Any other value and the operator will effectively be a no-op. +**Note**: This operator is deprecated, use the ``set-http-cntl`` operator instead, +with the ``SKIP_REMAP`` control. + set-cookie ~~~~~~~~~~ :: @@ -803,6 +809,28 @@ set-cookie Replaces the value of cookie ```` with ````, creating the cookie if necessary. +set-http-cntl +~~~~~~~~~~~~~ +;; + + set-http-cntl + +This operator lets you turn off (or on) the logging for a particular transaction. +The ```` is any of ``0``, ``off``, and ``false``, or ``1``, ``on`` and ``true``. +The available controllers are: + +================ ==================================================================== +Controller Description +================ ==================================================================== +LOGGING Turns off logging for the transction (default: ``on``) +INTERCEPT_RETRY Allow intercepts to be retried (default: ``off``) +RESP_CACHEABLE Force the response to be cacheable (default: ``off``) +REQ_CACHEABLE Force the request to be cacheable (default: ``off``) +SERVER_NO_STORE Don't allow the response to be written to cache (default: ``off``) +TXN_DEBUG Enable transaction debugging (default: ``off``) +SKIP_REMAP Don't require a remap match for the transaction (default: ``off``) +================ ==================================================================== + Operator Flags -------------- @@ -1276,4 +1304,4 @@ the client where the requested data was served from.:: cond %{SEND_RESPONSE_HDR_HOOK} [AND] cond %{HEADER:ATS-SRVR-UUID} ="" [OR] cond %{CACHE} ="hit-fresh" - set-header ATS-SRVR-UUID %{ID:UNIQUE} \ No newline at end of file + set-header ATS-SRVR-UUID %{ID:UNIQUE} diff --git a/plugins/header_rewrite/factory.cc b/plugins/header_rewrite/factory.cc index 6ad3d51b08c..b2cf5d2122f 100644 --- a/plugins/header_rewrite/factory.cc +++ b/plugins/header_rewrite/factory.cc @@ -73,6 +73,9 @@ operator_factory(const std::string &op) o = new OperatorSetDebug(); } else if (op == "set-body") { o = new OperatorSetBody(); + } else if (op == "set-http-cntl") { + o = new OperatorSetHttpCntl(); + } else { TSError("[%s] Unknown operator: %s", PLUGIN_NAME, op.c_str()); return nullptr; diff --git a/plugins/header_rewrite/operators.cc b/plugins/header_rewrite/operators.cc index 99be6a86d76..1f6f6327c5a 100644 --- a/plugins/header_rewrite/operators.cc +++ b/plugins/header_rewrite/operators.cc @@ -21,6 +21,7 @@ // #include #include +#include #include "ts/ts.h" @@ -548,6 +549,7 @@ OperatorSetTimeoutOut::exec(const Resources &res) const } // OperatorSkipRemap +// Deprecated: Remove for v10.0.0 void OperatorSkipRemap::initialize(Parser &p) { @@ -1008,6 +1010,7 @@ OperatorSetConnMark::exec(const Resources &res) const } // OperatorSetDebug +// Deprecated: Remove for v10.0.0 void OperatorSetDebug::initialize(Parser &p) { @@ -1027,3 +1030,69 @@ OperatorSetDebug::exec(const Resources &res) const { TSHttpTxnCntlSet(res.txnp, TS_HTTP_CNTL_TXN_DEBUG, true); } + +// OperatorSetHttpCntl +TSHttpCntlType +parse_cntl_qualifier(const std::string &q) // Helper function for parsing modifiers +{ + TSHttpCntlType qual = TS_HTTP_CNTL_LOGGING_MODE; + + if (q == "LOGGING") { + qual = TS_HTTP_CNTL_LOGGING_MODE; + } else if (q == "INTERCEPT_RETRY") { + qual = TS_HTTP_CNTL_INTERCEPT_RETRY_MODE; + } else if (q == "RESP_CACHEABLE") { + qual = TS_HTTP_CNTL_RESPONSE_CACHEABLE; + } else if (q == "REQ_CACHEABLE") { + qual = TS_HTTP_CNTL_REQUEST_CACHEABLE; + } else if (q == "SERVER_NO_STORE") { + qual = TS_HTTP_CNTL_SERVER_NO_STORE; + } else if (q == "TXN_DEBUG") { + qual = TS_HTTP_CNTL_TXN_DEBUG; + } else if (q == "SKIP_REMAP") { + qual = TS_HTTP_CNTL_SKIP_REMAPPING; + } else { + TSError("[%s] Invalid HTTP-CNTL() qualifier: %s", PLUGIN_NAME, q.c_str()); + } + + return qual; +} + +void +OperatorSetHttpCntl::initialize(Parser &p) +{ + Operator::initialize(p); + _cntl_qual = parse_cntl_qualifier(p.get_arg()); + + std::string flag = p.copy_value(); + + std::transform(flag.begin(), flag.end(), flag.begin(), ::tolower); + + if (flag == "1" || flag == "true" || flag == "on" || flag == "enable") { + _flag = true; + } +} + +void +OperatorSetHttpCntl::initialize_hooks() +{ + add_allowed_hook(TS_HTTP_READ_REQUEST_HDR_HOOK); + 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); +} + +// This is only for the debug statement, and must be in sync with TSHttpCntlType in apidefs.h.in +static const char *const HttpCntls[] = {"LOGGING", "INTERCEPT_RETRY", "RESP_CACHEABLE", "REQ_CACHEABLE", + "SERVER_NO_STORE", "TXN_DEBUG", "SKIP_REMAP"}; +void +OperatorSetHttpCntl::exec(const Resources &res) const +{ + if (_flag) { + TSHttpTxnCntlSet(res.txnp, _cntl_qual, true); + TSDebug(PLUGIN_NAME, " Turning ON %s for transaction", HttpCntls[static_cast(_cntl_qual)]); + } else { + TSHttpTxnCntlSet(res.txnp, _cntl_qual, false); + TSDebug(PLUGIN_NAME, " Turning OFF %s for transaction", HttpCntls[static_cast(_cntl_qual)]); + } +} diff --git a/plugins/header_rewrite/operators.h b/plugins/header_rewrite/operators.h index c2ddf79515c..5d0ae09b359 100644 --- a/plugins/header_rewrite/operators.h +++ b/plugins/header_rewrite/operators.h @@ -423,3 +423,23 @@ class OperatorSetBody : public Operator private: Value _value; }; + +class OperatorSetHttpCntl : public Operator +{ +public: + OperatorSetHttpCntl() { TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorSetHttpCntl"); } + + // noncopyable + OperatorSetHttpCntl(const OperatorSetHttpCntl &) = delete; + void operator=(const OperatorSetHttpCntl &) = delete; + + void initialize(Parser &p) override; + +protected: + void initialize_hooks() override; + void exec(const Resources &res) const override; + +private: + bool _flag = false; + TSHttpCntlType _cntl_qual; +}; diff --git a/plugins/header_rewrite/parser.h b/plugins/header_rewrite/parser.h index 4b3b468c037..feeb1c3d7a7 100644 --- a/plugins/header_rewrite/parser.h +++ b/plugins/header_rewrite/parser.h @@ -69,6 +69,13 @@ class Parser return _val; } + // Return a copy of the string, this implies RVO as well + std::string + copy_value() const + { + return _val; + } + bool mod_exist(const std::string &m) const {