Skip to content

Commit 88ed3af

Browse files
committed
hrw: Supports indexed query parameters as conds
1 parent f463c88 commit 88ed3af

5 files changed

Lines changed: 81 additions & 5 deletions

File tree

plugins/header_rewrite/conditions.cc

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <array>
3131
#include <atomic>
3232

33+
#include "swoc/TextView.h"
34+
3335
#include "ts/ts.h"
3436

3537
#include "conditions.h"
@@ -280,7 +282,26 @@ ConditionUrl::set_qualifier(const std::string &q)
280282
Condition::set_qualifier(q);
281283

282284
Dbg(pi_dbg_ctl, "\tParsing %%{URL:%s}", q.c_str());
283-
_url_qual = parse_url_qualifier(q);
285+
286+
std::string::size_type pos = q.find(':');
287+
288+
if (pos != std::string::npos) {
289+
std::string qual_part = q.substr(0, pos);
290+
std::string sub_qual = q.substr(pos + 1);
291+
292+
_url_qual = parse_url_qualifier(qual_part);
293+
294+
if (_url_qual == URL_QUAL_QUERY) {
295+
if (!sub_qual.empty()) {
296+
_query_param = sub_qual;
297+
Dbg(pi_dbg_ctl, "\tQuery parameter sub-key: %s", _query_param.c_str());
298+
}
299+
} else {
300+
TSError("[%s] Sub-qualifier not supported for URL component: %s", PLUGIN_NAME, qual_part.c_str());
301+
}
302+
} else {
303+
_url_qual = parse_url_qualifier(q);
304+
}
284305
}
285306

286307
void
@@ -347,8 +368,15 @@ ConditionUrl::append_value(std::string &s, const Resources &res)
347368
break;
348369
case URL_QUAL_QUERY:
349370
q_str = TSUrlHttpQueryGet(bufp, url, &i);
350-
s.append(q_str, i);
351-
Dbg(pi_dbg_ctl, " Query parameters to match is: %.*s", i, q_str);
371+
if (_query_param.empty()) {
372+
s.append(q_str, i);
373+
Dbg(pi_dbg_ctl, " Query parameters to match is: %.*s", i, q_str);
374+
} else {
375+
swoc::TextView value = res.get_query_param(_query_param, q_str, i);
376+
377+
s.append(value.data(), value.size());
378+
Dbg(pi_dbg_ctl, " Query parameter %s value is: %.*s", _query_param.c_str(), static_cast<int>(value.size()), value.data());
379+
}
352380
break;
353381
case URL_QUAL_SCHEME:
354382
q_str = TSUrlSchemeGet(bufp, url, &i);

plugins/header_rewrite/conditions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ class ConditionUrl : public Condition
300300
private:
301301
UrlQualifiers _url_qual = URL_QUAL_NONE;
302302
UrlType _type;
303+
std::string _query_param; // Optional: specific query parameter name for QUERY sub-key
303304
};
304305

305306
// DBM lookups

plugins/header_rewrite/operators.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ OperatorSetDestination::exec(const Resources &res) const
324324

325325
const_cast<Resources &>(res).changed_url = true;
326326
TSUrlHttpQuerySet(bufp, url_m_loc, value.c_str(), value.size());
327+
res.reset_query_cache();
327328
Dbg(pi_dbg_ctl, "OperatorSetDestination::exec() invoked with QUERY: %s", value.c_str());
328329
}
329330
break;
@@ -348,6 +349,7 @@ OperatorSetDestination::exec(const Resources &res) const
348349
if (TSUrlCreate(bufp, &new_url_loc) == TS_SUCCESS && TSUrlParse(bufp, new_url_loc, &start, end) == TS_PARSE_DONE &&
349350
TSHttpHdrUrlSet(bufp, res.hdr_loc, new_url_loc) == TS_SUCCESS) {
350351
const_cast<Resources &>(res).changed_url = true;
352+
res.reset_query_cache();
351353
Dbg(pi_dbg_ctl, "Set destination URL to %s", value.c_str());
352354
} else {
353355
Dbg(pi_dbg_ctl, "Failed to set URL %s", value.c_str());
@@ -461,6 +463,7 @@ OperatorRMDestination::exec(const Resources &res) const
461463
}
462464
const_cast<Resources &>(res).changed_url = true;
463465
TSUrlHttpQuerySet(bufp, url_m_loc, value.c_str(), value.size());
466+
res.reset_query_cache();
464467
break;
465468
case URL_QUAL_PORT:
466469
const_cast<Resources &>(res).changed_url = true;

plugins/header_rewrite/resources.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,32 @@ Resources::destroy()
181181

182182
_ready = false;
183183
}
184+
185+
swoc::TextView
186+
Resources::get_query_param(const std::string &name, const char *query_str, int query_len) const
187+
{
188+
if (!_extended_info.query_parsed) {
189+
if (query_str && query_len > 0) {
190+
swoc::TextView query_view(query_str, query_len);
191+
192+
while (!query_view.empty()) {
193+
swoc::TextView param = query_view.take_prefix_at('&');
194+
swoc::TextView param_name = param.take_prefix_at('=');
195+
swoc::TextView param_value = param;
196+
197+
if (!param_name.empty()) {
198+
_extended_info.query_params[param_name] = param_value;
199+
}
200+
}
201+
}
202+
_extended_info.query_parsed = true;
203+
}
204+
205+
auto it = _extended_info.query_params.find(swoc::TextView(name));
206+
207+
if (it != _extended_info.query_params.end()) {
208+
return it->second;
209+
}
210+
211+
return swoc::TextView();
212+
}

plugins/header_rewrite/resources.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#pragma once
2323

2424
#include <string>
25+
#include <unordered_map>
26+
27+
#include "swoc/TextView.h"
2528

2629
#include "regex_helper.h"
2730
#include "ts/ts.h"
@@ -96,6 +99,16 @@ class Resources
9699
return _extended_info.matches;
97100
}
98101

102+
// Get a query parameter value by name, with caching
103+
swoc::TextView get_query_param(const std::string &name, const char *query_str, int query_len) const;
104+
105+
void
106+
reset_query_cache() const
107+
{
108+
_extended_info.query_params.clear();
109+
_extended_info.query_parsed = false;
110+
}
111+
99112
TSCont contp = nullptr;
100113
TSRemapRequestInfo *_rri = nullptr;
101114
TSMBuffer bufp = nullptr;
@@ -114,8 +127,10 @@ class Resources
114127
TSHttpStatus resp_status = TS_HTTP_STATUS_NONE;
115128

116129
struct LifetimeExtension {
117-
std::string subject_storage;
118-
RegexMatches matches;
130+
std::string subject_storage;
131+
RegexMatches matches;
132+
std::unordered_map<swoc::TextView, swoc::TextView> query_params;
133+
bool query_parsed = false;
119134
};
120135
bool changed_url = false;
121136
mutable LifetimeExtension _extended_info;

0 commit comments

Comments
 (0)