Updated Branches: refs/heads/master 4bf36c8fd -> a3b07f9d4
TS-2228 Add a set-config operator This will allow a header_rewrite config to modify any of the overridable records.config settings. Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/a3b07f9d Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/a3b07f9d Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/a3b07f9d Branch: refs/heads/master Commit: a3b07f9d4c69bcbe5dab834a6a201184a097d39a Parents: 4bf36c8 Author: Leif Hedstrom <[email protected]> Authored: Sat Oct 19 20:28:32 2013 -0600 Committer: Leif Hedstrom <[email protected]> Committed: Wed Oct 23 15:41:09 2013 -0600 ---------------------------------------------------------------------- CHANGES | 2 + plugins/header_rewrite/README | 53 ++++++++++++++------------- plugins/header_rewrite/condition.cc | 2 +- plugins/header_rewrite/conditions.cc | 2 +- plugins/header_rewrite/factory.cc | 6 ++- plugins/header_rewrite/header_rewrite.cc | 14 +++---- plugins/header_rewrite/operators.cc | 51 ++++++++++++++++++++++++-- plugins/header_rewrite/operators.h | 24 ++++++++++++ plugins/header_rewrite/parser.cc | 4 +- plugins/header_rewrite/ruleset.cc | 4 +- plugins/header_rewrite/value.h | 9 ++++- 11 files changed, 124 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index c538af5..67976e1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,8 @@ Changes with Apache Traffic Server 4.1.0 + *) [TS-2228] Add a set-config operator for header_rewrite plugin. + *) [TS-2226] Add a set-header operator for header_rewrite plugin. *) [TS-2296] improve ConfigProcessor reference counting http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/README ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/README b/plugins/header_rewrite/README index ed6eeb0..4244e4a 100644 --- a/plugins/header_rewrite/README +++ b/plugins/header_rewrite/README @@ -12,11 +12,12 @@ Operators --------- The following operators are available: - rm-header header-name [flags] - add-header header <value> [flags] - set-status <status-code> [flags] - set-status-reason <value> [flags] - no-op [flags] + rm-header header-name [flags] + add-header header <value> [flags] + set-status <status-code> [flags] + set-status-reason <value> [flags] + set-config config <value> [flags] + no-op [flags] The following operator(s) currently only works when instantiating the plugin as a remap plugin: @@ -38,7 +39,7 @@ For example (as a remap rule): Operator flags -------------- - [L] Last rule, do not continue + [L] Last rule, do not continue Conditions @@ -46,22 +47,22 @@ Conditions The conditions are used as qualifiers: The operators specified will only be evaluated if the condition(s) are met. - cond %{STATUS} operand [flags] - cond %{RANDOM:nn} operand [flags] - cond %{ACCESS:file} [flags] - cond %{TRUE} [flags] - cond %{FALSE} [flags] - cond %{HEADER:header-name} operand [flags] - cond %{CLIENT-HEADER:header-name} operand [flags] - cond %{METHOD} operand [flags] - cond %{PROTOCOL} operand [flags] - cond %{PORT} operand [flags] - cond %{HOST} operand [flags] - cond %{TOHOST} operand [false] - cond %{FROMHOST} operand [false] - cond %{PATH} operand [false] - cond %{PARAMS} operand [false] - cond %{QUERY} operand [false] + cond %{STATUS} operand [flags] + cond %{RANDOM:nn} operand [flags] + cond %{ACCESS:file} [flags] + cond %{TRUE} [flags] + cond %{FALSE} [flags] + cond %{HEADER:header-name} operand [flags] + cond %{CLIENT-HEADER:header-name} operand [flags] + cond %{METHOD} operand [flags] + cond %{PROTOCOL} operand [flags] + cond %{PORT} operand [flags] + cond %{HOST} operand [flags] + cond %{TOHOST} operand [false] + cond %{FROMHOST} operand [false] + cond %{PATH} operand [false] + cond %{PARAMS} operand [false] + cond %{QUERY} operand [false] The difference between HEADER and CLIENT-HEADER is that HEADER adapts to the @@ -81,9 +82,9 @@ each rule. This implies that a new hook condition starts a new rule as well. Condition flags --------------- [NC] Not ase sensitive condition (when applicable) - [AND] AND with next condition (default) - [OR] OR with next condition - [NOT] Invert this condition + [AND] AND with next condition (default) + [OR] OR with next condition + [NOT] Invert this condition Operands to conditions @@ -112,7 +113,7 @@ Examples cond %{HEADER:X-Y-Foobar} cond %{METHOD} =GET [OR] cond %{METHOD} =POST -set-header X-Y-Fiefum %{HEADER:X-Y-Foobar} +add-header X-Y-Fiefum %{HEADER:X-Y-Foobar} rm-header X-Y-Foobar rm-header Set-Cookie http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/condition.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/condition.cc b/plugins/header_rewrite/condition.cc index 5180962..d7c05eb 100644 --- a/plugins/header_rewrite/condition.cc +++ b/plugins/header_rewrite/condition.cc @@ -60,7 +60,7 @@ Condition::initialize(Parser& p) if (p.mod_exist("OR")) { if (p.mod_exist("AND")) { - TSError("header_rewrite: Can't have both AND and OR in mods"); + TSError("%s: Can't have both AND and OR in mods", PLUGIN_NAME); } else { _mods = static_cast<CondModifiers>(_mods | COND_OR); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/conditions.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/conditions.cc b/plugins/header_rewrite/conditions.cc index 84ad1f0..6faac6f 100644 --- a/plugins/header_rewrite/conditions.cc +++ b/plugins/header_rewrite/conditions.cc @@ -332,7 +332,7 @@ ConditionDBM::initialize(Parser& p) // TSError("Failed to open DBM file: %s", _file.c_str()); // } } else { - TSError("Malformed DBM condition"); + TSError("%s: Malformed DBM condition", PLUGIN_NAME); } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/factory.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/factory.cc b/plugins/header_rewrite/factory.cc index 6c2cd9a..d7f0d6d 100644 --- a/plugins/header_rewrite/factory.cc +++ b/plugins/header_rewrite/factory.cc @@ -39,6 +39,8 @@ operator_factory(const std::string& op) o = new OperatorSetHeader(); } else if (op == "add-header") { o = new OperatorAddHeader(); + } else if (op == "set-config") { + o = new OperatorSetConfig(); } else if (op == "set-status") { o = new OperatorSetStatus(); } else if (op == "set-status-reason") { @@ -52,7 +54,7 @@ operator_factory(const std::string& op) } else if (op == "no-op") { o = new OperatorNoOp(); } else { - TSError("header_rewrite: unknown operator in header_rewrite: %s", op.c_str()); + TSError("%s:unknown operator in header_rewrite: %s", PLUGIN_NAME, op.c_str()); return NULL; } @@ -100,7 +102,7 @@ condition_factory(const std::string& cond) } else if (c_name == "DBM") { c = new ConditionDBM(); } else { - TSError("header_rewrite: unknown condition in header_rewrite: %s",c_name.c_str()); + TSError("%s: unknown condition in header_rewrite: %s", PLUGIN_NAME, c_name.c_str()); return NULL; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/header_rewrite.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/header_rewrite.cc b/plugins/header_rewrite/header_rewrite.cc index 20fd387..9d3dde0 100644 --- a/plugins/header_rewrite/header_rewrite.cc +++ b/plugins/header_rewrite/header_rewrite.cc @@ -82,7 +82,7 @@ parse_config(const std::string fname, TSHttpHookID default_hook) f.open(filename.c_str(), std::ios::in); if (!f.is_open()) { - TSError("header_rewrite: unable to open %s", filename.c_str()); + TSError("%s: unable to open %s", PLUGIN_NAME, filename.c_str()); return false; } @@ -181,7 +181,7 @@ cont_rewrite_headers(TSCont contp, TSEvent event, void *edata) hook = TS_HTTP_SEND_RESPONSE_HDR_HOOK; break; default: - TSError("header_rewrite: unknown event for this plugin"); + TSError("%s: unknown event for this plugin", PLUGIN_NAME); TSDebug(PLUGIN_NAME, "unknown event for this plugin"); break; } @@ -221,12 +221,12 @@ TSPluginInit(int argc, const char *argv[]) info.support_email = (char*)"[email protected]"; if (TS_SUCCESS != TSPluginRegister(TS_SDK_VERSION_3_0 , &info)) { - TSError("header_rewrite: plugin registration failed.\n"); + TSError("%s: plugin registration failed.\n", PLUGIN_NAME); } TSDebug(PLUGIN_NAME, "number of arguments: %d", argc); if (argc != 2) { - TSError("usage: %s <config-file>\n", argv[0] ); + TSError("%s usage: %s <config-file> ... \n", PLUGIN_NAME, argv[0]); assert(argc == 2); } @@ -245,7 +245,7 @@ TSPluginInit(int argc, const char *argv[]) } } } else { - TSError("header_rewrite: failed to parse configuration file"); + TSError("%s: failed to parse configuration file", PLUGIN_NAME); } } @@ -283,7 +283,7 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSE TSDebug(PLUGIN_NAME, "initializing the remap plugin header_rewrite"); if (argc < 3) { - TSError("Unable to create remap instance, need config file"); + TSError("%s: Unable to create remap instance, need config file", PLUGIN_NAME); return TS_ERROR; } @@ -291,7 +291,7 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSE // remap instantiation. all_rules[TS_REMAP_PSEUDO_HOOK] = NULL; if (!parse_config(argv[2], TS_REMAP_PSEUDO_HOOK)) { - TSError("Unable to create remap instance"); + TSError("%s: Unable to create remap instance", PLUGIN_NAME); return TS_ERROR; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/operators.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/operators.cc b/plugins/header_rewrite/operators.cc index 54c00d8..54ac221 100644 --- a/plugins/header_rewrite/operators.cc +++ b/plugins/header_rewrite/operators.cc @@ -25,6 +25,49 @@ #include "operators.h" +// OperatorConfig +void +OperatorSetConfig::initialize(Parser& p) { + Operator::initialize(p); + _config = p.get_arg(); + + if (TS_SUCCESS == TSHttpTxnConfigFind(_config.c_str(), _config.size(), &_key, &_type)) { + _value.set_value(p.get_value()); + } else { + _key = TS_CONFIG_NULL; + TSError("%s: no such records config: %s", PLUGIN_NAME, _config.c_str()); + } +} + + +void +OperatorSetConfig::exec(const Resources& res) const +{ + if (TS_CONFIG_NULL != _key) { + switch (_type) { + case TS_RECORDDATATYPE_INT: + if (TS_SUCCESS == TSHttpTxnConfigIntSet(res.txnp, _key, _value.get_int_value())) { + TSDebug(PLUGIN_NAME, "OperatorSetConfig::exec() invoked on %s=%d", _config.c_str(), _value.get_int_value()); + } + break; + case TS_RECORDDATATYPE_FLOAT: + if (TS_SUCCESS == TSHttpTxnConfigFloatSet(res.txnp, _key, _value.get_float_value())) { + TSDebug(PLUGIN_NAME, "OperatorSetConfig::exec() invoked on %s=%f", _config.c_str(), _value.get_float_value()); + } + break; + case TS_RECORDDATATYPE_STRING: + if (TS_SUCCESS == TSHttpTxnConfigStringSet(res.txnp, _key, _value.get_value().c_str(), _value.size())) { + TSDebug(PLUGIN_NAME, "OperatorSetConfig::exec() invoked on %s=%s", _config.c_str(), _value.get_value().c_str()); + } + break; + default: + TSError("%s: unknown data type, whut?", PLUGIN_NAME); + break; + } + } +} + + // OperatorSetStatus void OperatorSetStatus::initialize(Parser& p) @@ -34,7 +77,7 @@ OperatorSetStatus::initialize(Parser& p) _status.set_value(p.get_arg()); if (NULL == (_reason = TSHttpHdrReasonLookup((TSHttpStatus)_status.get_int_value()))) { - TSError("header_rewrite: unknown status %d", _status.get_int_value()); + TSError("%s: unknown status %d", PLUGIN_NAME, _status.get_int_value()); _reason_len = 0; } else { _reason_len = strlen(_reason); @@ -195,7 +238,7 @@ OperatorSetRedirect::initialize(Parser& p) if ((_status.get_int_value() != (int)TS_HTTP_STATUS_MOVED_PERMANENTLY) && (_status.get_int_value() != (int)TS_HTTP_STATUS_MOVED_TEMPORARILY)) { - TSError("header_rewrite: unsupported redirect status %d", _status.get_int_value()); + TSError("%s: unsupported redirect status %d", PLUGIN_NAME, _status.get_int_value()); } require_resources(RSRC_SERVER_RESPONSE_HEADERS); @@ -267,7 +310,7 @@ OperatorSetTimeoutOut::initialize(Parser& p) _type = TO_OUT_DNS; } else { _type = TO_OUT_UNDEFINED; - TSError("header_rewrite: unsupported timeout qualifier: %s", p.get_arg().c_str()); + TSError("%s: unsupported timeout qualifier: %s", PLUGIN_NAME, p.get_arg().c_str()); } _timeout.set_value(p.get_value()); @@ -298,7 +341,7 @@ OperatorSetTimeoutOut::exec(const Resources& res) const TSHttpTxnDNSTimeoutSet(res.txnp, _timeout.get_int_value()); break; default: - TSError("header_rewrite: unsupported timeout"); + TSError("%s: unsupported timeout", PLUGIN_NAME); break; } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/operators.h ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/operators.h b/plugins/header_rewrite/operators.h index a424f23..925b23e 100644 --- a/plugins/header_rewrite/operators.h +++ b/plugins/header_rewrite/operators.h @@ -33,6 +33,30 @@ /////////////////////////////////////////////////////////////////////////////// // Operator declarations. // +class OperatorSetConfig : public Operator +{ +public: + OperatorSetConfig() + : _key(TS_CONFIG_NULL), _type(TS_RECORDDATATYPE_NULL) + { + TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorSetConfig"); + } + void initialize(Parser& p); + +protected: + void exec(const Resources& res) const; + +private: + DISALLOW_COPY_AND_ASSIGN(OperatorSetConfig); + + TSOverridableConfigKey _key; + TSRecordDataType _type; + + std::string _config; + Value _value; +}; + + class OperatorSetStatus : public Operator { public: http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/parser.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/parser.cc b/plugins/header_rewrite/parser.cc index f354422..cdff4ee 100644 --- a/plugins/header_rewrite/parser.cc +++ b/plugins/header_rewrite/parser.cc @@ -54,7 +54,7 @@ Parser::preprocess(std::vector<std::string>& tokens) else _arg = ""; } else { - TSError("header_rewrite: conditions must be embraced in %%{}"); + TSError("%s: conditions must be embraced in %%{}", PLUGIN_NAME); return; } } else { @@ -87,7 +87,7 @@ Parser::preprocess(std::vector<std::string>& tokens) } } else { // Syntax error - TSError("header_rewrite: mods have to be embraced in []"); + TSError("%s: mods have to be embraced in []", PLUGIN_NAME); return; } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/ruleset.cc ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/ruleset.cc b/plugins/header_rewrite/ruleset.cc index 9b2d688..4a32c8b 100644 --- a/plugins/header_rewrite/ruleset.cc +++ b/plugins/header_rewrite/ruleset.cc @@ -48,7 +48,7 @@ RuleSet::add_condition(Parser& p) { TSDebug(PLUGIN_NAME, "Adding condition: %%{%s} with arg: %s\n", p.get_op().c_str(), p.get_arg().c_str()); c->initialize(p); if (!c->set_hook(_hook)) { - TSError("header_rewrite: can't use this condition in this hook"); + TSError("%s: can't use this condition in this hook", PLUGIN_NAME); return; } if (NULL == _cond) { @@ -73,7 +73,7 @@ RuleSet::add_operator(Parser& p) { TSDebug(PLUGIN_NAME, "Adding operator: %s(%s)\n", p.get_op().c_str(), p.get_arg().c_str()); o->initialize(p); if (!o->set_hook(_hook)) { - TSError("header_rewrite: can't use this operator in this hook"); + TSError("%s: can't use this operator in this hook", PLUGIN_NAME); return; } if (NULL == _oper) { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a3b07f9d/plugins/header_rewrite/value.h ---------------------------------------------------------------------- diff --git a/plugins/header_rewrite/value.h b/plugins/header_rewrite/value.h index 0c318fc..ef8c401 100644 --- a/plugins/header_rewrite/value.h +++ b/plugins/header_rewrite/value.h @@ -42,7 +42,7 @@ class Value : Statement { public: Value() - : _value(""), _int_value(-1), _cond_val(NULL) + : _value(""), _int_value(0), _float_value(0.0), _cond_val(NULL) { TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for Value"); }; @@ -58,8 +58,10 @@ public: if (_cond_val) { _cond_val->initialize(parser); } + } else { + _int_value = strtol(_value.c_str(), NULL, 10); + _float_value = strtod(_value.c_str(), NULL); } - _int_value = strtol(_value.c_str(), NULL, 10); } void @@ -72,7 +74,9 @@ public: } const std::string& get_value() const { return _value; } + size_t size() const { return _value.size(); } int get_int_value() const { return _int_value; } + double get_float_value() const { return _float_value; } bool empty() const { return _value.empty(); } @@ -81,6 +85,7 @@ private: std::string _value; int _int_value; + double _float_value; Condition* _cond_val; };
