You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by br...@apache.org on 2013/10/18 23:51:12 UTC

[5/5] git commit: initial atscppapi commit

initial atscppapi commit


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/7b2ea5f8
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/7b2ea5f8
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/7b2ea5f8

Branch: refs/heads/master
Commit: 7b2ea5f899dcc58d05d8681ba8332b90b5cc8f55
Parents: cc25667
Author: Brian Geffon <br...@apache.org>
Authored: Fri Oct 18 14:50:54 2013 -0700
Committer: Brian Geffon <br...@apache.org>
Committed: Fri Oct 18 14:50:54 2013 -0700

----------------------------------------------------------------------
 lib/atscppapi/Makefile.am                       |  19 +
 lib/atscppapi/examples/Makefile.am              |  38 +
 .../examples/async_http_fetch/AsyncHttpFetch.cc | 144 +++
 .../examples/async_http_fetch/Makefile.am       |  30 +
 .../examples/async_timer/AsyncTimer.cc          |  75 ++
 lib/atscppapi/examples/async_timer/Makefile.am  |  30 +
 .../examples/clientredirect/ClientRedirect.cc   |  76 ++
 .../examples/clientredirect/Makefile.am         |  29 +
 .../examples/clientrequest/ClientRequest.cc     | 133 +++
 .../examples/clientrequest/Makefile.am          |  30 +
 .../examples/customresponse/CustomResponse.cc   |  82 ++
 .../examples/customresponse/Makefile.am         |  29 +
 lib/atscppapi/examples/data_caching/Makefile.am |  29 +
 .../examples/data_caching/data_caching.cc       |  98 +++
 .../examples/detachedrequest/DetachedRequest.cc |  69 ++
 .../examples/detachedrequest/Makefile.am        |  30 +
 .../examples/globalhook/GlobalHookPlugin.cc     |  44 +
 lib/atscppapi/examples/globalhook/Makefile.am   |  29 +
 .../GzipTransformationPlugin.cc                 | 170 ++++
 .../examples/gzip_transformation/Makefile.am    |  30 +
 .../examples/helloworld/HelloWorldPlugin.cc     |  36 +
 lib/atscppapi/examples/helloworld/Makefile.am   |  29 +
 .../InternalTransactionHandling.cc              |  65 ++
 .../internal_transaction_handling/Makefile.am   |  29 +
 .../examples/logger_example/LoggerExample.cc    | 132 +++
 .../examples/logger_example/Makefile.am         |  30 +
 .../multiple_transaction_hooks/Makefile.am      |  29 +
 .../MultipleTransactionHookPlugins.cc           | 100 +++
 .../null_transformation_plugin/Makefile.am      |  30 +
 .../NullTransformationPlugin.cc                 |  71 ++
 lib/atscppapi/examples/post_buffer/Makefile.am  |  29 +
 .../examples/post_buffer/PostBuffer.cc          |  75 ++
 lib/atscppapi/examples/remap_plugin/Makefile.am |  30 +
 .../examples/remap_plugin/RemapPlugin.cc        |  86 ++
 .../examples/request_cookies/Makefile.am        |  30 +
 .../examples/request_cookies/RequestCookies.cc  |  67 ++
 .../examples/serverresponse/Makefile.am         |  29 +
 .../examples/serverresponse/ServerResponse.cc   | 105 +++
 lib/atscppapi/examples/stat_example/Makefile.am |  30 +
 .../examples/stat_example/StatExample.cc        |  71 ++
 .../examples/timeout_example/Makefile.am        |  30 +
 .../timeout_example/TimeoutExamplePlugin.cc     |  56 ++
 .../examples/transactionhook/Makefile.am        |  30 +
 .../transactionhook/TransactionHookPlugin.cc    |  60 ++
 lib/atscppapi/src/AsyncHttpFetch.cc             | 170 ++++
 lib/atscppapi/src/AsyncTimer.cc                 | 106 +++
 .../src/CaseInsensitiveStringComparator.cc      |  70 ++
 lib/atscppapi/src/ClientRequest.cc              |  75 ++
 lib/atscppapi/src/GlobalPlugin.cc               |  78 ++
 lib/atscppapi/src/GzipDeflateTransformation.cc  | 156 ++++
 lib/atscppapi/src/GzipInflateTransformation.cc  | 130 +++
 lib/atscppapi/src/Headers.cc                    | 532 +++++++++++
 lib/atscppapi/src/HttpMethod.cc                 |  36 +
 lib/atscppapi/src/HttpVersion.cc                |  29 +
 lib/atscppapi/src/InitializableValue.cc         |  29 +
 lib/atscppapi/src/Logger.cc                     | 213 +++++
 lib/atscppapi/src/Makefile.am                   |  77 ++
 lib/atscppapi/src/Plugin.cc                     |  31 +
 lib/atscppapi/src/RemapPlugin.cc                |  66 ++
 lib/atscppapi/src/Request.cc                    | 167 ++++
 lib/atscppapi/src/Response.cc                   | 126 +++
 lib/atscppapi/src/Stat.cc                       |  96 ++
 lib/atscppapi/src/Transaction.cc                | 300 +++++++
 lib/atscppapi/src/TransactionPlugin.cc          |  83 ++
 lib/atscppapi/src/TransformationPlugin.cc       | 319 +++++++
 lib/atscppapi/src/Url.cc                        | 218 +++++
 lib/atscppapi/src/include/InitializableValue.h  |  90 ++
 lib/atscppapi/src/include/atscppapi/Async.h     | 187 ++++
 .../src/include/atscppapi/AsyncHttpFetch.h      | 102 +++
 .../src/include/atscppapi/AsyncTimer.h          |  78 ++
 .../atscppapi/CaseInsensitiveStringComparator.h |  51 ++
 .../src/include/atscppapi/ClientRequest.h       |  59 ++
 .../src/include/atscppapi/GlobalPlugin.h        |  90 ++
 .../atscppapi/GzipDeflateTransformation.h       |  91 ++
 .../atscppapi/GzipInflateTransformation.h       |  92 ++
 lib/atscppapi/src/include/atscppapi/Headers.h   | 246 ++++++
 .../src/include/atscppapi/HttpMethod.h          |  58 ++
 .../src/include/atscppapi/HttpStatus.h          | 104 +++
 .../src/include/atscppapi/HttpVersion.h         |  52 ++
 lib/atscppapi/src/include/atscppapi/Logger.h    | 268 ++++++
 lib/atscppapi/src/include/atscppapi/Mutex.h     | 250 ++++++
 lib/atscppapi/src/include/atscppapi/Plugin.h    | 106 +++
 .../src/include/atscppapi/PluginInit.h          |  55 ++
 .../src/include/atscppapi/RemapPlugin.h         |  69 ++
 lib/atscppapi/src/include/atscppapi/Request.h   |  72 ++
 lib/atscppapi/src/include/atscppapi/Response.h  |  71 ++
 lib/atscppapi/src/include/atscppapi/Stat.h      | 106 +++
 .../src/include/atscppapi/Transaction.h         | 314 +++++++
 .../src/include/atscppapi/TransactionPlugin.h   | 113 +++
 .../include/atscppapi/TransformationPlugin.h    | 129 +++
 lib/atscppapi/src/include/atscppapi/Url.h       | 149 ++++
 .../src/include/atscppapi/noncopyable.h         |  64 ++
 .../src/include/atscppapi/shared_ptr.h          |  41 +
 lib/atscppapi/src/include/atscppapi/utils.h     |  69 ++
 lib/atscppapi/src/include/logging_internal.h    |  44 +
 lib/atscppapi/src/include/utils_internal.h      |  89 ++
 lib/atscppapi/src/utils.cc                      |  79 ++
 lib/atscppapi/src/utils_internal.cc             | 246 ++++++
 lib/cpp11api/Makefile.am                        |  37 -
 lib/cpp11api/cpp11api.cc                        | 880 -------------------
 lib/cpp11api/ts-cpp11-headers.h                 | 120 ---
 lib/cpp11api/ts-cpp11.h                         | 126 ---
 102 files changed, 9234 insertions(+), 1163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/Makefile.am b/lib/atscppapi/Makefile.am
new file mode 100644
index 0000000..028d09c
--- /dev/null
+++ b/lib/atscppapi/Makefile.am
@@ -0,0 +1,19 @@
+#
+#  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.
+includedir=$(prefix)/include/ts
+
+SUBDIRS = src

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/Makefile.am b/lib/atscppapi/examples/Makefile.am
new file mode 100644
index 0000000..7a48ad0
--- /dev/null
+++ b/lib/atscppapi/examples/Makefile.am
@@ -0,0 +1,38 @@
+#
+#  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.
+
+SUBDIRS = helloworld \
+	  globalhook \
+      transactionhook \
+	  multiple_transaction_hooks \
+	  data_caching \
+	  clientrequest \
+	  serverresponse \
+	  clientredirect \
+	  customresponse \
+	  null_transformation_plugin \
+	  post_buffer \
+	  logger_example \
+      detachedrequest \
+	  stat_example \
+      remap_plugin \
+	  async_http_fetch \
+	  gzip_transformation \
+	  timeout_example \
+      internal_transaction_handling \
+      async_timer \
+      request_cookies
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc b/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc
new file mode 100644
index 0000000..c98e658
--- /dev/null
+++ b/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc
@@ -0,0 +1,144 @@
+/**
+  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 <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/Logger.h>
+#include <atscppapi/Async.h>
+#include <atscppapi/AsyncHttpFetch.h>
+#include <atscppapi/PluginInit.h>
+#include <cstring>
+#include <cassert>
+
+using namespace atscppapi;
+using std::string;
+
+// This is for the -T tag debugging
+// To view the debug messages ./traffic_server -T "async_http_fetch_example.*"
+#define TAG "async_http_fetch_example"
+
+class AsyncHttpFetch2 : public AsyncHttpFetch {
+public:
+  AsyncHttpFetch2(string request) : AsyncHttpFetch(request) { };
+};
+
+class AsyncHttpFetch3 : public AsyncHttpFetch {
+public:
+  AsyncHttpFetch3(string request, HttpMethod method) : AsyncHttpFetch(request, method) { };
+};
+
+class TransactionHookPlugin : public TransactionPlugin, public AsyncReceiver<AsyncHttpFetch>,
+                              public AsyncReceiver<AsyncHttpFetch2>, public AsyncReceiver<AsyncHttpFetch3> {
+public:
+  TransactionHookPlugin(Transaction &transaction) :
+    TransactionPlugin(transaction), transaction_(transaction), num_fetches_pending_(0) {
+    TS_DEBUG(TAG, "Constructed TransactionHookPlugin, saved a reference to this transaction.");
+    registerHook(HOOK_SEND_REQUEST_HEADERS);
+  }
+
+  void handleSendRequestHeaders(Transaction &transaction) {
+    Async::execute<AsyncHttpFetch>(this, new AsyncHttpFetch("http://127.0.0.1/"), getMutex());
+    ++num_fetches_pending_;
+
+    // we'll add some custom headers for this request
+    AsyncHttpFetch2 *provider2 = new AsyncHttpFetch2("http://127.0.0.1/");
+    Headers &request_headers = provider2->getRequestHeaders();
+    request_headers.set("Header1", "Value1");
+    request_headers.set("Header2", "Value2");
+    Async::execute<AsyncHttpFetch2>(this, provider2, getMutex());
+    ++num_fetches_pending_;
+  }
+
+  void handleAsyncComplete(AsyncHttpFetch &async_http_fetch) {
+    // This will be called when our async event is complete.
+    TS_DEBUG(TAG, "AsyncHttpFetch completed");
+    handleAnyAsyncComplete(async_http_fetch);
+  }
+
+  void handleAsyncComplete(AsyncHttpFetch2 &async_http_fetch) {
+    // This will be called when our async event is complete.
+    TS_DEBUG(TAG, "AsyncHttpFetch2 completed");
+    handleAnyAsyncComplete(async_http_fetch);
+  }
+
+  virtual ~TransactionHookPlugin() {
+    TS_DEBUG(TAG, "Destroyed TransactionHookPlugin!");
+    // since we die right away, we should not receive the callback for this (using POST request this time)
+    Async::execute<AsyncHttpFetch3>(this, new AsyncHttpFetch3("http://127.0.0.1/", HTTP_METHOD_POST), getMutex());
+  }
+
+  void handleAsyncComplete(AsyncHttpFetch3 &async_http_fetch) {
+    assert(!"AsyncHttpFetch3 shouldn't have completed!");
+  }
+
+private:
+  Transaction &transaction_;
+  int num_fetches_pending_;
+
+  void handleAnyAsyncComplete(AsyncHttpFetch &async_http_fetch) {
+    // This will be called when our async event is complete.
+    const Response &response = async_http_fetch.getResponse();
+    if (async_http_fetch.getResult() == AsyncHttpFetch::RESULT_SUCCESS) {
+      TS_DEBUG(TAG, "Response version is [%s], status code %d, reason phrase [%s]",
+               HTTP_VERSION_STRINGS[response.getVersion()].c_str(), response.getStatusCode(), 
+               response.getReasonPhrase().c_str());
+      for (Headers::const_iterator iter = response.getHeaders().begin(), end = response.getHeaders().end();
+           iter != end; ++iter) {
+        TS_DEBUG(TAG, "*************** Response header: name [%s], values [%s]", iter->first.c_str(), 
+                 Headers::getJoinedValues(iter->second).c_str());;
+      }
+      const void *body;
+      size_t body_size;
+      async_http_fetch.getResponseBody(body, body_size);
+      TS_DEBUG(TAG, "Response body is [%.*s]", body_size, body);
+    } else {
+      TS_ERROR(TAG, "Fetch did not complete successfully; Result %d",
+               static_cast<int>(async_http_fetch.getResult()));
+    }
+    if (--num_fetches_pending_ == 0) {
+      TS_DEBUG(TAG, "Reenabling transaction");
+      transaction_.resume();
+    }
+  }
+
+};
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    TS_DEBUG(TAG, "Registering a global hook HOOK_READ_REQUEST_HEADERS_POST_REMAP");
+    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
+  }
+
+  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
+    TS_DEBUG(TAG, "Received a request in handleReadRequestHeadersPostRemap.");
+
+    // If we don't make sure to check if it's an internal request we can get ourselves into an infinite loop!
+    if (!transaction.isInternalRequest()) {
+      transaction.addPlugin(new TransactionHookPlugin(transaction));
+    }
+    transaction.resume();
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  TS_DEBUG(TAG, "Loaded async_http_fetch_example plugin");
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/async_http_fetch/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/async_http_fetch/Makefile.am b/lib/atscppapi/examples/async_http_fetch/Makefile.am
new file mode 100644
index 0000000..dd1dd94
--- /dev/null
+++ b/lib/atscppapi/examples/async_http_fetch/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=AsyncHttpFetch.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = AsyncHttpFetch.la
+AsyncHttpFetch_la_SOURCES = AsyncHttpFetch.cc
+AsyncHttpFetch_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/async_timer/AsyncTimer.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/async_timer/AsyncTimer.cc b/lib/atscppapi/examples/async_timer/AsyncTimer.cc
new file mode 100644
index 0000000..296d815
--- /dev/null
+++ b/lib/atscppapi/examples/async_timer/AsyncTimer.cc
@@ -0,0 +1,75 @@
+/**
+  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 <atscppapi/Logger.h>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/AsyncTimer.h>
+#include <atscppapi/GlobalPlugin.h>
+
+using namespace atscppapi;
+using std::string;
+
+#define TAG "async_timer"
+
+class TimerEventReceiver : public AsyncReceiver<AsyncTimer> {
+public:
+  TimerEventReceiver(AsyncTimer::Type type, int period_in_ms, int initial_period_in_ms = 0, int max_instances = 0)
+    : max_instances_(max_instances), instance_count_(0), type_(type) {
+    timer_ = new AsyncTimer(type, period_in_ms, initial_period_in_ms);
+    Async::execute<AsyncTimer>(this, timer_, shared_ptr<Mutex>()); // letting the system create the mutex
+  }
+
+  void handleAsyncComplete(AsyncTimer &timer) {
+    TS_DEBUG(TAG, "Got timer event in object %p!", this);
+    if ((type_ == AsyncTimer::TYPE_ONE_OFF) || (max_instances_ && (++instance_count_ == max_instances_))) {
+      TS_DEBUG(TAG, "Stopping timer in object %p!", this);
+      delete this;
+    }
+  }
+
+  ~TimerEventReceiver() {
+    delete timer_;
+  }
+
+private:
+  int max_instances_;
+  int instance_count_;
+  AsyncTimer::Type type_;
+  AsyncTimer *timer_;
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  int period_in_ms = 1000;
+  TimerEventReceiver *timer1 = new TimerEventReceiver(AsyncTimer::TYPE_PERIODIC, period_in_ms);
+  TS_DEBUG(TAG, "Created periodic timer %p with initial period 0, regular period %d and max instances 0", timer1,
+           period_in_ms);
+  int initial_period_in_ms = 100;
+  TimerEventReceiver *timer2 = new TimerEventReceiver(AsyncTimer::TYPE_PERIODIC, period_in_ms,
+                                                      initial_period_in_ms);
+  TS_DEBUG(TAG, "Created periodic timer %p with initial period %d, regular period %d and max instances 0", timer2,
+           initial_period_in_ms, period_in_ms);
+  initial_period_in_ms = 200;
+  int max_instances = 10;
+  TimerEventReceiver *timer3 = new TimerEventReceiver(AsyncTimer::TYPE_PERIODIC, period_in_ms, initial_period_in_ms,
+                                                      max_instances);
+  TS_DEBUG(TAG, "Created periodic timer %p with initial period %d, regular period %d and max instances %d", timer3,
+           initial_period_in_ms, period_in_ms, max_instances);
+
+  TimerEventReceiver *timer4 = new TimerEventReceiver(AsyncTimer::TYPE_ONE_OFF, period_in_ms);
+  TS_DEBUG(TAG, "Created one-off timer %p with period %d", timer4, period_in_ms);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/async_timer/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/async_timer/Makefile.am b/lib/atscppapi/examples/async_timer/Makefile.am
new file mode 100644
index 0000000..577d8d7
--- /dev/null
+++ b/lib/atscppapi/examples/async_timer/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=AsyncTimer.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = AsyncTimer.la
+AsyncTimer_la_SOURCES = AsyncTimer.cc
+AsyncTimer_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/clientredirect/ClientRedirect.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/clientredirect/ClientRedirect.cc b/lib/atscppapi/examples/clientredirect/ClientRedirect.cc
new file mode 100644
index 0000000..1da6533
--- /dev/null
+++ b/lib/atscppapi/examples/clientredirect/ClientRedirect.cc
@@ -0,0 +1,76 @@
+/**
+  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 <iostream>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/PluginInit.h>
+
+using namespace atscppapi;
+
+using std::cout;
+using std::endl;
+using std::list;
+using std::string;
+
+
+class ClientRedirectTransactionPlugin : public atscppapi::TransactionPlugin {
+public:
+  ClientRedirectTransactionPlugin(Transaction &transaction, const string &location)
+     : TransactionPlugin(transaction), location_(location) {
+
+    //
+    // We will set this transaction to jump to error state and then we will setup
+    // the redirect on SEND_RESPONSE_HEADERS
+    //
+    TransactionPlugin::registerHook(HOOK_SEND_RESPONSE_HEADERS);
+    transaction.error();
+  }
+
+  void handleSendResponseHeaders(Transaction &transaction) {
+    transaction.getClientResponse().setStatusCode(HTTP_STATUS_MOVED_TEMPORARILY);
+    transaction.getClientResponse().setReasonPhrase("Moved Temporarily");
+    transaction.getClientResponse().getHeaders().set("Location", location_);
+    transaction.resume();
+  }
+
+  virtual ~ClientRedirectTransactionPlugin() { }
+private:
+  string location_;
+};
+
+
+class ClientRedirectGlobalPlugin : public GlobalPlugin {
+public:
+  ClientRedirectGlobalPlugin() {
+    registerHook(HOOK_SEND_REQUEST_HEADERS);
+  }
+
+  void handleSendRequestHeaders(Transaction &transaction) {
+    if(transaction.getClientRequest().getUrl().getQuery().find("redirect=1") != string::npos) {
+      transaction.addPlugin(new ClientRedirectTransactionPlugin(transaction, "http://www.linkedin.com/"));
+      return;
+    }
+    transaction.resume();
+  }
+
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  GlobalPlugin *instance = new ClientRedirectGlobalPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/clientredirect/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/clientredirect/Makefile.am b/lib/atscppapi/examples/clientredirect/Makefile.am
new file mode 100644
index 0000000..ec1629c
--- /dev/null
+++ b/lib/atscppapi/examples/clientredirect/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=ClientRedirect.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = ClientRedirect.la
+ClientRedirect_la_SOURCES = ClientRedirect.cc
+ClientRedirect_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/clientrequest/ClientRequest.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/clientrequest/ClientRequest.cc b/lib/atscppapi/examples/clientrequest/ClientRequest.cc
new file mode 100644
index 0000000..b143374
--- /dev/null
+++ b/lib/atscppapi/examples/clientrequest/ClientRequest.cc
@@ -0,0 +1,133 @@
+/**
+  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 <iostream>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/utils.h>
+
+using namespace atscppapi;
+
+using std::cout;
+using std::endl;
+using std::list;
+using std::string;
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    registerHook(HOOK_READ_REQUEST_HEADERS_PRE_REMAP);
+    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
+    registerHook(HOOK_SEND_REQUEST_HEADERS);
+  }
+
+
+  void handleReadRequestHeadersPreRemap(Transaction &transaction) {
+    cout << "Hello from handleReadRequesHeadersPreRemap!" << endl;
+
+    ClientRequest &client_request = transaction.getClientRequest();
+    Url &request_url = client_request.getUrl();
+    const Url &pristine_request_url = client_request.getPristineUrl();
+
+    cout << "Method is " << HTTP_METHOD_STRINGS[client_request.getMethod()] << endl;
+    cout << "Version is " << HTTP_VERSION_STRINGS[client_request.getVersion()] << endl;
+    cout << "---------------------------------------------------" << endl;
+    cout << "URL is " << request_url.getUrlString() << endl;
+    cout << "Path is " << request_url.getPath() << endl;
+    cout << "Query is " << request_url.getQuery() << endl;
+    cout << "Host is " << request_url.getHost() << endl;
+    cout << "Port is " << request_url.getPort() << endl;
+    cout << "Scheme is " << request_url.getScheme() << endl;
+    cout << "---------------------------------------------------" << endl;
+    if (request_url.getPath() == "remap_me") {
+      request_url.setPath("index.html");
+    }
+
+    transaction.resume();
+  }
+
+
+  void handleReadRequestHeadersPostRemap(Transaction &transaction) {
+    cout << "Hello from handleReadRequesHeadersPostRemap!" << endl;
+
+    ClientRequest &client_request = transaction.getClientRequest();
+    Url &request_url = client_request.getUrl();
+    const Url &pristine_request_url = client_request.getPristineUrl();
+
+    cout << "--------------------PRISTINE-----------------------" << endl;
+    cout << "URL is " << pristine_request_url.getUrlString() << endl;
+    cout << "Path is " << pristine_request_url.getPath() << endl;
+    cout << "--------------------POST REMAP---------------------" << endl;
+    cout << "URL is " << request_url.getUrlString() << endl;
+    cout << "Path is " << request_url.getPath() << endl;
+    cout << "---------------------------------------------------" << endl;
+
+    Headers &client_request_headers = client_request.getHeaders();
+
+    Headers::const_iterator ii = client_request_headers.find("AccepT-EncodinG");
+    if(ii != client_request_headers.end()) {
+      cout << "Deleting accept-encoding header" << endl;
+      client_request_headers.erase("AccepT-EnCoDing"); // Case Insensitive
+    }
+
+    // These will be split back up into a list of three values automatically (see header output below).
+    cout << "Adding back Accept-Encoding." << endl;
+    client_request_headers.set("accept-encoding", "gzip, identity, my_special_format");
+
+    cout << "Adding a new accept type accept header" << endl;
+    client_request_headers.append("accept", "text/blah");
+
+    for (Headers::const_iterator header_iter = client_request_headers.begin(),
+           header_end = client_request_headers.end(); header_iter != header_end; ++header_iter) {
+      const string &name = header_iter->first;
+      const list<string> &value_list = header_iter->second;
+      cout << "Header. " << name <<  ": " << endl;
+      for (list<string>::const_iterator value_iter = value_list.begin(), value_end = value_list.end();
+           value_iter != value_end; ++value_iter) {
+        cout << "\t" << *value_iter << endl;
+      }
+    }
+
+    /*
+     * These will output:
+     * Joining on a non-existant header gives:
+     * Joining the accept encoding header gives: gzip,identity,my_special_format
+     * Joining the accept encoding header with space gives: gzip identity my_special_format
+     */
+    cout << "Joining on a non-existant header gives: " << client_request_headers.getJoinedValues("i_dont_exist") << endl;
+    cout << "Joining the accept encoding header gives: " << client_request_headers.getJoinedValues("accept-encoding") << endl;
+    cout << "Joining the accept encoding header with space gives: " << client_request_headers.getJoinedValues("accept-encoding", ' ') << endl;
+
+    transaction.resume();
+  }
+
+  void handleSendRequestHeaders(Transaction &transaction) {
+    cout << "Hello from handleSendRequestHeaders!" << endl;
+    cout << "---------------------IP INFORMATION-----------------" << endl;
+    cout << "Server Address: " << utils::getIpPortString(transaction.getServerAddress()) << endl;
+    cout << "Incoming Address: " << utils::getIpPortString(transaction.getIncomingAddress()) << endl;
+    cout << "Client Address: " << utils::getIpPortString(transaction.getClientAddress()) << endl;
+    cout << "Next Hop Address: " << utils::getIpPortString(transaction.getNextHopAddress()) << endl;
+    transaction.resume();
+  }
+
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/clientrequest/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/clientrequest/Makefile.am b/lib/atscppapi/examples/clientrequest/Makefile.am
new file mode 100644
index 0000000..9041577
--- /dev/null
+++ b/lib/atscppapi/examples/clientrequest/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=ClientRequest.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = ClientRequest.la
+ClientRequest_la_SOURCES = ClientRequest.cc
+ClientRequest_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/customresponse/CustomResponse.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/customresponse/CustomResponse.cc b/lib/atscppapi/examples/customresponse/CustomResponse.cc
new file mode 100644
index 0000000..870a838
--- /dev/null
+++ b/lib/atscppapi/examples/customresponse/CustomResponse.cc
@@ -0,0 +1,82 @@
+/**
+  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 <iostream>
+#include <string>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/PluginInit.h>
+
+using namespace atscppapi;
+
+using std::cout;
+using std::endl;
+using std::string;
+
+/*
+ *
+ * This example demonstrates how you can exploit .error() to send
+ * any response from any state by forcing the state machine to
+ * jump to the error state. You will then send your custom
+ * response in sendResponseHeaders() rather than the error page.
+ *
+ */
+
+class CustomResponseTransactionPlugin : public atscppapi::TransactionPlugin {
+public:
+  CustomResponseTransactionPlugin(Transaction &transaction, HttpStatus status, const string &reason, const string &body)
+     : TransactionPlugin(transaction), status_(status), reason_(reason), body_(body) {
+    TransactionPlugin::registerHook(HOOK_SEND_RESPONSE_HEADERS);
+    transaction.error(body_); // Set the error body now, and change the status and reason later.
+  }
+
+  void handleSendResponseHeaders(Transaction &transaction) {
+    transaction.getClientResponse().setStatusCode(status_);
+    transaction.getClientResponse().setReasonPhrase(reason_);
+    transaction.resume();
+  }
+
+  virtual ~CustomResponseTransactionPlugin() { }
+private:
+  HttpStatus status_;
+  string reason_;
+  string body_;
+};
+
+
+class ClientRedirectGlobalPlugin : public GlobalPlugin {
+public:
+  ClientRedirectGlobalPlugin() {
+    registerHook(HOOK_SEND_REQUEST_HEADERS);
+  }
+
+  void handleSendRequestHeaders(Transaction &transaction) {
+    if(transaction.getClientRequest().getUrl().getQuery().find("custom=1") != string::npos) {
+      transaction.addPlugin(new CustomResponseTransactionPlugin(transaction, HTTP_STATUS_OK, "Ok",
+                                                                "Hello! This is a custom response without making "
+                                                                "an origin request and no server intercept."));
+      return; // dont forget to return since the CustomResponse call will call .error().
+    }
+    transaction.resume();
+  }
+
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  GlobalPlugin *instance = new ClientRedirectGlobalPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/customresponse/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/customresponse/Makefile.am b/lib/atscppapi/examples/customresponse/Makefile.am
new file mode 100644
index 0000000..1e7093a
--- /dev/null
+++ b/lib/atscppapi/examples/customresponse/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=CustomResponse.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = CustomResponse.la
+CustomResponse_la_SOURCES = CustomResponse.cc
+CustomResponse_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/data_caching/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/data_caching/Makefile.am b/lib/atscppapi/examples/data_caching/Makefile.am
new file mode 100644
index 0000000..818e965
--- /dev/null
+++ b/lib/atscppapi/examples/data_caching/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=data_caching.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = data_caching.la
+data_caching_la_SOURCES = data_caching.cc
+data_caching_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/data_caching/data_caching.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/data_caching/data_caching.cc b/lib/atscppapi/examples/data_caching/data_caching.cc
new file mode 100644
index 0000000..64ae4ee
--- /dev/null
+++ b/lib/atscppapi/examples/data_caching/data_caching.cc
@@ -0,0 +1,98 @@
+/**
+  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 <iostream>
+#include <cstdlib>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/ClientRequest.h>
+#include <atscppapi/utils.h>
+
+#include <ts/ts.h>
+
+using namespace atscppapi;
+using namespace std;
+
+namespace {
+
+const string SPECIAL_HEADER("Special-Header");
+
+}
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    registerHook(HOOK_READ_REQUEST_HEADERS_PRE_REMAP);
+    registerHook(HOOK_SEND_RESPONSE_HEADERS);
+  }
+
+  virtual void handleReadRequestHeadersPreRemap(Transaction &transaction) {
+    cout << "Hello from handleReadRequesHeadersPreRemap!" << endl;
+    checkForSpecialHeader(transaction.getClientRequest().getHeaders());
+    transaction.resume();
+  }
+
+  virtual void handleSendResponseHeaders(Transaction &transaction) {
+    cout << "Hello from handleSendResponseHeaders!" << endl;
+    checkForSpecialHeader(transaction.getClientRequest().getHeaders());
+    transaction.resume();
+  }
+
+private:
+  void checkForSpecialHeader(const Headers &headers) {
+    Headers::const_iterator iter = headers.find(SPECIAL_HEADER);
+    if (iter == headers.end()) {
+      cout << "Special header is absent" << endl;
+    } else {
+      cout << "Special header is present with value " << iter->second.front() << endl;
+    }
+  }
+};
+
+namespace {
+
+int handlePostRemap(TSCont cont, TSEvent event, void *edata) {
+  TSHttpTxn txn = static_cast<TSHttpTxn>(edata);
+  TSMBuffer hdr_buf;
+  TSMLoc hdr_loc, field_loc;
+  TSHttpTxnClientReqGet(txn, &hdr_buf, &hdr_loc);
+  int nullTerminatedStringLength = -1;
+  TSMimeHdrFieldCreateNamed(hdr_buf, hdr_loc, SPECIAL_HEADER.c_str(), nullTerminatedStringLength, &field_loc);
+  const char *value = "foo";
+  int insertAtBeginningIndex = 0;
+  TSMimeHdrFieldValueStringInsert(hdr_buf, hdr_loc, field_loc, insertAtBeginningIndex, value,
+                                  nullTerminatedStringLength);
+  TSMimeHdrFieldAppend(hdr_buf, hdr_loc, field_loc);
+  TSHandleMLocRelease(hdr_buf, hdr_loc, field_loc);
+  TSMLoc hdr_loc_null_parent = NULL;
+  TSHandleMLocRelease(hdr_buf, hdr_loc_null_parent, hdr_loc);
+  TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
+  return 0;
+}
+
+}
+
+void TSPluginInit(int argc, const char *argv[]) {
+  int do_overwrite = 1;
+  setenv(utils::DISABLE_DATA_CACHING_ENV_FLAG.c_str(), "true", do_overwrite);
+
+  GlobalPlugin *instance = new GlobalHookPlugin();
+
+  TSMutex nullMutex = NULL;
+  TSCont globalCont = TSContCreate(handlePostRemap, nullMutex);
+  TSHttpHookAdd(TS_HTTP_POST_REMAP_HOOK, globalCont);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/detachedrequest/DetachedRequest.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/detachedrequest/DetachedRequest.cc b/lib/atscppapi/examples/detachedrequest/DetachedRequest.cc
new file mode 100644
index 0000000..ee95118
--- /dev/null
+++ b/lib/atscppapi/examples/detachedrequest/DetachedRequest.cc
@@ -0,0 +1,69 @@
+/**
+  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 <atscppapi/GlobalPlugin.h>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/Logger.h>
+
+using namespace std;
+using namespace atscppapi;
+
+#define LOG_TAG "detachedrequest"
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    registerHook(HOOK_READ_REQUEST_HEADERS_PRE_REMAP);
+  }
+  void handleReadRequestHeadersPreRemap(Transaction &transaction) {
+    string url_str("http://www.linkedin.com/");
+    Request detached_request(url_str);
+    Url &url = detached_request.getUrl();
+    TS_DEBUG(LOG_TAG, "Method is [%s], url is [%s], version is [%s]",
+             HTTP_METHOD_STRINGS[detached_request.getMethod()].c_str(),
+             detached_request.getUrl().getUrlString().c_str(),
+             HTTP_VERSION_STRINGS[detached_request.getVersion()].c_str());
+
+    Headers &detached_request_headers = detached_request.getHeaders();
+    TS_DEBUG(LOG_TAG, "Headers before adds");
+    printHeaders(detached_request_headers);
+
+    detached_request_headers.set("Header1", "value1");
+    detached_request_headers.append("Header1", "value2");
+    detached_request_headers.set("Header2", "value1");
+    TS_DEBUG(LOG_TAG, "Headers after adds");
+    printHeaders(detached_request_headers);
+
+    detached_request_headers.erase("Header1");
+    TS_DEBUG(LOG_TAG, "Headers after erase");
+    printHeaders(detached_request_headers);
+
+    transaction.resume();
+  }
+private:
+  void printHeaders(const Headers &headers) {
+    for (Headers::const_iterator iter = headers.begin(), end = headers.end(); iter != end; ++iter) {
+      TS_DEBUG(LOG_TAG, "Header [%s] has values [%s]", iter->first.c_str(),
+               Headers::getJoinedValues(iter->second).c_str());
+    }
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/detachedrequest/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/detachedrequest/Makefile.am b/lib/atscppapi/examples/detachedrequest/Makefile.am
new file mode 100644
index 0000000..afe0199
--- /dev/null
+++ b/lib/atscppapi/examples/detachedrequest/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=DetachedRequest.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = DetachedRequest.la
+DetachedRequest_la_SOURCES = DetachedRequest.cc
+DetachedRequest_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/globalhook/GlobalHookPlugin.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/globalhook/GlobalHookPlugin.cc b/lib/atscppapi/examples/globalhook/GlobalHookPlugin.cc
new file mode 100644
index 0000000..68ceebf
--- /dev/null
+++ b/lib/atscppapi/examples/globalhook/GlobalHookPlugin.cc
@@ -0,0 +1,44 @@
+/**
+  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 <iostream>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/PluginInit.h>
+
+using namespace atscppapi;
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    registerHook(HOOK_READ_REQUEST_HEADERS_PRE_REMAP, [](Transaction &t) {
+
+    });
+
+  }
+
+  virtual void handleReadRequestHeadersPreRemap(Transaction &transaction) {
+    std::cout << "Hello from handleReadRequesHeadersPreRemap!" << std::endl;
+    transaction.resume();
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/globalhook/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/globalhook/Makefile.am b/lib/atscppapi/examples/globalhook/Makefile.am
new file mode 100644
index 0000000..9269312
--- /dev/null
+++ b/lib/atscppapi/examples/globalhook/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=GlobalHookPlugin.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = GlobalHookPlugin.la
+GlobalHookPlugin_la_SOURCES = GlobalHookPlugin.cc
+GlobalHookPlugin_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/gzip_transformation/GzipTransformationPlugin.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/gzip_transformation/GzipTransformationPlugin.cc b/lib/atscppapi/examples/gzip_transformation/GzipTransformationPlugin.cc
new file mode 100644
index 0000000..176870f
--- /dev/null
+++ b/lib/atscppapi/examples/gzip_transformation/GzipTransformationPlugin.cc
@@ -0,0 +1,170 @@
+/**
+  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 <iostream>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/TransformationPlugin.h>
+#include <atscppapi/GzipInflateTransformation.h>
+#include <atscppapi/GzipDeflateTransformation.h>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/Logger.h>
+
+using namespace atscppapi;
+using namespace atscppapi::transformations;
+using std::string;
+
+#define TAG "gzip_transformation"
+
+/*
+ * Note, the GzipInflateTransformation and GzipDeflateTransformation do not
+ * check headers to determine if the content was gziped and it doesn't check
+ * headers to make sure the client supports gzip, this is entirely up to the plugin
+ * to verify that the content-encoding is gzipped, it's also up to the client
+ * to make sure the user's accept-encoding supports gzip.
+ *
+ * Read this example very carefully, in this example we modify the Accept-Encoding
+ * header to the origin to ensure that we will be returned gzipped or identity encoding
+ * content. If we receive gzipped content we will inflate it, we will apply our transformation
+ * and if the client supports gzip we will deflate the content that we transformed. Finally,
+ * if the user supported gzip (then they got gzip) and we must make sure the content-encoding
+ * header is correctly set on the way out.
+ */
+
+class Helpers {
+public:
+  static bool clientAcceptsGzip(Transaction &transaction) {
+    return transaction.getClientRequest().getHeaders().getJoinedValues("Accept-Encoding").find("gzip") != string::npos;
+  }
+
+  static bool serverReturnedGzip(Transaction &transaction) {
+    return transaction.getServerResponse().getHeaders().getJoinedValues("Content-Encoding").find("gzip") != string::npos;
+  }
+
+  enum ContentType { UNKNOWN = 0, TEXT_HTML  = 1, TEXT_PLAIN = 2 };
+
+  static ContentType getContentType(Transaction &transaction) {
+    if (transaction.getServerResponse().getHeaders().getJoinedValues("Content-Type").find("text/html") != string::npos) {
+      return TEXT_HTML;
+    } else if (transaction.getServerResponse().getHeaders().getJoinedValues("Content-Type").find("text/plain") != string::npos) {
+      return TEXT_PLAIN;
+    } else {
+      return UNKNOWN;
+    }
+  }
+};
+
+class SomeTransformationPlugin : public TransformationPlugin {
+public:
+  SomeTransformationPlugin(Transaction &transaction)
+    : TransformationPlugin(transaction, RESPONSE_TRANSFORMATION), transaction_(transaction) {
+    registerHook(HOOK_SEND_RESPONSE_HEADERS);
+  }
+
+  void handleSendResponseHeaders(Transaction &transaction) {
+    TS_DEBUG(TAG, "Added X-Content-Transformed header");
+    transaction.getClientResponse().getHeaders().set("X-Content-Transformed", "1");
+    transaction.resume();
+  }
+
+  void consume(const string &data) {
+    produce(data);
+  }
+
+  void handleInputComplete() {
+    Helpers::ContentType content_type = Helpers::getContentType(transaction_);
+    if (content_type == Helpers::TEXT_HTML) {
+      TS_DEBUG(TAG, "Adding an HTML comment at the end of the page");
+      produce("\n<br /><!-- Gzip Transformation Plugin Was Here -->");
+    } else if (content_type == Helpers::TEXT_PLAIN) {
+      TS_DEBUG(TAG, "Adding a text comment at the end of the page");
+      produce("\nGzip Transformation Plugin Was Here");
+    } else {
+      TS_DEBUG(TAG, "Unable to add TEXT or HTML comment because content type was not text/html or text/plain.");
+    }
+    setOutputComplete();
+  }
+
+  virtual ~SomeTransformationPlugin() { }
+private:
+  Transaction &transaction_;
+};
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    registerHook(HOOK_SEND_REQUEST_HEADERS);
+    registerHook(HOOK_READ_RESPONSE_HEADERS);
+    registerHook(HOOK_SEND_RESPONSE_HEADERS);
+  }
+
+  virtual void handleSendRequestHeaders(Transaction &transaction) {
+    // Since we can only decompress gzip we will change the accept encoding header
+    // to gzip, even if the user cannot accept gziped content we will return to them
+    // uncompressed content in that case since we have to be able to transform the content.
+    string original_accept_encoding = transaction.getServerRequest().getHeaders().getJoinedValues("Accept-Encoding");
+
+    // Make sure it's done on the server request to avoid clobbering the clients original accept encoding header.
+    transaction.getServerRequest().getHeaders().set("Accept-Encoding", "gzip");
+    TS_DEBUG(TAG, "Changed the servers request accept encoding header from \"%s\" to gzip", original_accept_encoding.c_str());
+
+    transaction.resume();
+  }
+
+  virtual void handleReadResponseHeaders(Transaction &transaction) {
+    TS_DEBUG(TAG, "Determining if we need to add an inflate transformation or a deflate transformation..");
+    // We're guaranteed to have been returned either gzipped content or Identity.
+
+    if (Helpers::serverReturnedGzip(transaction)) {
+      // If the returned content was gziped we will inflate it so we can transform it.
+      TS_DEBUG(TAG,"Creating Inflate Transformation because the server returned gziped content");
+      transaction.addPlugin(new GzipInflateTransformation(transaction,
+                                                          TransformationPlugin::RESPONSE_TRANSFORMATION));
+    }
+
+    transaction.addPlugin(new SomeTransformationPlugin(transaction));
+
+    // Even if the server didn't return gziped content, if the user supports it we will gzip it.
+    if (Helpers::clientAcceptsGzip(transaction)) {
+      TS_DEBUG(TAG,"The client supports gzip so we will deflate the content on the way out.");
+      transaction.addPlugin(new GzipDeflateTransformation(transaction,
+                                                          TransformationPlugin::RESPONSE_TRANSFORMATION));
+    }
+    transaction.resume();
+  }
+
+  virtual void handleSendResponseHeaders(Transaction &transaction) {
+    // If the client supported gzip then we can guarantee they are receiving gzip since regardless of the
+    // origins content-encoding we returned gzip, so let's make sure the content-encoding header is correctly
+    // set to gzip or identity.
+    if (Helpers::clientAcceptsGzip(transaction)) {
+      TS_DEBUG(TAG,"Setting the client response content-encoding to gzip since the user supported it, that's what they got.");
+      transaction.getClientResponse().getHeaders().set("Content-Encoding", "gzip");
+    } else {
+      TS_DEBUG(TAG,"Setting the client response content-encoding to identity since the user didn't support gzip");
+      transaction.getClientResponse().getHeaders().set("Content-Encoding", "identity");
+    }
+    transaction.resume();
+  }
+
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  TS_DEBUG(TAG, "TSPluginInit");
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/gzip_transformation/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/gzip_transformation/Makefile.am b/lib/atscppapi/examples/gzip_transformation/Makefile.am
new file mode 100644
index 0000000..bfaaae1
--- /dev/null
+++ b/lib/atscppapi/examples/gzip_transformation/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=GzipTransformationPlugin.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = GzipTransformationPlugin.la
+GzipTransformationPlugin_la_SOURCES = GzipTransformationPlugin.cc
+GzipTransformationPlugin_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/helloworld/HelloWorldPlugin.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/helloworld/HelloWorldPlugin.cc b/lib/atscppapi/examples/helloworld/HelloWorldPlugin.cc
new file mode 100644
index 0000000..6c73cda
--- /dev/null
+++ b/lib/atscppapi/examples/helloworld/HelloWorldPlugin.cc
@@ -0,0 +1,36 @@
+/**
+  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 <iostream>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/PluginInit.h>
+
+class HelloWorldPlugin : public atscppapi::GlobalPlugin {
+public:
+  HelloWorldPlugin() {
+    std::cout << "Hello World!" << std::endl;
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  std::cout << "Hello from " << argv[0] << std::endl;
+  atscppapi::GlobalPlugin *instance = new HelloWorldPlugin();
+}
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/helloworld/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/helloworld/Makefile.am b/lib/atscppapi/examples/helloworld/Makefile.am
new file mode 100644
index 0000000..ebdd7d1
--- /dev/null
+++ b/lib/atscppapi/examples/helloworld/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=HelloWorldPlugin.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = HelloWorldPlugin.la
+HelloWorldPlugin_la_SOURCES = HelloWorldPlugin.cc
+HelloWorldPlugin_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/internal_transaction_handling/InternalTransactionHandling.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/internal_transaction_handling/InternalTransactionHandling.cc b/lib/atscppapi/examples/internal_transaction_handling/InternalTransactionHandling.cc
new file mode 100644
index 0000000..566acce
--- /dev/null
+++ b/lib/atscppapi/examples/internal_transaction_handling/InternalTransactionHandling.cc
@@ -0,0 +1,65 @@
+/**
+  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 <atscppapi/GlobalPlugin.h>
+#include <atscppapi/Logger.h>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/AsyncHttpFetch.h>
+
+using namespace atscppapi;
+using std::string;
+
+#define TAG "internal_transaction_handling"
+
+class AllTransactionsGlobalPlugin : public GlobalPlugin {
+public:
+  AllTransactionsGlobalPlugin() : GlobalPlugin() {
+    TS_DEBUG(TAG, "Registering a global hook HOOK_READ_REQUEST_HEADERS_POST_REMAP");
+    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
+  }
+
+  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
+    TS_DEBUG(TAG, "Received a request in handleReadRequestHeadersPostRemap.");
+    transaction.resume();
+  }
+};
+
+class NoInternalTransactionsGlobalPlugin : public GlobalPlugin, public AsyncReceiver<AsyncHttpFetch> {
+public:
+  NoInternalTransactionsGlobalPlugin() : GlobalPlugin(true) {
+    TS_DEBUG(TAG, "Registering a global hook HOOK_READ_REQUEST_HEADERS_POST_REMAP");
+    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
+  }
+
+  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
+    TS_DEBUG(TAG, "Received a request in handleReadRequestHeadersPostRemap.");
+    shared_ptr<Mutex> mutex(new Mutex()); // required for async operation
+    Async::execute<AsyncHttpFetch>(this, new AsyncHttpFetch("http://127.0.0.1/"), mutex); // internal transaction
+    transaction.resume();
+  }
+
+  void handleAsyncComplete(AsyncHttpFetch &provider) {
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  TS_DEBUG(TAG, "Loaded async_http_fetch_example plugin");
+  AllTransactionsGlobalPlugin *instance1 = new AllTransactionsGlobalPlugin();
+  NoInternalTransactionsGlobalPlugin *instance2 = new NoInternalTransactionsGlobalPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/internal_transaction_handling/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/internal_transaction_handling/Makefile.am b/lib/atscppapi/examples/internal_transaction_handling/Makefile.am
new file mode 100644
index 0000000..447c943
--- /dev/null
+++ b/lib/atscppapi/examples/internal_transaction_handling/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=InternalTransactionHandling.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = InternalTransactionHandling.la
+InternalTransactionHandling_la_SOURCES = InternalTransactionHandling.cc
+InternalTransactionHandling_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/logger_example/LoggerExample.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/logger_example/LoggerExample.cc b/lib/atscppapi/examples/logger_example/LoggerExample.cc
new file mode 100644
index 0000000..4538c41
--- /dev/null
+++ b/lib/atscppapi/examples/logger_example/LoggerExample.cc
@@ -0,0 +1,132 @@
+/**
+  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.
+ */
+
+
+/**
+ * @warning log rolling doesn't work correctly in 3.2.x, see:
+ *   https://issues.apache.org/jira/browse/TS-1813, Apply the patch in
+ *   TS-1813 to correct log rolling in 3.2.x
+ */
+
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/Logger.h>
+#include <atscppapi/PluginInit.h>
+#include <cstring>
+
+using namespace atscppapi;
+using std::string;
+
+namespace {
+Logger log;
+}
+
+/*
+ * You should always take advantage of the LOG_DEBUG, LOG_INFO, and LOG_ERROR
+ * macros available in Logger.h, they are easy to use as you can see below
+ * and will provide detailed information about the logging site such as
+ * filename, function name, and line number of the message
+ */
+
+class GlobalHookPlugin : public GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    memset(big_buffer_6kb_,'a', sizeof(big_buffer_6kb_));
+    big_buffer_6kb_[sizeof(big_buffer_6kb_) - 1] = '\0';
+
+    memset(big_buffer_14kb_,'a', sizeof(big_buffer_14kb_));
+    big_buffer_14kb_[sizeof(big_buffer_14kb_) - 1] = '\0';
+
+    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
+  }
+
+  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
+    LOG_DEBUG(log, "handleReadRequestHeadersPostRemap.\n"
+        "\tRequest URL: %s\n"
+        "\tRequest Path: %s\n"
+        "\tRequest Query: %s\n"
+        "\tRequest Method: %s", transaction.getClientRequest().getUrl().getUrlString().c_str(),
+                                transaction.getClientRequest().getUrl().getPath().c_str(),
+                                transaction.getClientRequest().getUrl().getQuery().c_str(),
+                                HTTP_METHOD_STRINGS[transaction.getClientRequest().getMethod()].c_str()
+                               );
+
+    // Next, to demonstrate how you can change logging levels:
+    if (transaction.getClientRequest().getUrl().getPath() == "change_log_level") {
+      if (transaction.getClientRequest().getUrl().getQuery().find("level=debug") != string::npos) {
+        log.setLogLevel(Logger::LOG_LEVEL_DEBUG);
+        LOG_DEBUG(log, "Changed log level to DEBUG");
+      } else if (transaction.getClientRequest().getUrl().getQuery().find("level=info") != string::npos) {
+        log.setLogLevel(Logger::LOG_LEVEL_INFO);
+        LOG_INFO(log, "Changed log level to INFO");
+      } else if (transaction.getClientRequest().getUrl().getQuery().find("level=error") != string::npos) {
+        log.setLogLevel(Logger::LOG_LEVEL_ERROR);
+        LOG_ERROR(log, "Changed log level to ERROR");
+      }
+    }
+
+    // One drawback to usign the Traffic Server Text Loggers is that you're limited in the size of the log
+    // lines, this limit is now set at 8kb for atscppapi, but this limit might be removed in the future.
+    LOG_INFO(log, "This message will be dropped (see error.log) because it's just too big: %s", big_buffer_14kb_);
+
+    // This should work though:
+    LOG_INFO(log, "%s", big_buffer_6kb_);
+
+    transaction.resume();
+  }
+private:
+  char big_buffer_6kb_[6*1024];
+  char big_buffer_14kb_[14*1024];
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  // Create a new logger
+  // This will create a log file with the name logger_example.log (since we left off
+  //    the extension it will automatically add .log)
+  //
+  // The second argument is timestamp, which will force a timestamp on every log message
+  //  this is enabled by default.
+  // The third argument is renaming enabled, which means if a log already exists with that
+  //  name it will try logger_example.1 and so on, this is enabled by default.
+  // The fourth argument is the initial logging level this can always be changed with log.setLogLevel().
+  //  the default log level is LOG_LEVEL_INFO.
+  // The fifth argument is to enable log rolling, this is enabled by default.
+  // The sixth argument is the freuqency in which we will roll the logs, 300 seconds is very low,
+  //  the default for this argument is 3600.
+  log.init("logger_example", true, true, Logger::LOG_LEVEL_DEBUG, true, 300);
+
+  // Now that we've initialized a logger we can do all kinds of fun things on it:
+  log.setRollingEnabled(true); // already done via log.init, just an example.
+  log.setRollingIntervalSeconds(300); // already done via log.init
+
+  // You have two ways to log to a logger, you can log directly on the object itself:
+  log.logInfo("Hello World from: %s", argv[0]);
+
+  // Alternatively you can take advantage of the super helper macros for logging
+  // that will include the file, function, and line number automatically as part
+  // of the log message:
+  LOG_INFO(log, "Hello World with more info from: %s", argv[0]);
+
+  // This will hurt performance, but it's an option that's always available to you
+  // to force flush the logs. Otherwise TrafficServer will flush the logs around
+  // once every second. You should really avoid flushing the log unless it's really necessary.
+  log.flush();
+
+  GlobalPlugin *instance = new GlobalHookPlugin();
+}
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/logger_example/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/logger_example/Makefile.am b/lib/atscppapi/examples/logger_example/Makefile.am
new file mode 100644
index 0000000..404dd8c
--- /dev/null
+++ b/lib/atscppapi/examples/logger_example/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=LoggerExample.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = LoggerExample.la
+LoggerExample_la_SOURCES = LoggerExample.cc
+LoggerExample_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/multiple_transaction_hooks/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/multiple_transaction_hooks/Makefile.am b/lib/atscppapi/examples/multiple_transaction_hooks/Makefile.am
new file mode 100644
index 0000000..d56c921
--- /dev/null
+++ b/lib/atscppapi/examples/multiple_transaction_hooks/Makefile.am
@@ -0,0 +1,29 @@
+#
+#  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.
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=MultipleTransactionHookPlugins.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = MultipleTransactionHookPlugins.la
+MultipleTransactionHookPlugins_la_SOURCES = MultipleTransactionHookPlugins.cc
+MultipleTransactionHookPlugins_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc b/lib/atscppapi/examples/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
new file mode 100644
index 0000000..ce9db4d
--- /dev/null
+++ b/lib/atscppapi/examples/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
@@ -0,0 +1,100 @@
+/**
+  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 <iostream>
+#include <vector>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransactionPlugin.h>
+#include <atscppapi/PluginInit.h>
+
+using namespace atscppapi;
+
+class MultipleTransactionHookPluginsOne : public atscppapi::TransactionPlugin {
+public:
+  MultipleTransactionHookPluginsOne(Transaction &transaction) : TransactionPlugin(transaction) {
+    TransactionPlugin::registerHook(HOOK_SEND_RESPONSE_HEADERS);
+    std::cout << "Constructed MultipleTransactionHookPluginsOne!" << std::endl;
+  }
+
+  virtual ~MultipleTransactionHookPluginsOne() {
+    std::cout << "Destroyed MultipleTransactionHookPluginsOne!" << std::endl;
+  }
+
+  void handleSendResponseHeaders(Transaction &transaction) {
+    std::cerr << "MultipleTransactionHookPluginsOne -- Send response headers!" << std::endl;
+    transaction.resume();
+  }
+};
+
+class MultipleTransactionHookPluginsTwo : public atscppapi::TransactionPlugin {
+public:
+  MultipleTransactionHookPluginsTwo(Transaction &transaction) : TransactionPlugin(transaction) {
+    TransactionPlugin::registerHook(HOOK_SEND_REQUEST_HEADERS);
+    TransactionPlugin::registerHook(HOOK_SEND_RESPONSE_HEADERS);
+    std::cout << "Constructed MultipleTransactionHookPluginsTwo!" << std::endl;
+  }
+
+  virtual ~MultipleTransactionHookPluginsTwo() {
+    std::cout << "Destroyed MultipleTransactionHookPluginsTwo!" << std::endl;
+  }
+
+  void handleSendRequestHeaders(Transaction &transaction) {
+    std::cout << "MultipleTransactionHookPluginsTwo -- Send request headers!" << std::endl;
+    some_container_.push_back("We have transaction scoped storage in Transaction Hooks!");
+    transaction.resume();
+  }
+
+  void handleSendResponseHeaders(Transaction &transaction) {
+     std::cout << "MultipleTransactionHookPluginsTwo -- Send response headers!" << std::endl;
+
+     // Demonstrate the concept of transaction scoped storage.
+     if(some_container_.size()) {
+       std::cout << some_container_.back() << std::endl;
+     }
+
+     transaction.resume();
+   }
+
+private:
+  std::vector<std::string> some_container_;
+};
+
+class GlobalHookPlugin : public atscppapi::GlobalPlugin {
+public:
+  GlobalHookPlugin() {
+    GlobalPlugin::registerHook(HOOK_READ_REQUEST_HEADERS_PRE_REMAP);
+  }
+
+  virtual void handleReadRequestHeadersPreRemap(Transaction &transaction) {
+    std::cout << "Hello from handleReadRequesHeadersPreRemap!" << std::endl;
+
+    // We need not store the addresses of the transaction plugins
+    // because they will be cleaned up automatically when the transaction
+    // closes.
+
+    transaction.addPlugin(new MultipleTransactionHookPluginsOne(transaction));
+    transaction.addPlugin(new MultipleTransactionHookPluginsTwo(transaction));
+
+    transaction.resume();
+  }
+};
+
+void TSPluginInit(int argc, const char *argv[]) {
+  atscppapi::GlobalPlugin *instance = new GlobalHookPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7b2ea5f8/lib/atscppapi/examples/null_transformation_plugin/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/atscppapi/examples/null_transformation_plugin/Makefile.am b/lib/atscppapi/examples/null_transformation_plugin/Makefile.am
new file mode 100644
index 0000000..f41c64c
--- /dev/null
+++ b/lib/atscppapi/examples/null_transformation_plugin/Makefile.am
@@ -0,0 +1,30 @@
+#
+#  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.
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+target=NullTransformationPlugin.so
+pkglibdir = ${pkglibexecdir}
+pkglib_LTLIBRARIES = NullTransformationPlugin.la
+NullTransformationPlugin_la_SOURCES = NullTransformationPlugin.cc
+NullTransformationPlugin_la_LDFLAGS = -module -avoid-version -shared -L$(top_srcdir) -latscppapi
+
+all:
+	ln -sf .libs/$(target)
+
+clean-local:
+	rm -f $(target)