You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2013/10/23 23:18:02 UTC
git commit: TS-2226 Add support for a set-header operator.
Updated Branches:
refs/heads/master 22e33c53f -> 4bf36c8fd
TS-2226 Add support for a set-header operator.
This is an optimization over the old pattern of doing
rm-header Foo
add-header Foo "bar"
This also reorganizes the code a bit, to avoid so much
duplication.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/4bf36c8f
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/4bf36c8f
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/4bf36c8f
Branch: refs/heads/master
Commit: 4bf36c8fdfcb36a037289909c073a451b78aeeea
Parents: 22e33c5
Author: Leif Hedstrom <zw...@apache.org>
Authored: Sat Oct 19 16:00:01 2013 -0600
Committer: Leif Hedstrom <zw...@apache.org>
Committed: Wed Oct 23 15:16:38 2013 -0600
----------------------------------------------------------------------
CHANGES | 2 +
plugins/header_rewrite/factory.cc | 2 +
plugins/header_rewrite/operator.cc | 13 ++
plugins/header_rewrite/operator.h | 24 ++++
plugins/header_rewrite/operators.cc | 212 ++++++++++++++++++-------------
plugins/header_rewrite/operators.h | 96 ++++++++------
6 files changed, 222 insertions(+), 127 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 84b8e1b..c538af5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,8 @@
Changes with Apache Traffic Server 4.1.0
+ *) [TS-2226] Add a set-header operator for header_rewrite plugin.
+
*) [TS-2296] improve ConfigProcessor reference counting
*) [ TS-2295] update statvfs usage
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/plugins/header_rewrite/factory.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/factory.cc b/plugins/header_rewrite/factory.cc
index d20fa40..6c2cd9a 100644
--- a/plugins/header_rewrite/factory.cc
+++ b/plugins/header_rewrite/factory.cc
@@ -35,6 +35,8 @@ operator_factory(const std::string& op)
if (op == "rm-header") {
o = new OperatorRMHeader();
+ } else if (op == "set-header") {
+ o = new OperatorSetHeader();
} else if (op == "add-header") {
o = new OperatorAddHeader();
} else if (op == "set-status") {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/plugins/header_rewrite/operator.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operator.cc b/plugins/header_rewrite/operator.cc
index a5dffdd..77adbfd 100644
--- a/plugins/header_rewrite/operator.cc
+++ b/plugins/header_rewrite/operator.cc
@@ -15,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
+
//////////////////////////////////////////////////////////////////////////////////////////////
// operator.cc: Implementation of the operator base class
//
@@ -43,3 +44,15 @@ Operator::initialize(Parser& p) {
}
}
+
+void
+OperatorHeaders::initialize(Parser& p) {
+ Operator::initialize(p);
+
+ _header = p.get_arg();
+
+ require_resources(RSRC_SERVER_RESPONSE_HEADERS);
+ require_resources(RSRC_SERVER_REQUEST_HEADERS);
+ require_resources(RSRC_CLIENT_REQUEST_HEADERS);
+ require_resources(RSRC_CLIENT_RESPONSE_HEADERS);
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/plugins/header_rewrite/operator.h
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operator.h b/plugins/header_rewrite/operator.h
index f136290..6ef2e73 100644
--- a/plugins/header_rewrite/operator.h
+++ b/plugins/header_rewrite/operator.h
@@ -70,4 +70,28 @@ private:
OperModifiers _mods;
};
+
+///////////////////////////////////////////////////////////////////////////////
+// Base class for all Header based Operators, this is obviously also an
+// Operator interface.
+//
+class OperatorHeaders : public Operator
+{
+public:
+ OperatorHeaders()
+ : _header("")
+ {
+ TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorHeaders");
+ }
+
+ void initialize(Parser& p);
+
+protected:
+ std::string _header;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OperatorHeaders);
+};
+
+
#endif // __OPERATOR_H
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/plugins/header_rewrite/operators.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operators.cc b/plugins/header_rewrite/operators.cc
index 3775166..54c00d8 100644
--- a/plugins/header_rewrite/operators.cc
+++ b/plugins/header_rewrite/operators.cc
@@ -25,42 +25,10 @@
#include "operators.h"
-// OperatorRMHeader
-void
-OperatorRMHeader::initialize(Parser& p) {
- Operator::initialize(p);
-
- _header = p.get_arg();
-
- require_resources(RSRC_SERVER_RESPONSE_HEADERS);
- require_resources(RSRC_SERVER_REQUEST_HEADERS);
- require_resources(RSRC_CLIENT_REQUEST_HEADERS);
- require_resources(RSRC_CLIENT_RESPONSE_HEADERS);
-}
-
-
-void
-OperatorRMHeader::exec(const Resources& res) const
-{
- TSMLoc field_loc, tmp;
-
- if (res.bufp && res.hdr_loc) {
- TSDebug(PLUGIN_NAME, "OperatorRMHeader::exec() invoked on header %s", _header.c_str());
- field_loc = TSMimeHdrFieldFind(res.bufp, res.hdr_loc, _header.c_str(), _header.size());
- while (field_loc) {
- TSDebug(PLUGIN_NAME, "\tdeleting header %s", _header.c_str());
- tmp = TSMimeHdrFieldNextDup(res.bufp, res.hdr_loc, field_loc);
- TSMimeHdrFieldDestroy(res.bufp, res.hdr_loc, field_loc);
- TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
- field_loc = tmp;
- }
- }
-}
-
-
// OperatorSetStatus
void
-OperatorSetStatus::initialize(Parser& p) {
+OperatorSetStatus::initialize(Parser& p)
+{
Operator::initialize(p);
_status.set_value(p.get_arg());
@@ -79,7 +47,8 @@ OperatorSetStatus::initialize(Parser& p) {
void
-OperatorSetStatus::initialize_hooks() {
+OperatorSetStatus::initialize_hooks()
+{
add_allowed_hook(TS_HTTP_READ_RESPONSE_HDR_HOOK);
add_allowed_hook(TS_HTTP_SEND_RESPONSE_HDR_HOOK);
}
@@ -98,7 +67,8 @@ OperatorSetStatus::exec(const Resources& res) const
// OperatorSetStatusReason
void
-OperatorSetStatusReason::initialize(Parser& p) {
+OperatorSetStatusReason::initialize(Parser& p)
+{
Operator::initialize(p);
_reason.set_value(p.get_arg());
@@ -127,57 +97,11 @@ OperatorSetStatusReason::exec(const Resources& res) const {
}
-// OperatorAddHeader
-void
-OperatorAddHeader::initialize(Parser& p) {
- Operator::initialize(p);
-
- _header = p.get_arg();
- _value.set_value(p.get_value());
-
- require_resources(RSRC_SERVER_RESPONSE_HEADERS);
- require_resources(RSRC_SERVER_REQUEST_HEADERS);
- require_resources(RSRC_CLIENT_REQUEST_HEADERS);
- require_resources(RSRC_CLIENT_RESPONSE_HEADERS);
-}
-
-
-void
-OperatorAddHeader::exec(const Resources& res) const
-{
-// int IP = TSHttpTxnServerIPGet(res.txnp);
-// inet_ntop(AF_INET, &IP, buf, sizeof(buf));
- std::string value;
-
- _value.append_value(value, res);
-
- // Never set an empty header (I don't think that ever makes sense?)
- if (value.empty()) {
- TSDebug(PLUGIN_NAME, "Would set header %s to an empty value, skipping", _header.c_str());
- return;
- }
-
- if (res.bufp && res.hdr_loc) {
- TSDebug(PLUGIN_NAME, "OperatorAddHeader::exec() invoked on header %s: %s", _header.c_str(), value.c_str());
- TSMLoc field_loc;
-
- if (TS_SUCCESS == TSMimeHdrFieldCreateNamed(res.bufp, res.hdr_loc, _header.c_str(), _header.size(), &field_loc)) {
- if (TS_SUCCESS == TSMimeHdrFieldValueStringInsert(res.bufp, res.hdr_loc, field_loc, -1, value.c_str(), value.size())) {
- TSDebug(PLUGIN_NAME, " adding header %s", _header.c_str());
- //INKHttpHdrPrint(res.bufp, res.hdr_loc, reqBuff);
- TSMimeHdrFieldAppend(res.bufp, res.hdr_loc, field_loc);
- }
- TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
- }
-
- }
-}
-
-
/// TODO and XXX: These currently only support when running as remap plugin.
// OperatorSetDestination
void
-OperatorSetDestination::initialize(Parser& p) {
+OperatorSetDestination::initialize(Parser& p)
+{
Operator::initialize(p);
_url_qual = parse_url_qualifier(p.get_arg());
@@ -262,7 +186,8 @@ OperatorSetDestination::exec(const Resources& res) const
/// TODO and XXX: These currently only support when running as remap plugin.
// OperatorSetRedirect
void
-OperatorSetRedirect::initialize(Parser& p) {
+OperatorSetRedirect::initialize(Parser& p)
+{
Operator::initialize(p);
_status.set_value(p.get_arg());
@@ -328,7 +253,8 @@ OperatorSetRedirect::exec(const Resources& res) const
// OperatorSetTimeoutOut
void
-OperatorSetTimeoutOut::initialize(Parser& p) {
+OperatorSetTimeoutOut::initialize(Parser& p)
+{
Operator::initialize(p);
if (p.get_arg() == "active") {
@@ -377,3 +303,117 @@ OperatorSetTimeoutOut::exec(const Resources& res) const
}
}
+
+// OperatorRMHeader
+void
+OperatorRMHeader::exec(const Resources& res) const
+{
+ TSMLoc field_loc, tmp;
+
+ if (res.bufp && res.hdr_loc) {
+ TSDebug(PLUGIN_NAME, "OperatorRMHeader::exec() invoked on header %s", _header.c_str());
+ field_loc = TSMimeHdrFieldFind(res.bufp, res.hdr_loc, _header.c_str(), _header.size());
+ while (field_loc) {
+ TSDebug(PLUGIN_NAME, "\tdeleting header %s", _header.c_str());
+ tmp = TSMimeHdrFieldNextDup(res.bufp, res.hdr_loc, field_loc);
+ TSMimeHdrFieldDestroy(res.bufp, res.hdr_loc, field_loc);
+ TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
+ field_loc = tmp;
+ }
+ }
+}
+
+
+// OperatorAddHeader
+void
+OperatorAddHeader::initialize(Parser& p)
+{
+ OperatorHeaders::initialize(p);
+
+ _value.set_value(p.get_value());
+}
+
+void
+OperatorAddHeader::exec(const Resources& res) const
+{
+ std::string value;
+
+ _value.append_value(value, res);
+
+ // Never set an empty header (I don't think that ever makes sense?)
+ if (value.empty()) {
+ TSDebug(PLUGIN_NAME, "Would set header %s to an empty value, skipping", _header.c_str());
+ return;
+ }
+
+ if (res.bufp && res.hdr_loc) {
+ TSDebug(PLUGIN_NAME, "OperatorAddHeader::exec() invoked on header %s: %s", _header.c_str(), value.c_str());
+ TSMLoc field_loc;
+
+ if (TS_SUCCESS == TSMimeHdrFieldCreateNamed(res.bufp, res.hdr_loc, _header.c_str(), _header.size(), &field_loc)) {
+ if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(res.bufp, res.hdr_loc, field_loc, -1, value.c_str(), value.size())) {
+ TSDebug(PLUGIN_NAME, " adding header %s", _header.c_str());
+ TSMimeHdrFieldAppend(res.bufp, res.hdr_loc, field_loc);
+ }
+ TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
+ }
+ }
+}
+
+
+// OperatorSetHeader
+void
+OperatorSetHeader::initialize(Parser& p)
+{
+ OperatorHeaders::initialize(p);
+
+ _value.set_value(p.get_value());
+}
+
+void
+OperatorSetHeader::exec(const Resources& res) const
+{
+ std::string value;
+
+ _value.append_value(value, res);
+
+ // Never set an empty header (I don't think that ever makes sense?)
+ if (value.empty()) {
+ TSDebug(PLUGIN_NAME, "Would set header %s to an empty value, skipping", _header.c_str());
+ return;
+ }
+
+ if (res.bufp && res.hdr_loc) {
+ TSMLoc field_loc = TSMimeHdrFieldFind(res.bufp, res.hdr_loc, _header.c_str(), _header.size());
+
+ TSDebug(PLUGIN_NAME, "OperatorSetHeader::exec() invoked on header %s: %s", _header.c_str(), value.c_str());
+
+ if (!field_loc) {
+ // No existing header, so create one
+ if (TS_SUCCESS == TSMimeHdrFieldCreateNamed(res.bufp, res.hdr_loc, _header.c_str(), _header.size(), &field_loc)) {
+ if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(res.bufp, res.hdr_loc, field_loc, -1, value.c_str(), value.size())) {
+ TSDebug(PLUGIN_NAME, " adding header %s", _header.c_str());
+ TSMimeHdrFieldAppend(res.bufp, res.hdr_loc, field_loc);
+ }
+ TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
+ }
+ } else {
+ TSMLoc tmp = NULL;
+ bool first = true;
+
+ while (field_loc) {
+ if (first) {
+ first = false;
+ if (TS_SUCCESS == TSMimeHdrFieldValueStringSet(res.bufp, res.hdr_loc, field_loc, -1, value.c_str(), value.size())) {
+ TSDebug(PLUGIN_NAME, " overwriting header %s", _header.c_str());
+ }
+ } else {
+ TSMimeHdrFieldDestroy(res.bufp, res.hdr_loc, field_loc);
+ }
+ tmp = TSMimeHdrFieldNextDup(res.bufp, res.hdr_loc, field_loc);
+ TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
+ field_loc = tmp;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4bf36c8f/plugins/header_rewrite/operators.h
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operators.h b/plugins/header_rewrite/operators.h
index f43858f..a424f23 100644
--- a/plugins/header_rewrite/operators.h
+++ b/plugins/header_rewrite/operators.h
@@ -33,26 +33,6 @@
///////////////////////////////////////////////////////////////////////////////
// Operator declarations.
//
-class OperatorRMHeader : public Operator
-{
-public:
- OperatorRMHeader()
- : _header("")
- {
- TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorRMHeader");
- }
- void initialize(Parser& p);
-
-protected:
- void exec(const Resources& res) const;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(OperatorRMHeader);
-
- std::string _header;
-};
-
-
class OperatorSetStatus : public Operator
{
public:
@@ -96,27 +76,6 @@ private:
};
-class OperatorAddHeader : public Operator
-{
-public:
- OperatorAddHeader()
- : _header("")
- {
- TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorAddHeader");
- }
- void initialize(Parser& p);
-
-protected:
- void exec(const Resources& res) const;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(OperatorAddHeader);
-
- std::string _header;
- Value _value;
-};
-
-
class OperatorSetDestination : public Operator
{
public:
@@ -203,4 +162,59 @@ private:
};
+// All the header operators share a base class
+class OperatorRMHeader : public OperatorHeaders
+{
+public:
+ OperatorRMHeader()
+ {
+ TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorRMHeader");
+ }
+
+protected:
+ void exec(const Resources& res) const;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OperatorRMHeader);
+};
+
+
+class OperatorAddHeader : public OperatorHeaders
+{
+public:
+ OperatorAddHeader()
+ {
+ TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorAddHeader");
+ }
+ void initialize(Parser& p);
+
+protected:
+ void exec(const Resources& res) const;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OperatorAddHeader);
+
+ Value _value;
+};
+
+
+class OperatorSetHeader : public OperatorHeaders
+{
+public:
+ OperatorSetHeader()
+ {
+ TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for OperatorSetHeader");
+ }
+ void initialize(Parser& p);
+
+protected:
+ void exec(const Resources& res) const;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(OperatorSetHeader);
+
+ Value _value;
+};
+
+
#endif // __OPERATORS_H