From 4dc694c573c950f19220f988a101b9601dc4f677 Mon Sep 17 00:00:00 2001 From: Chris McFarlen Date: Thu, 14 Aug 2025 16:46:44 -0500 Subject: [PATCH 1/4] Add unit test for hrw --- plugins/header_rewrite/CMakeLists.txt | 6 ++ plugins/header_rewrite/header_rewrite.cc | 6 -- plugins/header_rewrite/matcher.cc | 12 ++- plugins/header_rewrite/matcher.h | 4 +- plugins/header_rewrite/matcher_tests.cc | 107 +++++++++++++++++++++++ 5 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 plugins/header_rewrite/matcher_tests.cc diff --git a/plugins/header_rewrite/CMakeLists.txt b/plugins/header_rewrite/CMakeLists.txt index e1a8ef7bc68..6218542ff54 100644 --- a/plugins/header_rewrite/CMakeLists.txt +++ b/plugins/header_rewrite/CMakeLists.txt @@ -57,6 +57,12 @@ if(BUILD_TESTING) if(maxminddb_FOUND) target_link_libraries(test_header_rewrite PRIVATE maxminddb::maxminddb) endif() + + add_executable(test_matcher matcher_tests.cc matcher.cc lulu.cc regex_helper.cc resources.cc) + add_test(NAME test_matcher COMMAND $) + + target_link_libraries(test_matcher PRIVATE catch2::catch2 ts::tsutil libswoc::libswoc PCRE::PCRE) + endif() verify_global_plugin(header_rewrite) verify_remap_plugin(header_rewrite) diff --git a/plugins/header_rewrite/header_rewrite.cc b/plugins/header_rewrite/header_rewrite.cc index 86f7bdf5291..9f5bdce815d 100644 --- a/plugins/header_rewrite/header_rewrite.cc +++ b/plugins/header_rewrite/header_rewrite.cc @@ -40,12 +40,6 @@ // Debugs namespace header_rewrite_ns { -const char PLUGIN_NAME[] = "header_rewrite"; -const char PLUGIN_NAME_DBG[] = "dbg_header_rewrite"; - -DbgCtl dbg_ctl{PLUGIN_NAME_DBG}; -DbgCtl pi_dbg_ctl{PLUGIN_NAME}; - std::once_flag initHRWLibs; PluginFactory plugin_factory; diff --git a/plugins/header_rewrite/matcher.cc b/plugins/header_rewrite/matcher.cc index 75faa6a2a12..38f4ef9f65d 100644 --- a/plugins/header_rewrite/matcher.cc +++ b/plugins/header_rewrite/matcher.cc @@ -21,11 +21,21 @@ limitations under the License. */ +#include "tsutil/DbgCtl.h" #include #include #include "matcher.h" +namespace header_rewrite_ns +{ +const char PLUGIN_NAME[] = "header_rewrite"; +const char PLUGIN_NAME_DBG[] = "dbg_header_rewrite"; + +DbgCtl dbg_ctl{PLUGIN_NAME_DBG}; +DbgCtl pi_dbg_ctl{PLUGIN_NAME}; +} // namespace header_rewrite_ns + static bool match_with_modifiers(std::string_view rhs, std::string_view lhs, CondModifiers mods) { @@ -116,7 +126,7 @@ Matchers::test(const sockaddr *const &addr, const Resources & if (ranges.contains(swoc::IPAddr(addr))) { if (pi_dbg_ctl.on()) { char text[INET6_ADDRSTRLEN]; - Dbg(pi_dbg_ctl, "Successfully found IP-range match on %s", getIP(addr, text)); + Dbg(dbg_ctl, "Successfully found IP-range match on %s", getIP(addr, text)); } return true; } diff --git a/plugins/header_rewrite/matcher.h b/plugins/header_rewrite/matcher.h index 3099b300f87..2aff7bd9a5e 100644 --- a/plugins/header_rewrite/matcher.h +++ b/plugins/header_rewrite/matcher.h @@ -361,13 +361,13 @@ template class Matchers : public Matcher test_reg(const std::string &t, const Resources &res) const { TSAssert(std::holds_alternative(_data)); - Dbg(pi_dbg_ctl, "Test regular expression against: %s (NOCASE = %s)", t.c_str(), + Dbg(header_rewrite_ns::dbg_ctl, "Test regular expression against: %s (NOCASE = %s)", t.c_str(), has_modifier(_mods, CondModifiers::MOD_NOCASE) ? "true" : "false"); const auto &re = std::get(_data); int count = re.regexMatch(t.c_str(), t.length(), const_cast(res).ovector); if (count > 0) { - Dbg(pi_dbg_ctl, "Successfully found regular expression match"); + Dbg(header_rewrite_ns::dbg_ctl, "Successfully found regular expression match"); const_cast(res).ovector_ptr = t.c_str(); const_cast(res).ovector_count = count; diff --git a/plugins/header_rewrite/matcher_tests.cc b/plugins/header_rewrite/matcher_tests.cc new file mode 100644 index 00000000000..b7e85741db4 --- /dev/null +++ b/plugins/header_rewrite/matcher_tests.cc @@ -0,0 +1,107 @@ +/** + @file Test for matcher.cc + + @section license License + + 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. +*/ + +#include "matcher.h" +#include "ts/apidefs.h" +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +int +_TSAssert(const char *, const char *, int) +{ + return 0; +} + +void +TSError(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); +} + +TSHttpStatus +TSHttpHdrStatusGet(TSMBuffer, TSMLoc) +{ + return TS_HTTP_STATUS_OK; +} + +TSReturnCode +TSHandleMLocRelease(TSMBuffer, TSMLoc, TSMLoc) +{ + return TS_SUCCESS; +} + +const char * +TSHttpHookNameLookup(TSHttpHookID) +{ + return nullptr; +} + +TSReturnCode +TSHttpTxnClientReqGet(TSHttpTxn, TSMBuffer *, TSMLoc *) +{ + return TS_SUCCESS; +} + +TSReturnCode +TSHttpTxnServerReqGet(TSHttpTxn, TSMBuffer *, TSMLoc *) +{ + return TS_SUCCESS; +} + +TSReturnCode +TSHttpTxnClientRespGet(TSHttpTxn, TSMBuffer *, TSMLoc *) +{ + return TS_SUCCESS; +} + +TSReturnCode +TSHttpTxnServerRespGet(TSHttpTxn, TSMBuffer *, TSMLoc *) +{ + return TS_SUCCESS; +} + +TEST_CASE("Matcher", "[plugins][header_rewrite]") +{ + Matchers foo(MATCH_EQUAL); + TSHttpTxn txn = nullptr; + TSCont c = nullptr; + Resources res(txn, c); + + foo.set("FOO", CondModifiers::MOD_NOCASE); + REQUIRE(foo.test("foo", res) == true); +} + +TEST_CASE("MatcherSet", "[plugins][header_rewrite]") +{ + Matchers foo(MATCH_SET); + TSHttpTxn txn = nullptr; + TSCont c = nullptr; + Resources res(txn, c); + + foo.set("foo, bar, baz", CondModifiers::MOD_NOCASE); + REQUIRE(foo.test("FOO", res) == true); +} From a52633e78d83dfc94fc630aef1743e5fa0f96163 Mon Sep 17 00:00:00 2001 From: Chris McFarlen Date: Thu, 14 Aug 2025 17:21:00 -0500 Subject: [PATCH 2/4] Add forward declarations to matcher.h --- plugins/header_rewrite/matcher.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/header_rewrite/matcher.h b/plugins/header_rewrite/matcher.h index 2aff7bd9a5e..de4cadbb17a 100644 --- a/plugins/header_rewrite/matcher.h +++ b/plugins/header_rewrite/matcher.h @@ -380,3 +380,11 @@ template class Matchers : public Matcher std::variant, swoc::IPRangeSet, regexHelper> _data; CondModifiers _mods = CondModifiers::NONE; }; + +// forward declare spcializations implemented in matcher.cc + +template <> bool Matchers::test_eq(const std::string &) const; + +template <> bool Matchers::test_set(const std::string &) const; + +template <> bool Matchers::test(const sockaddr *const &, const Resources &) const; From 776d4612dcb0bf57f4de2a8697868ec326f06eef Mon Sep 17 00:00:00 2001 From: Chris McFarlen Date: Thu, 14 Aug 2025 17:25:07 -0500 Subject: [PATCH 3/4] cleanup dbg --- plugins/header_rewrite/matcher.cc | 2 +- plugins/header_rewrite/matcher.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/header_rewrite/matcher.cc b/plugins/header_rewrite/matcher.cc index 38f4ef9f65d..f4aec365e1a 100644 --- a/plugins/header_rewrite/matcher.cc +++ b/plugins/header_rewrite/matcher.cc @@ -126,7 +126,7 @@ Matchers::test(const sockaddr *const &addr, const Resources & if (ranges.contains(swoc::IPAddr(addr))) { if (pi_dbg_ctl.on()) { char text[INET6_ADDRSTRLEN]; - Dbg(dbg_ctl, "Successfully found IP-range match on %s", getIP(addr, text)); + Dbg(pi_dbg_ctl, "Successfully found IP-range match on %s", getIP(addr, text)); } return true; } diff --git a/plugins/header_rewrite/matcher.h b/plugins/header_rewrite/matcher.h index de4cadbb17a..1a61b3e505d 100644 --- a/plugins/header_rewrite/matcher.h +++ b/plugins/header_rewrite/matcher.h @@ -361,13 +361,13 @@ template class Matchers : public Matcher test_reg(const std::string &t, const Resources &res) const { TSAssert(std::holds_alternative(_data)); - Dbg(header_rewrite_ns::dbg_ctl, "Test regular expression against: %s (NOCASE = %s)", t.c_str(), + Dbg(pi_dbg_ctl, "Test regular expression against: %s (NOCASE = %s)", t.c_str(), has_modifier(_mods, CondModifiers::MOD_NOCASE) ? "true" : "false"); const auto &re = std::get(_data); int count = re.regexMatch(t.c_str(), t.length(), const_cast(res).ovector); if (count > 0) { - Dbg(header_rewrite_ns::dbg_ctl, "Successfully found regular expression match"); + Dbg(pi_dbg_ctl, "Successfully found regular expression match"); const_cast(res).ovector_ptr = t.c_str(); const_cast(res).ovector_count = count; From 57a7f097cc788557ca2334a7f54a7bd5d0fad238 Mon Sep 17 00:00:00 2001 From: Chris McFarlen Date: Mon, 18 Aug 2025 11:48:08 -0500 Subject: [PATCH 4/4] Fix link issues --- plugins/header_rewrite/CMakeLists.txt | 2 +- plugins/header_rewrite/matcher_tests.cc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/header_rewrite/CMakeLists.txt b/plugins/header_rewrite/CMakeLists.txt index 6218542ff54..028b80bb404 100644 --- a/plugins/header_rewrite/CMakeLists.txt +++ b/plugins/header_rewrite/CMakeLists.txt @@ -61,7 +61,7 @@ if(BUILD_TESTING) add_executable(test_matcher matcher_tests.cc matcher.cc lulu.cc regex_helper.cc resources.cc) add_test(NAME test_matcher COMMAND $) - target_link_libraries(test_matcher PRIVATE catch2::catch2 ts::tsutil libswoc::libswoc PCRE::PCRE) + target_link_libraries(test_matcher PRIVATE catch2::catch2 ts::tscore libswoc::libswoc PCRE::PCRE) endif() verify_global_plugin(header_rewrite) diff --git a/plugins/header_rewrite/matcher_tests.cc b/plugins/header_rewrite/matcher_tests.cc index b7e85741db4..eb730bc4fd6 100644 --- a/plugins/header_rewrite/matcher_tests.cc +++ b/plugins/header_rewrite/matcher_tests.cc @@ -84,6 +84,8 @@ TSHttpTxnServerRespGet(TSHttpTxn, TSMBuffer *, TSMLoc *) return TS_SUCCESS; } +ClassAllocator mutexAllocator("mutexAllocator"); + TEST_CASE("Matcher", "[plugins][header_rewrite]") { Matchers foo(MATCH_EQUAL);