Skip to content

Commit fd6730e

Browse files
committed
add strategies api for getting a strategy during remap plugin init
1 parent 26574c5 commit fd6730e

File tree

7 files changed

+84
-39
lines changed

7 files changed

+84
-39
lines changed

include/proxy/http/remap/RemapConfig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ struct BUILD_TABLE_INFO {
7676
// noncopyable
7777
BUILD_TABLE_INFO(const BUILD_TABLE_INFO &) = delete; // disabled
7878
BUILD_TABLE_INFO &operator=(const BUILD_TABLE_INFO &) = delete; // disabled
79+
80+
// This is used to expose rewrite and its next hop strategy factory.
81+
inline static BUILD_TABLE_INFO *instance = nullptr;
7982
};
8083

8184
const char *remap_parse_directive(BUILD_TABLE_INFO *bti, char *errbuf, size_t errbufsize);

include/ts/ts.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,19 @@ void const *TSHttpTxnNextHopStrategyGet(TSHttpTxn txnp);
16161616
*/
16171617
char const *TSHttpNextHopStrategyNameGet(void const *strategy);
16181618

1619+
/**
1620+
Retrieves a pointer to the named strategy in the strategy table.
1621+
This can only be called during TSRemapNewInstance.
1622+
Returns nullptr if no strategy found.
1623+
This uses the current RemapInit NextHopStrategyFactory.
1624+
1625+
This strategy pointer can still be used by all following transactions.
1626+
1627+
@param name of the strategy to look up.
1628+
1629+
*/
1630+
void const *TSHttpInitNextHopNamedStrategyGet(const char *name);
1631+
16191632
/**
16201633
Retrieves a pointer to the named strategy in the strategy table.
16211634
Returns nullptr if no strategy is set.

plugins/header_rewrite/operators.cc

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,44 +1636,43 @@ void
16361636
OperatorSetNextHopStrategy::initialize(Parser &p)
16371637
{
16381638
Operator::initialize(p);
1639+
_stratname = p.get_arg();
16391640

1640-
_value.set_value(p.get_arg(), this);
1641-
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::initialie: %s", _value.get_value().c_str());
1641+
if (_stratname.empty() || "null" == _stratname) {
1642+
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::initialize: 'clear'");
1643+
} else {
1644+
_strategy = TSHttpInitNextHopNamedStrategyGet(_stratname.c_str());
1645+
if (nullptr == _strategy) {
1646+
TSWarning("[%s] Failed to get strategy '%s'", PLUGIN_NAME, _stratname.c_str());
1647+
_apply = false;
1648+
} else {
1649+
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::initialize: '%s'", _stratname.c_str());
1650+
}
1651+
}
16421652
}
16431653

16441654
void
16451655
OperatorSetNextHopStrategy::initialize_hooks()
16461656
{
1647-
add_allowed_hook(TS_HTTP_READ_REQUEST_HDR_HOOK);
16481657
add_allowed_hook(TS_REMAP_PSEUDO_HOOK);
16491658
}
16501659

16511660
bool
16521661
OperatorSetNextHopStrategy::exec(const Resources &res) const
16531662
{
1654-
if (!res.state.txnp) {
1655-
TSError("[%s] OperatorSetNextHopStrategy() failed. Transaction is null", PLUGIN_NAME);
1656-
}
1657-
1658-
auto const txnp = res.state.txnp;
1659-
1660-
std::string value;
1661-
_value.append_value(value, res);
1662-
1663-
// Setting an empty strategy clears it for either parent.config or remap to
1664-
if ("null" == value || value.empty()) {
1665-
Dbg(pi_dbg_ctl, "Clearing strategy");
1666-
TSHttpTxnNextHopStrategySet(txnp, nullptr);
1663+
if (!_apply) {
1664+
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::exec: do nothing");
16671665
return true;
16681666
}
1667+
auto const txnp = res.state.txnp;
16691668

1670-
void const *const stratptr = TSHttpTxnNextHopNamedStrategyGet(txnp, value.c_str());
1671-
if (nullptr == stratptr) {
1672-
TSWarning("[%s] Failed to get strategy '%s'", PLUGIN_NAME, value.c_str());
1669+
if (nullptr == _strategy) {
1670+
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::exec: Clearing strategy");
16731671
} else {
1674-
Dbg(pi_dbg_ctl, " Setting strategy '%s'", value.c_str());
1675-
TSHttpTxnNextHopStrategySet(txnp, stratptr);
1672+
Dbg(pi_dbg_ctl, "OperatorSetNextHopStrategy::exec: Setting strategy to '%s'", _stratname.c_str());
16761673
}
16771674

1675+
TSHttpTxnNextHopStrategySet(txnp, _strategy);
1676+
16781677
return true;
16791678
}

plugins/header_rewrite/operators.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,5 +668,7 @@ class OperatorSetNextHopStrategy : public Operator
668668
bool exec(const Resources &res) const override;
669669

670670
private:
671-
Value _value;
671+
bool _apply = true;
672+
std::string _stratname;
673+
void const *_strategy = nullptr;
672674
};

plugins/regex_remap/regex_remap.cc

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,17 @@ class RemapRegex
227227
return _lowercase_substitutions;
228228
}
229229
inline bool
230-
has_strategy() const
230+
has_strategy_option() const
231231
{
232232
return _has_strategy;
233233
}
234234
inline std::string const &
235-
strategy() const
235+
strategy_name_option() const
236+
{
237+
return _strategy_name;
238+
}
239+
inline void const *
240+
strategy_option() const
236241
{
237242
return _strategy;
238243
}
@@ -274,7 +279,8 @@ class RemapRegex
274279
int _dns_timeout = -1;
275280

276281
bool _has_strategy = false;
277-
std::string _strategy = {};
282+
std::string _strategy_name = {};
283+
void const *_strategy = nullptr;
278284

279285
Override *_first_override = nullptr;
280286
int _sub_pos[MAX_SUBS];
@@ -323,8 +329,15 @@ RemapRegex::initialize(const std::string &reg, const std::string &sub, const std
323329
} else if (opt.compare(start, 23, "lowercase_substitutions") == 0) {
324330
_lowercase_substitutions = true;
325331
} else if (opt.compare(start, 8, "strategy") == 0) {
326-
_has_strategy = true;
327-
_strategy = opt_val;
332+
_has_strategy = true;
333+
_strategy_name = opt_val;
334+
if (!_strategy_name.empty() && "null" != _strategy_name) {
335+
_strategy = TSHttpInitNextHopNamedStrategyGet(_strategy_name.c_str());
336+
if (nullptr == _strategy) {
337+
TSError("[%s] Unable to resolve strategy: '%s'", PLUGIN_NAME, opt_val.c_str());
338+
_has_strategy = false; // disable the strategy action
339+
}
340+
}
328341
} else if (opt_val.size() <= 0) {
329342
// All other options have a required value
330343
TSError("[%s] Malformed options: %s", PLUGIN_NAME, opt.c_str());
@@ -987,20 +1000,14 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
9871000
Dbg(dbg_ctl, "Setting DNS timeout to %d", re->dns_timeout_option());
9881001
TSHttpTxnDNSTimeoutSet(txnp, re->dns_timeout_option());
9891002
}
990-
if (re->has_strategy()) {
991-
auto const &strat = re->strategy();
992-
if (strat.empty() || "null" == strat) {
1003+
if (re->has_strategy_option()) {
1004+
auto const strat = re->strategy_option();
1005+
if (nullptr == strat) {
9931006
Dbg(dbg_ctl, "Clearing strategy (use parent.config)");
994-
TSHttpTxnNextHopStrategySet(txnp, nullptr);
9951007
} else {
996-
void const *const stratptr = TSHttpTxnNextHopNamedStrategyGet(txnp, strat.c_str());
997-
if (nullptr == stratptr) {
998-
Dbg(dbg_ctl, "No strategy found with name '%s'", strat.c_str());
999-
} else {
1000-
Dbg(dbg_ctl, "Setting strategy to %s", strat.c_str());
1001-
TSHttpTxnNextHopStrategySet(txnp, stratptr);
1002-
}
1008+
Dbg(dbg_ctl, "Setting strategy to %s", re->strategy_name_option().c_str());
10031009
}
1010+
TSHttpTxnNextHopStrategySet(txnp, strat);
10041011
}
10051012
bool lowercase_substitutions = false;
10061013
if (re->lowercase_substitutions_option() == true) {

src/api/InkAPI.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5044,6 +5044,24 @@ TSHttpTxnNextHopNamedStrategyGet(TSHttpTxn txnp, const char *name)
50445044
return static_cast<void const *>(strat);
50455045
}
50465046

5047+
void const *
5048+
TSHttpInitNextHopNamedStrategyGet(const char *name)
5049+
{
5050+
auto const bt = BUILD_TABLE_INFO::instance;
5051+
5052+
sdk_assert(sdk_sanity_check_null_ptr((void *)bt) == TS_SUCCESS);
5053+
sdk_assert(sdk_sanity_check_null_ptr((void *)bt->rewrite) == TS_SUCCESS);
5054+
sdk_assert(sdk_sanity_check_null_ptr((void *)bt->rewrite->strategyFactory) == TS_SUCCESS);
5055+
5056+
// HttpSM has a reference count handle to UrlRewrite which has a
5057+
// pointer to NextHopStrategyFactory
5058+
NextHopSelectionStrategy const *const strat = bt->rewrite->strategyFactory->strategyInstance(name);
5059+
5060+
fprintf(stderr, "strategy: %s, ptr: %p\n", name, (void *)strat);
5061+
5062+
return static_cast<void const *>(strat);
5063+
}
5064+
50475065
TSReturnCode
50485066
TSHttpTxnParentProxyGet(TSHttpTxn txnp, const char **hostname, int *port)
50495067
{

src/proxy/http/remap/RemapConfig.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,18 @@ clear_xstr_array(char *v[], size_t vsize)
9090
}
9191

9292
BUILD_TABLE_INFO::BUILD_TABLE_INFO()
93-
9493
{
9594
memset(this->paramv, 0, sizeof(this->paramv));
9695
memset(this->argv, 0, sizeof(this->argv));
96+
ink_assert(nullptr == BUILD_TABLE_INFO::instance);
97+
BUILD_TABLE_INFO::instance = this;
9798
}
9899

99100
BUILD_TABLE_INFO::~BUILD_TABLE_INFO()
100101
{
101102
this->reset();
103+
ink_assert(nullptr != BUILD_TABLE_INFO::instance);
104+
BUILD_TABLE_INFO::instance = nullptr;
102105
}
103106

104107
void

0 commit comments

Comments
 (0)