diff --git a/doc/admin-guide/plugins/header_rewrite.en.rst b/doc/admin-guide/plugins/header_rewrite.en.rst index 678fb55a191..b918d801145 100644 --- a/doc/admin-guide/plugins/header_rewrite.en.rst +++ b/doc/admin-guide/plugins/header_rewrite.en.rst @@ -689,6 +689,18 @@ used as its replacement. You must supply a non-zero length value, otherwise this operator will be an effective no-op (though a warning will be emitted to the logs if debugging is enabled). +rm-destination +~~~~~~~~~~~~~~ +:: + + rm-destination + +Removes individual components of the remapped destination's address. When +changing the remapped destination, ```` should be used to indicate the +component that is being modified (see `URL Parts`_). Currently the only valid +parts for rm-destination are QUERY, PATH, and PORT. + + set-header ~~~~~~~~~~ :: @@ -1204,3 +1216,11 @@ could each be tagged with a consistent name to make finding logs easier.:: set-header @PropertyName "someproperty" (Then in :file:`logging.yaml`, log ``%<{@PropertyName}cqh>``) + +Remove Client Query Parameters +------------------------------------ + +The following ruleset removes any query parameters set by the client.:: + + cond %{REMAP_PSEUDO_HOOK} + rm-destination QUERY \ No newline at end of file diff --git a/plugins/header_rewrite/factory.cc b/plugins/header_rewrite/factory.cc index 961d17a5059..89bdde700ec 100644 --- a/plugins/header_rewrite/factory.cc +++ b/plugins/header_rewrite/factory.cc @@ -47,6 +47,8 @@ operator_factory(const std::string &op) o = new OperatorSetStatusReason(); } else if (op == "set-destination") { o = new OperatorSetDestination(); + } else if (op == "rm-destination") { + o = new OperatorRMDestination(); } else if (op == "set-redirect") { o = new OperatorSetRedirect(); } else if (op == "timeout-out") { diff --git a/plugins/header_rewrite/operators.cc b/plugins/header_rewrite/operators.cc index bbd6f52fbab..960884b001c 100644 --- a/plugins/header_rewrite/operators.cc +++ b/plugins/header_rewrite/operators.cc @@ -164,6 +164,17 @@ OperatorSetDestination::initialize(Parser &p) require_resources(RSRC_SERVER_REQUEST_HEADERS); } +// OperatorRMDestination +void +OperatorRMDestination::initialize(Parser &p) +{ + Operator::initialize(p); + + _url_qual = parse_url_qualifier(p.get_arg()); + require_resources(RSRC_CLIENT_REQUEST_HEADERS); + require_resources(RSRC_SERVER_REQUEST_HEADERS); +} + void OperatorSetDestination::exec(const Resources &res) const { @@ -273,6 +284,54 @@ OperatorSetDestination::exec(const Resources &res) const } } +void +OperatorRMDestination::exec(const Resources &res) const +{ + if (res._rri || (res.bufp && res.hdr_loc)) { + // Default empty string to delete components + static std::string value = ""; + + // Determine which TSMBuffer and TSMLoc to use + TSMBuffer bufp; + TSMLoc url_m_loc; + if (res._rri) { + bufp = res._rri->requestBufp; + url_m_loc = res._rri->requestUrl; + } else { + bufp = res.bufp; + if (TSHttpHdrUrlGet(res.bufp, res.hdr_loc, &url_m_loc) != TS_SUCCESS) { + TSDebug(PLUGIN_NAME, "TSHttpHdrUrlGet was unable to return the url m_loc"); + return; + } + } + + // Never set an empty destination value (I don't think that ever makes sense?) + switch (_url_qual) { + case URL_QUAL_PATH: + const_cast(res).changed_url = true; + TSUrlPathSet(bufp, url_m_loc, value.c_str(), value.size()); + TSDebug(PLUGIN_NAME, "OperatorRMDestination::exec() deleting PATH"); + break; + case URL_QUAL_QUERY: + const_cast(res).changed_url = true; + TSUrlHttpQuerySet(bufp, url_m_loc, value.c_str(), value.size()); + TSDebug(PLUGIN_NAME, "OperatorRMDestination::exec() deleting QUERY"); + break; + case URL_QUAL_PORT: + const_cast(res).changed_url = true; + TSUrlPortSet(bufp, url_m_loc, 0); + TSDebug(PLUGIN_NAME, "OperatorRMDestination::exec() deleting PORT"); + break; + default: + TSDebug(PLUGIN_NAME, "RM Destination %i has no handler", _url_qual); + break; + } + } else { + TSDebug(PLUGIN_NAME, "OperatorRMDestination::exec() unable to continue due to missing bufp=%p or hdr_loc=%p, rri=%p!", res.bufp, + res.hdr_loc, res._rri); + } +} + // OperatorSetRedirect void OperatorSetRedirect::initialize(Parser &p) diff --git a/plugins/header_rewrite/operators.h b/plugins/header_rewrite/operators.h index f1d24fab342..c79bd614b38 100644 --- a/plugins/header_rewrite/operators.h +++ b/plugins/header_rewrite/operators.h @@ -113,6 +113,25 @@ class OperatorSetDestination : public Operator Value _value; }; +// All the header operators share a base class +class OperatorRMDestination : public Operator +{ +public: + OperatorRMDestination() { TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorRMDestination"); } + + // noncopyable + OperatorRMDestination(const OperatorRMDestination &) = delete; + void operator=(const OperatorRMDestination &) = delete; + + void initialize(Parser &p) override; + +protected: + void exec(const Resources &res) const override; + +private: + UrlQualifiers _url_qual = URL_QUAL_NONE; +}; + class OperatorSetRedirect : public Operator { public: