You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/01/17 20:51:28 UTC
git commit: TS-2508: escalation plugin
Updated Branches:
refs/heads/master 6af333d39 -> 9fda6972b
TS-2508: escalation plugin
The escalation plugin is intended to allow Traffic Server to handle
origin errors by rerouting to a different URL. This doesn't currently
work, since the APIs it uses cause crashes. In it's current form,
it should be useful as a test case to work on fixing the APIs.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/9fda6972
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/9fda6972
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/9fda6972
Branch: refs/heads/master
Commit: 9fda6972b6c36a8075e7f780521a589b19c22aff
Parents: 6af333d
Author: James Peach <jp...@apache.org>
Authored: Fri Jan 10 10:48:37 2014 -0800
Committer: James Peach <jp...@apache.org>
Committed: Fri Jan 17 11:51:05 2014 -0800
----------------------------------------------------------------------
CHANGES | 2 +
configure.ac | 1 +
plugins/experimental/Makefile.am | 1 +
plugins/experimental/escalate/Makefile.am | 22 ++++
plugins/experimental/escalate/escalate.cc | 166 +++++++++++++++++++++++++
5 files changed, 192 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fda6972/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index a0d6ffd..be6efa7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 4.2.0
+ *) [TS-2508] Add a *highly* experimental escalation plugin.
+
*) [TS-2507] Fix the state transition logging in HttpSM::handle_server_setup_error.
*) [TS-1648] Segmentation fault in dir_clear_range()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fda6972/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index ebffa6f..a71f578 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1940,6 +1940,7 @@ AC_CONFIG_FILES([
plugins/experimental/buffer_upload/Makefile
plugins/experimental/channel_stats/Makefile
plugins/experimental/custom_redirect/Makefile
+ plugins/experimental/escalate/Makefile
plugins/experimental/esi/Makefile
plugins/experimental/geoip_acl/Makefile
plugins/experimental/lua/Makefile
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fda6972/plugins/experimental/Makefile.am
----------------------------------------------------------------------
diff --git a/plugins/experimental/Makefile.am b/plugins/experimental/Makefile.am
index fae383d..d2d14ab 100644
--- a/plugins/experimental/Makefile.am
+++ b/plugins/experimental/Makefile.am
@@ -19,6 +19,7 @@ if BUILD_EXPERIMENTAL_PLUGINS
SUBDIRS = \
authproxy \
balancer \
+ escalate \
buffer_upload \
channel_stats \
custom_redirect \
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fda6972/plugins/experimental/escalate/Makefile.am
----------------------------------------------------------------------
diff --git a/plugins/experimental/escalate/Makefile.am b/plugins/experimental/escalate/Makefile.am
new file mode 100644
index 0000000..1537847
--- /dev/null
+++ b/plugins/experimental/escalate/Makefile.am
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+include $(top_srcdir)/build/plugins.mk
+
+pkglib_LTLIBRARIES = escalate.la
+escalate_la_SOURCES = escalate.cc
+escalate_la_LDFLAGS = $(TS_PLUGIN_LDFLAGS)
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fda6972/plugins/experimental/escalate/escalate.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/escalate/escalate.cc b/plugins/experimental/escalate/escalate.cc
new file mode 100644
index 0000000..7181111
--- /dev/null
+++ b/plugins/experimental/escalate/escalate.cc
@@ -0,0 +1,166 @@
+/** @file
+
+ Escalation plugin.
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include <ts/ts.h>
+#include <ts/remap.h>
+#include <ts/experimental.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <string>
+#include <sstream>
+#include <iterator>
+#include <map>
+
+struct EscalationState
+{
+ typedef std::map<unsigned, TSMLoc> urlmap_type;
+
+ EscalationState() {
+ this->mbuf = TSMBufferCreate();
+ }
+
+ ~EscalationState() {
+ TSMBufferDestroy(this->mbuf);
+ }
+
+ TSCont handler;
+ urlmap_type urlmap;
+ TSMBuffer mbuf;
+};
+
+static unsigned
+toint(const std::string& str)
+{
+ std::istringstream istr(str);
+ unsigned val;
+
+ istr >> val;
+ return val;
+}
+
+static int
+EscalateResponse(TSCont cont, TSEvent event, void * edata)
+{
+ EscalationState * es = (EscalationState *)TSContDataGet(cont);
+ TSHttpTxn txn = (TSHttpTxn)edata;
+ TSMBuffer buffer;
+ TSMLoc hdr;
+ TSHttpStatus status;
+
+ TSDebug("escalate", "hit escalation hook with event %d", (int)event);
+ TSReleaseAssert(event == TS_EVENT_HTTP_READ_RESPONSE_HDR);
+
+ // First, we need the server response ...
+ TSReleaseAssert(
+ TSHttpTxnServerRespGet(txn, &buffer, &hdr) == TS_SUCCESS
+ );
+
+ // Next, the respose status ...
+ status = TSHttpHdrStatusGet(buffer, hdr);
+
+ // If we have an escalation URL for this response code, set the redirection URL and force it
+ // to be followed.
+ EscalationState::urlmap_type::iterator entry = es->urlmap.find((unsigned)status);
+ if (entry != es->urlmap.end()) {
+ TSDebug("escalate", "found an escalation entry for HTTP status %u", (unsigned)status);
+ TSHttpTxnRedirectRequest(txn, es->mbuf, entry->second);
+ TSHttpTxnFollowRedirect(txn, 1 /* on */);
+ }
+
+ // Set the transaction free ...
+ TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
+ return TS_EVENT_NONE;
+}
+
+TSReturnCode
+TSRemapInit(TSRemapInterface * /* api */, char * /* errbuf */, int /* bufsz */)
+{
+ return TS_SUCCESS;
+}
+
+TSReturnCode
+TSRemapNewInstance(int argc, char * argv[], void ** instance, char * errbuf, int errbuf_size)
+{
+ EscalationState * es((EscalationState *)instance);
+
+ es = new EscalationState();
+ es->handler = TSContCreate(EscalateResponse, NULL);
+ TSContDataSet(es->handler, es);
+
+ // The first two arguments are the "from" and "to" URL string. We can just
+ // skip those, since we only ever remap on the error path.
+ for (int i = 2; i < argc; ++i) {
+ unsigned status;
+ TSMLoc url;
+ char * sep;
+
+ // Each token should be a status code then a URL, separated by '='.
+ sep = strchr(argv[i], '=');
+ if (sep == NULL) {
+ snprintf(errbuf, errbuf_size, "missing status code: %s", argv[i]);
+ goto fail;
+ }
+
+ status = toint(std::string(argv[i], std::distance(argv[i], sep)));
+ if (status < 100 || status > 599) {
+ snprintf(errbuf, errbuf_size, "invalid status code: %.*s", (int)std::distance(argv[i], sep), argv[i]);
+ goto fail;
+ }
+
+ TSReleaseAssert(TSUrlCreate(es->mbuf, &url) == TS_SUCCESS);
+
+ ++sep; // Skip over the '='.
+
+ TSDebug("escalate", "escalating HTTP status %u to %s", status, sep);
+ if (TSUrlParse(es->mbuf, url, (const char **)&sep, argv[i] + strlen(argv[i])) != TS_PARSE_DONE) {
+ snprintf(errbuf, errbuf_size, "invalid target URL: %s", sep);
+ goto fail;
+ }
+
+ // OK, we have a valid status/URL pair.
+ es->urlmap[status] = url;
+ }
+
+ *instance = es;
+ return TS_SUCCESS;
+
+fail:
+ delete es;
+ return TS_ERROR;
+}
+
+void
+TSRemapDeleteInstance(void * instance)
+{
+ delete (EscalationState *)instance;
+}
+
+TSRemapStatus
+TSRemapDoRemap(void * instance, TSHttpTxn txn, TSRemapRequestInfo * /* rri */)
+{
+ EscalationState * es((EscalationState *)instance);
+
+ TSHttpTxnHookAdd(txn, TS_HTTP_READ_RESPONSE_HDR_HOOK, es->handler);
+ return TSREMAP_NO_REMAP;
+}