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