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/11/13 22:55:45 UTC
[20/50] [abbrv] git commit: TS-2316: header_rewrite: added variable
expansion support to add-header
TS-2316: header_rewrite: added variable expansion support to add-header
Submitted by: Thomas Jackson <th...@linkedin.com>
Sponsored by: LinkedIn
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/3f4e1c74
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/3f4e1c74
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/3f4e1c74
Branch: refs/heads/5.0.x
Commit: 3f4e1c74527f5ecaed0b9f1d116ba29dd6c419f5
Parents: 236c52c
Author: Alexey Ivanov <ai...@linkedin.com>
Authored: Mon Nov 4 20:29:19 2013 -0800
Committer: Alexey Ivanov <ai...@linkedin.com>
Committed: Sun Nov 10 18:07:53 2013 -0800
----------------------------------------------------------------------
plugins/header_rewrite/operator.h | 137 +++++++++++++++++++++++++++++++
plugins/header_rewrite/operators.cc | 3 +
2 files changed, 140 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f4e1c74/plugins/header_rewrite/operator.h
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operator.h b/plugins/header_rewrite/operator.h
index aba2f11..5c24925 100644
--- a/plugins/header_rewrite/operator.h
+++ b/plugins/header_rewrite/operator.h
@@ -29,6 +29,9 @@
#include "statement.h"
#include "parser.h"
+#include <iostream>
+#include <arpa/inet.h>
+#include <sstream>
// Operator modifiers
enum OperModifiers {
@@ -94,4 +97,138 @@ private:
};
+class VariableExpander {
+private:
+ std::string _source;
+public:
+ VariableExpander(const std::string &source) :
+ _source(source) {
+ }
+
+ std::string expand(const Resources& res) {
+ std::string result;
+ result.reserve(512); // TODO: Can be optimized
+ result.assign(_source);
+
+ while (true) {
+ std::string::size_type start = result.find("%<");
+ if (start == std::string::npos)
+ break;
+
+ std::string::size_type end = result.find(">", start);
+ if (end == std::string::npos)
+ break;
+
+ std::string first_part = result.substr(0, start);
+ std::string last_part = result.substr(end + 1);
+
+ // Now evaluate the variable
+ std::string variable = result.substr(start, end - start + 1);
+
+ // This will be the value to replace the "variable" section of the string with
+ std::string resolved_variable = "";
+
+ // Initialize some stuff
+ TSMBuffer bufp;
+ TSMLoc hdr_loc;
+ TSMLoc url_loc;
+
+ if (variable == "%<proto>") {
+ // Protocol of the incoming request
+ if (TSHttpTxnPristineUrlGet(res.txnp, &bufp, &url_loc) == TS_SUCCESS) {
+ int len;
+ resolved_variable = TSUrlSchemeGet(bufp, url_loc, &len);
+ }
+ } else if (variable == "%<port>") {
+ // Original port of the incoming request
+ if (TSHttpTxnClientReqGet(res.txnp, &bufp, &hdr_loc) == TS_SUCCESS) {
+ if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) == TS_SUCCESS) {
+ std::stringstream out;
+ out << TSUrlPortGet(bufp, url_loc);
+ resolved_variable = out.str();
+ TSHandleMLocRelease(bufp, hdr_loc, url_loc);
+ }
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+ }
+ } else if (variable == "%<chi>") {
+ // IP address of the client's host machine
+ resolved_variable = getIP(TSHttpTxnClientAddrGet(res.txnp));
+ } else if (variable == "%<cqhl>") {
+ // The client request header length; the header length in the client request to Traffic Server.
+ std::stringstream out;
+ out << TSHttpHdrLengthGet(res.client_bufp, res.client_hdr_loc);
+ resolved_variable = out.str();
+ } else if (variable == "%<cqhm>") {
+ // The HTTP method in the client request to Traffic Server: GET, POST, and so on (subset of cqtx).
+ int method_len;
+ const char *methodp = TSHttpHdrMethodGet(res.client_bufp, res.client_hdr_loc, &method_len);
+ if (methodp && method_len) {
+ resolved_variable.assign(methodp, method_len);
+ }
+ } else if (variable == "%<cquup>") {
+ // The client request unmapped URL path. This field records a URL path
+ // before it is remapped (reverse proxy mode).
+ if (TSHttpTxnPristineUrlGet(res.txnp, &bufp, &url_loc) == TS_SUCCESS) {
+ int path_len;
+ const char *path = TSUrlPathGet(bufp, url_loc, &path_len);
+
+ if (path && path_len) {
+ resolved_variable.assign(path, path_len);
+ }
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc);
+ }
+ }
+
+ // TODO(SaveTheRbtz): Can be optimized
+ result.assign(first_part);
+ result.append(resolved_variable);
+ result.append(last_part);
+ }
+
+ return result;
+ }
+
+private:
+ std::string getIP(sockaddr const * s_sockaddr) {
+ const struct sockaddr_in *s_sockaddr_in;
+ const struct sockaddr_in6 *s_sockaddr_in6;
+
+ if (s_sockaddr == NULL)
+ return "";
+
+ char res[INET6_ADDRSTRLEN] = { '\0' };
+
+ switch (s_sockaddr->sa_family) {
+ case AF_INET:
+ s_sockaddr_in = reinterpret_cast<const struct sockaddr_in *>(s_sockaddr);
+ inet_ntop(s_sockaddr_in->sin_family, &s_sockaddr_in->sin_addr, res, INET_ADDRSTRLEN);
+ break;
+ case AF_INET6:
+ s_sockaddr_in6 = reinterpret_cast<const struct sockaddr_in6 *>(s_sockaddr);
+ inet_ntop(s_sockaddr_in6->sin6_family, &s_sockaddr_in6->sin6_addr, res, INET6_ADDRSTRLEN);
+ break;
+ }
+
+ return std::string(res);
+ }
+
+ std::string getURL(const Resources& res) {
+ TSMBuffer bufp;
+ TSMLoc url_loc;
+
+ if (TSHttpTxnPristineUrlGet(res.txnp, &bufp, &url_loc) != TS_SUCCESS)
+ return "";
+
+ int url_len;
+ char *url = TSUrlStringGet(bufp, url_loc, &url_len);
+ std::string ret;
+ if (url && url_len)
+ ret.assign(url, url_len);
+ TSfree(url);
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc);
+
+ return ret;
+ }
+};
+
#endif // __OPERATOR_H
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f4e1c74/plugins/header_rewrite/operators.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/operators.cc b/plugins/header_rewrite/operators.cc
index 69c6bec..881e058 100644
--- a/plugins/header_rewrite/operators.cc
+++ b/plugins/header_rewrite/operators.cc
@@ -384,6 +384,9 @@ OperatorAddHeader::exec(const Resources& res) const
{
std::string value;
+ VariableExpander ve(value);
+ value = ve.expand(res);
+
_value.append_value(value, res);
// Never set an empty header (I don't think that ever makes sense?)