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 2016/03/07 23:17:24 UTC
trafficserver git commit: TS-2642 Adds a new operator %{NOW} to
header_rewrite
Repository: trafficserver
Updated Branches:
refs/heads/master 91a8444a5 -> 0792a4a3d
TS-2642 Adds a new operator %{NOW} to header_rewrite
This can be used to make time based decisions, such as denying
requests prior to a certain date. Or changing QOS settings based
on time of day.
This closes #517
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/0792a4a3
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/0792a4a3
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/0792a4a3
Branch: refs/heads/master
Commit: 0792a4a3de317ce2977f1cdcc62801e563601428
Parents: 91a8444
Author: Leif Hedstrom <zw...@apache.org>
Authored: Fri Jan 22 12:15:03 2016 -0700
Committer: Leif Hedstrom <zw...@apache.org>
Committed: Mon Mar 7 15:14:32 2016 -0700
----------------------------------------------------------------------
doc/admin-guide/plugins/header_rewrite.en.rst | 20 ++++++
plugins/header_rewrite/Examples/Now | 10 +++
plugins/header_rewrite/conditions.cc | 67 +++++++++++++++----
plugins/header_rewrite/conditions.h | 19 ++++++
plugins/header_rewrite/factory.cc | 5 +-
plugins/header_rewrite/statement.cc | 77 +++++++++++++++++++++-
plugins/header_rewrite/statement.h | 18 ++++-
7 files changed, 199 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/doc/admin-guide/plugins/header_rewrite.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/header_rewrite.en.rst b/doc/admin-guide/plugins/header_rewrite.en.rst
index 4e2f18e..8100c41 100644
--- a/doc/admin-guide/plugins/header_rewrite.en.rst
+++ b/doc/admin-guide/plugins/header_rewrite.en.rst
@@ -264,6 +264,26 @@ METHOD
The HTTP method (e.g. ``GET``, ``HEAD``, ``POST``, and so on) used by the
client for this transaction.
+NOW
+~~~
+::
+
+ cond %{NOW} >1453484915
+
+This is the current time, in the local timezone as set on the machine,
+typically GMC. Without any further qualifiers, this is the time in seconds
+since EPOCH aka Unix time. Qualifiers can be used to give various other
+values, such as year, month etc.
+::
+
+ %{NOW:YEAR} Current year (e.g. 2016)
+ %{NOW:MONTH} Current month (0-11, 0 == January)
+ %{NOW:DAY} Current day of the month (1-31)
+ %{NOW:HOUR} Current hour (0-23, in the 24h system)
+ %{NOW:MIN} Current minute (0-59}
+ %{NOW:WEEKDAY} Current weekday (0-6, 0 == Sunday)
+ %{NOW:YEARDAY} Current day of the year (0-365, 0 == Jan 1st)
+
PATH
~~~~
::
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/Examples/Now
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/Examples/Now b/plugins/header_rewrite/Examples/Now
new file mode 100644
index 0000000..09a33bd
--- /dev/null
+++ b/plugins/header_rewrite/Examples/Now
@@ -0,0 +1,10 @@
+cond %{SEND_RESPONSE_HDR_HOOK} [AND]
+cond %{NOW} >1453484915
+ set-header X-Now %{NOW}
+ set-header X-Now-Year %{NOW:YEAR}
+ set-header X-Now-Month %{NOW:MONTH}
+ set-header X-Now-Day %{NOW:DAY}
+ set-header X-Now-Hour %{NOW:HOUR}
+ set-header X-Now-Min %{NOW:MINUTE}
+ set-header X-Now-WEEKDAY %{NOW:WEEKDAY}
+ set-header X-Now-YEARDAY %{NOW:YEARDAY}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/conditions.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/conditions.cc b/plugins/header_rewrite/conditions.cc
index 0f22400..4e6f29e 100644
--- a/plugins/header_rewrite/conditions.cc
+++ b/plugins/header_rewrite/conditions.cc
@@ -34,7 +34,6 @@ void
ConditionStatus::initialize(Parser &p)
{
Condition::initialize(p);
-
Matchers<TSHttpStatus> *match = new Matchers<TSHttpStatus>(_cond_op);
match->set(static_cast<TSHttpStatus>(strtol(p.get_arg().c_str(), NULL, 10)));
@@ -77,8 +76,8 @@ void
ConditionMethod::initialize(Parser &p)
{
Condition::initialize(p);
-
Matchers<std::string> *match = new Matchers<std::string>(_cond_op);
+
match->set(p.get_arg());
_matcher = match;
@@ -120,12 +119,10 @@ void
ConditionRandom::initialize(Parser &p)
{
struct timeval tv;
-
Condition::initialize(p);
+ Matchers<unsigned int> *match = new Matchers<unsigned int>(_cond_op);
gettimeofday(&tv, NULL);
-
- Matchers<unsigned int> *match = new Matchers<unsigned int>(_cond_op);
_seed = getpid() * tv.tv_usec;
_max = strtol(_qualifier.c_str(), NULL, 10);
@@ -146,6 +143,7 @@ void
ConditionRandom::append_value(std::string &s, const Resources & /* res ATS_UNUSED */)
{
std::ostringstream oss;
+
oss << rand_r(&_seed) % _max;
s += oss.str();
TSDebug(PLUGIN_NAME, "Appending RANDOM(%d) to evaluation value -> %s", _max, s.c_str());
@@ -157,7 +155,6 @@ void
ConditionAccess::initialize(Parser &p)
{
struct timeval tv;
-
Condition::initialize(p);
gettimeofday(&tv, NULL);
@@ -206,10 +203,9 @@ void
ConditionHeader::initialize(Parser &p)
{
Condition::initialize(p);
-
Matchers<std::string> *match = new Matchers<std::string>(_cond_op);
- match->set(p.get_arg());
+ match->set(p.get_arg());
_matcher = match;
require_resources(RSRC_CLIENT_REQUEST_HEADERS);
@@ -256,7 +252,6 @@ ConditionHeader::append_value(std::string &s, const Resources &res)
}
}
-
bool
ConditionHeader::eval(const Resources &res)
{
@@ -268,15 +263,15 @@ ConditionHeader::eval(const Resources &res)
return rval;
}
+
// ConditionPath
void
ConditionPath::initialize(Parser &p)
{
Condition::initialize(p);
-
Matchers<std::string> *match = new Matchers<std::string>(_cond_op);
- match->set(p.get_arg());
+ match->set(p.get_arg());
_matcher = match;
}
@@ -308,13 +303,14 @@ ConditionPath::eval(const Resources &res)
return static_cast<const Matchers<std::string> *>(_matcher)->test(s);
}
+
// ConditionQuery
void
ConditionQuery::initialize(Parser &p)
{
Condition::initialize(p);
-
Matchers<std::string> *match = new Matchers<std::string>(_cond_op);
+
match->set(p.get_arg());
_matcher = match;
}
@@ -324,6 +320,7 @@ ConditionQuery::append_value(std::string &s, const Resources &res)
{
int query_len = 0;
const char *query = TSUrlHttpQueryGet(res._rri->requestBufp, res._rri->requestUrl, &query_len);
+
TSDebug(PLUGIN_NAME, "Appending QUERY to evaluation value: %.*s", query_len, query);
s.append(query, query_len);
}
@@ -360,6 +357,7 @@ ConditionUrl::set_qualifier(const std::string &q)
{
Condition::set_qualifier(q);
+ TSDebug(PLUGIN_NAME, "\tParsing %%{URL:%s}", q.c_str());
_url_qual = parse_url_qualifier(q);
}
@@ -623,6 +621,7 @@ ConditionIncomingPort::append_value(std::string &s, const Resources &res)
TSDebug(PLUGIN_NAME, "Appending %d to evaluation value -> %s", port, s.c_str());
}
+
// ConditionTransactCount
void
ConditionTransactCount::initialize(Parser &p)
@@ -666,3 +665,47 @@ ConditionTransactCount::append_value(std::string &s, Resources const &res)
}
}
}
+
+
+// ConditionNow: time related conditions, such as time since epoch (default), hour, day etc.
+void
+ConditionNow::initialize(Parser &p)
+{
+ Condition::initialize(p);
+ Matchers<int64_t> *match = new Matchers<int64_t>(_cond_op);
+
+ match->set(static_cast<unsigned int64_t>(strtol(p.get_arg().c_str(), NULL, 10)));
+ _matcher = match;
+}
+
+
+void
+ConditionNow::set_qualifier(const std::string &q)
+{
+ Condition::set_qualifier(q);
+
+ TSDebug(PLUGIN_NAME, "\tParsing %%{NOW:%s} qualifier", q.c_str());
+ _now_qual = parse_now_qualifier(q);
+}
+
+
+void
+ConditionNow::append_value(std::string &s, const Resources & /* res ATS_UNUSED */)
+{
+ std::ostringstream oss;
+
+ oss << get_now_qualified(_now_qual);
+ s += oss.str();
+ TSDebug(PLUGIN_NAME, "Appending NOW() to evaluation value -> %s", s.c_str());
+}
+
+
+bool
+ConditionNow::eval(const Resources &res)
+{
+ int64_t now = get_now_qualified(_now_qual);
+
+ TSDebug(PLUGIN_NAME, "Evaluating NOW() -> %" PRId64, now);
+
+ return static_cast<const Matchers<int64_t> *>(_matcher)->test(now);
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/conditions.h
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/conditions.h b/plugins/header_rewrite/conditions.h
index c905da5..5a77907 100644
--- a/plugins/header_rewrite/conditions.h
+++ b/plugins/header_rewrite/conditions.h
@@ -392,4 +392,23 @@ private:
DISALLOW_COPY_AND_ASSIGN(ConditionTransactCount);
};
+// now: Keeping track of current time / day / hour etc.
+class ConditionNow : public Condition
+{
+public:
+ explicit ConditionNow() : _now_qual(NOW_QUAL_EPOCH) { TSDebug(PLUGIN_NAME_DBG, "Calling CTOR for ConditionNow"); };
+
+ void initialize(Parser &p);
+ void set_qualifier(const std::string &q);
+ void append_value(std::string &s, const Resources &res);
+
+protected:
+ bool eval(const Resources &res);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ConditionNow);
+ NowQualifiers _now_qual;
+};
+
+
#endif // __CONDITIONS_H
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/factory.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/factory.cc b/plugins/header_rewrite/factory.cc
index be1225b..1c6a901 100644
--- a/plugins/header_rewrite/factory.cc
+++ b/plugins/header_rewrite/factory.cc
@@ -127,13 +127,16 @@ condition_factory(const std::string &cond)
c = new ConditionMethod();
} else if (c_name == "TXN-COUNT") {
c = new ConditionTransactCount();
+ } else if (c_name == "NOW") {
+ c = new ConditionNow();
} else {
TSError("[%s] Unknown condition: %s", PLUGIN_NAME, c_name.c_str());
return NULL;
}
- if (c_qual != "")
+ if (c_qual != "") {
c->set_qualifier(c_qual);
+ }
return c;
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/statement.cc
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/statement.cc b/plugins/header_rewrite/statement.cc
index 5ef247f..e6c3f58 100644
--- a/plugins/header_rewrite/statement.cc
+++ b/plugins/header_rewrite/statement.cc
@@ -19,8 +19,6 @@
// statement.cc: Implementation of the statement base class.
//
//
-#include "ts/ts.h"
-
#include "statement.h"
void
@@ -74,10 +72,55 @@ Statement::initialize_hooks()
add_allowed_hook(TS_REMAP_PSEUDO_HOOK);
}
+// Time related functionality for statements. We return an int64_t here, to assure that
+// gettimeofday() / Epoch does not lose bits.
+int64_t
+Statement::get_now_qualified(NowQualifiers qual) const
+{
+ time_t now;
+
+ // First short circuit for the Epoch qualifier, since it needs less data
+ time(&now);
+ if (NOW_QUAL_EPOCH == qual) {
+ return static_cast<int64_t>(now);
+ } else {
+ struct tm res;
+
+ localtime_r(&now, &res);
+ switch (qual) {
+ case NOW_QUAL_EPOCH:
+ TSReleaseAssert(!"EPOCH should have been handled before");
+ break;
+ case NOW_QUAL_YEAR:
+ return static_cast<int64_t>(res.tm_year + 1900); // This makes more sense
+ break;
+ case NOW_QUAL_MONTH:
+ return static_cast<int64_t>(res.tm_mon);
+ break;
+ case NOW_QUAL_DAY:
+ return static_cast<int64_t>(res.tm_mday);
+ break;
+ case NOW_QUAL_HOUR:
+ return static_cast<int64_t>(res.tm_hour);
+ break;
+ case NOW_QUAL_MINUTE:
+ return static_cast<int64_t>(res.tm_min);
+ break;
+ case NOW_QUAL_WEEKDAY:
+ return static_cast<int64_t>(res.tm_wday);
+ break;
+ case NOW_QUAL_YEARDAY:
+ return static_cast<int64_t>(res.tm_yday);
+ break;
+ }
+ }
+ return 0;
+}
+
// Parse URL qualifiers
UrlQualifiers
-Statement::parse_url_qualifier(const std::string &q)
+Statement::parse_url_qualifier(const std::string &q) const
{
UrlQualifiers qual = URL_QUAL_NONE;
@@ -98,3 +141,31 @@ Statement::parse_url_qualifier(const std::string &q)
return qual;
}
+
+
+// Parse NOW qualifiers
+NowQualifiers
+Statement::parse_now_qualifier(const std::string &q) const
+{
+ NowQualifiers qual = NOW_QUAL_EPOCH; // Default is seconds since epoch
+
+ if (q == "EPOCH") {
+ qual = NOW_QUAL_EPOCH;
+ } else if (q == "YEAR") {
+ qual = NOW_QUAL_YEAR;
+ } else if (q == "MONTH") {
+ qual = NOW_QUAL_MONTH;
+ } else if (q == "DAY") {
+ qual = NOW_QUAL_DAY;
+ } else if (q == "HOUR") {
+ qual = NOW_QUAL_HOUR;
+ } else if (q == "MINUTE") {
+ qual = NOW_QUAL_MINUTE;
+ } else if (q == "WEEKDAY") {
+ qual = NOW_QUAL_WEEKDAY;
+ } else if (q == "YEARDAY") {
+ qual = NOW_QUAL_YEARDAY;
+ }
+
+ return qual;
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0792a4a3/plugins/header_rewrite/statement.h
----------------------------------------------------------------------
diff --git a/plugins/header_rewrite/statement.h b/plugins/header_rewrite/statement.h
index a7aa3c4..254cf55 100644
--- a/plugins/header_rewrite/statement.h
+++ b/plugins/header_rewrite/statement.h
@@ -24,6 +24,7 @@
#define __STATEMENT_H__ 1
#include <string>
+#include <time.h>
#include <vector>
#include "ts/ts.h"
@@ -45,6 +46,18 @@ enum UrlQualifiers {
URL_QUAL_URL
};
+// NOW data
+enum NowQualifiers {
+ NOW_QUAL_EPOCH,
+ NOW_QUAL_YEAR,
+ NOW_QUAL_MONTH,
+ NOW_QUAL_DAY,
+ NOW_QUAL_HOUR,
+ NOW_QUAL_MINUTE,
+ NOW_QUAL_WEEKDAY,
+ NOW_QUAL_YEARDAY
+};
+
class Statement
{
@@ -114,7 +127,10 @@ public:
protected:
virtual void initialize_hooks();
- UrlQualifiers parse_url_qualifier(const std::string &q);
+ UrlQualifiers parse_url_qualifier(const std::string &q) const;
+ NowQualifiers parse_now_qualifier(const std::string &q) const;
+ int64_t get_now_qualified(NowQualifiers qual) const;
+
void
require_resources(const ResourceIDs ids)
{