Skip to content

Commit 2fc1735

Browse files
authored
Refactor HRW matchers, add SETS (#12218)
1 parent 9ebd639 commit 2fc1735

13 files changed

Lines changed: 480 additions & 246 deletions

File tree

doc/admin-guide/plugins/header_rewrite.en.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,9 @@ Operand Description
722722
/regex/ Matches the condition's provided value against the regular
723723
expression. Start the regex with (?i) to flag it for a case
724724
insensitive match, e.g. /(?i)regex/ will match ReGeX.
725+
(x,y,z) Matches the condition's provided value against the list of
726+
comma-separated values. The list may be a list of strings, like
727+
``(mp3,m3u,m3u8)``, or a list of integers, like ``(301,302,307,308)``.
725728
<string Matches if the value from the condition is lexically less than
726729
*string*.
727730
>string Matches if the value from the condition is lexically greater than
@@ -1504,6 +1507,13 @@ already set to some value, and the status code is a 2xx::
15041507
cond %{STATUS} <300
15051508
set-header Cache-Control "max-age=600, public"
15061509

1510+
Add a response header for certain status codes
1511+
----------------------------------------------
1512+
1513+
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
1514+
cond %{STATUS} (301,302,307,308)
1515+
set-header X-Redirect-Status %{STATUS}
1516+
15071517
Add HSTS
15081518
--------
15091519

plugins/header_rewrite/condition.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ parse_matcher_op(std::string &arg)
6060
} else {
6161
return MATCH_ERROR;
6262
}
63+
case '(':
64+
arg.erase(0, 1);
65+
// There should be a right paren at the end
66+
if (arg.length() >= 1 && arg[arg.length() - 1] == ')') {
67+
arg.erase(arg.length() - 1, arg.length());
68+
return MATCH_SET;
69+
} else {
70+
return MATCH_ERROR;
71+
}
6372
default:
6473
return MATCH_EQUAL;
6574
break;

plugins/header_rewrite/conditions.cc

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ void
3939
ConditionStatus::initialize(Parser &p)
4040
{
4141
Condition::initialize(p);
42-
MatcherType *match = new MatcherType(_cond_op);
42+
auto *match = new MatcherType(_cond_op);
4343

44-
match->set(static_cast<TSHttpStatus>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
44+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType {
45+
auto status = Parser::parseNumeric<DataType>(s);
46+
if (status > 999) {
47+
throw std::runtime_error("Invalid status code: " + s);
48+
}
49+
return status;
50+
});
4551
_matcher = match;
4652

4753
require_resources(RSRC_SERVER_RESPONSE_HEADERS);
@@ -60,6 +66,7 @@ bool
6066
ConditionStatus::eval(const Resources &res)
6167
{
6268
Dbg(pi_dbg_ctl, "Evaluating STATUS()");
69+
6370
return static_cast<MatcherType *>(_matcher)->test(res.resp_status, res);
6471
}
6572

@@ -75,7 +82,7 @@ void
7582
ConditionMethod::initialize(Parser &p)
7683
{
7784
Condition::initialize(p);
78-
MatcherType *match = new MatcherType(_cond_op);
85+
auto *match = new MatcherType(_cond_op);
7986

8087
match->set(p.get_arg(), mods());
8188
_matcher = match;
@@ -117,13 +124,13 @@ ConditionRandom::initialize(Parser &p)
117124
{
118125
struct timeval tv;
119126
Condition::initialize(p);
120-
MatcherType *match = new MatcherType(_cond_op);
127+
auto *match = new MatcherType(_cond_op);
121128

122129
gettimeofday(&tv, nullptr);
123130
_seed = getpid() * tv.tv_usec;
124131
_max = strtol(_qualifier.c_str(), nullptr, 10);
125132

126-
match->set(static_cast<unsigned int>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
133+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
127134
_matcher = match;
128135
}
129136

@@ -190,7 +197,7 @@ void
190197
ConditionHeader::initialize(Parser &p)
191198
{
192199
Condition::initialize(p);
193-
MatcherType *match = new MatcherType(_cond_op);
200+
auto *match = new MatcherType(_cond_op);
194201

195202
match->set(p.get_arg(), mods());
196203
_matcher = match;
@@ -255,7 +262,7 @@ ConditionUrl::initialize(Parser &p)
255262
{
256263
Condition::initialize(p);
257264

258-
MatcherType *match = new MatcherType(_cond_op);
265+
auto *match = new MatcherType(_cond_op);
259266
match->set(p.get_arg(), mods());
260267
_matcher = match;
261268
}
@@ -369,7 +376,7 @@ ConditionDBM::initialize(Parser &p)
369376
{
370377
Condition::initialize(p);
371378

372-
MatcherType *match = new MatcherType(_cond_op);
379+
auto *match = new MatcherType(_cond_op);
373380
match->set(p.get_arg(), mods());
374381
_matcher = match;
375382

@@ -433,7 +440,7 @@ ConditionCookie::initialize(Parser &p)
433440
{
434441
Condition::initialize(p);
435442

436-
MatcherType *match = new MatcherType(_cond_op);
443+
auto *match = new MatcherType(_cond_op);
437444

438445
match->set(p.get_arg(), mods());
439446
_matcher = match;
@@ -512,13 +519,13 @@ ConditionIp::initialize(Parser &p)
512519
{
513520
Condition::initialize(p);
514521

515-
if (_cond_op == MATCH_IP_RANGES) { // Special hack for IP ranges for now ...
522+
if (_cond_op == MATCH_IP_RANGES) { // Special hack for IP ranges
516523
MatcherTypeIp *match = new MatcherTypeIp(_cond_op);
517524

518-
match->set(p.get_arg());
525+
match->set(p.get_arg(), mods(), [](const std::string & /*s*/) { return static_cast<const sockaddr *>(nullptr); });
519526
_matcher = match;
520527
} else {
521-
MatcherType *match = new MatcherType(_cond_op);
528+
auto *match = new MatcherType(_cond_op);
522529

523530
match->set(p.get_arg(), mods());
524531
_matcher = match;
@@ -615,10 +622,9 @@ void
615622
ConditionTransactCount::initialize(Parser &p)
616623
{
617624
Condition::initialize(p);
618-
MatcherType *match = new MatcherType(_cond_op);
619-
std::string const &arg = p.get_arg();
625+
auto *match = new MatcherType(_cond_op);
620626

621-
match->set(strtol(arg.c_str(), nullptr, 10), mods());
627+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
622628
_matcher = match;
623629
}
624630

@@ -706,9 +712,9 @@ ConditionNow::initialize(Parser &p)
706712
{
707713
Condition::initialize(p);
708714

709-
MatcherType *match = new MatcherType(_cond_op);
715+
auto *match = new MatcherType(_cond_op);
710716

711-
match->set(static_cast<int64_t>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
717+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
712718
_matcher = match;
713719
}
714720

@@ -776,9 +782,9 @@ ConditionGeo::initialize(Parser &p)
776782
Condition::initialize(p);
777783

778784
if (is_int_type()) {
779-
Matchers<int64_t> *match = new Matchers<int64_t>(_cond_op);
785+
auto *match = new Matchers<int64_t>(_cond_op);
780786

781-
match->set(static_cast<int64_t>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
787+
match->set(p.get_arg(), mods(), [](const std::string &s) -> int64_t { return Parser::parseNumeric<int64_t>(s); });
782788
_matcher = match;
783789
} else {
784790
// The default is to have a string matcher
@@ -854,9 +860,9 @@ ConditionId::initialize(Parser &p)
854860
Condition::initialize(p);
855861

856862
if (_id_qual == ID_QUAL_REQUEST) {
857-
Matchers<uint64_t> *match = new Matchers<uint64_t>(_cond_op);
863+
auto *match = new Matchers<uint64_t>(_cond_op);
858864

859-
match->set(static_cast<uint64_t>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
865+
match->set(p.get_arg(), mods(), [](const std::string &s) -> uint64_t { return Parser::parseNumeric<uint64_t>(s); });
860866
_matcher = match;
861867
} else {
862868
// The default is to have a string matcher
@@ -934,7 +940,7 @@ ConditionCidr::initialize(Parser &p)
934940
{
935941
Condition::initialize(p);
936942

937-
MatcherType *match = new MatcherType(_cond_op);
943+
auto *match = new MatcherType(_cond_op);
938944

939945
match->set(p.get_arg(), mods());
940946
_matcher = match;
@@ -1040,10 +1046,10 @@ ConditionInbound::initialize(Parser &p)
10401046
if (_cond_op == MATCH_IP_RANGES) { // Special hack for IP ranges for now ...
10411047
MatcherTypeIp *match = new MatcherTypeIp(_cond_op);
10421048

1043-
match->set(p.get_arg());
1049+
match->set(p.get_arg(), mods(), [](const std::string & /* s */) { return static_cast<const sockaddr *>(nullptr); });
10441050
_matcher = match;
10451051
} else {
1046-
MatcherType *match = new MatcherType(_cond_op);
1052+
auto *match = new MatcherType(_cond_op);
10471053

10481054
match->set(p.get_arg(), mods());
10491055
_matcher = match;
@@ -1212,10 +1218,9 @@ void
12121218
ConditionSessionTransactCount::initialize(Parser &p)
12131219
{
12141220
Condition::initialize(p);
1215-
MatcherType *match = new MatcherType(_cond_op);
1216-
std::string const &arg = p.get_arg();
1221+
auto *match = new MatcherType(_cond_op);
12171222

1218-
match->set(strtol(arg.c_str(), nullptr, 10), mods());
1223+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
12191224
_matcher = match;
12201225
}
12211226

@@ -1246,10 +1251,9 @@ ConditionTcpInfo::initialize(Parser &p)
12461251
{
12471252
Condition::initialize(p);
12481253
Dbg(pi_dbg_ctl, "Initializing TCP Info");
1249-
MatcherType *match = new MatcherType(_cond_op);
1250-
std::string const &arg = p.get_arg();
1254+
auto *match = new MatcherType(_cond_op);
12511255

1252-
match->set(strtol(arg.c_str(), nullptr, 10), mods());
1256+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
12531257
_matcher = match;
12541258
}
12551259

@@ -1318,7 +1322,7 @@ void
13181322
ConditionCache::initialize(Parser &p)
13191323
{
13201324
Condition::initialize(p);
1321-
MatcherType *match = new MatcherType(_cond_op);
1325+
auto *match = new MatcherType(_cond_op);
13221326

13231327
match->set(p.get_arg(), mods());
13241328
_matcher = match;
@@ -1367,7 +1371,7 @@ ConditionNextHop::initialize(Parser &p)
13671371
{
13681372
Condition::initialize(p);
13691373

1370-
MatcherType *match = new MatcherType(_cond_op);
1374+
auto *match = new MatcherType(_cond_op);
13711375
match->set(p.get_arg(), mods());
13721376
_matcher = match;
13731377
}
@@ -1475,9 +1479,9 @@ void
14751479
ConditionStateInt8::initialize(Parser &p)
14761480
{
14771481
Condition::initialize(p);
1478-
MatcherType *match = new MatcherType(_cond_op);
1482+
auto *match = new MatcherType(_cond_op);
14791483

1480-
match->set(static_cast<uint8_t>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
1484+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
14811485
_matcher = match;
14821486
}
14831487

@@ -1519,9 +1523,9 @@ void
15191523
ConditionStateInt16::initialize(Parser &p)
15201524
{
15211525
Condition::initialize(p);
1522-
MatcherType *match = new MatcherType(_cond_op);
1526+
auto *match = new MatcherType(_cond_op);
15231527

1524-
match->set(static_cast<uint16_t>(strtol(p.get_arg().c_str(), nullptr, 10)), mods());
1528+
match->set(p.get_arg(), mods(), [](const std::string &s) -> DataType { return Parser::parseNumeric<DataType>(s); });
15251529
_matcher = match;
15261530
}
15271531

0 commit comments

Comments
 (0)