quick cpp 11 commit more changes to come

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

Branch: refs/heads/master
Commit: 7986be6188369778d55a4b275e258dddc9d1ae70
Parents: 1be0bfc
Author: Brian Geffon <[email protected]>
Authored: Mon Jul 23 12:56:20 2012 -0700
Committer: Brian Geffon <[email protected]>
Committed: Mon Jul 23 12:56:20 2012 -0700

----------------------------------------------------------------------
 configure.ac             |   15 +++
 lib/Makefile.am          |    4 +
 lib/cpp11api/Makefile.am |   28 +++++
 lib/cpp11api/cpp11api.cc |  231 +++++++++++++++++++++++++++++++++++++++++
 lib/cpp11api/ts-cpp11.h  |   70 +++++++++++++
 5 files changed, 348 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7986be61/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 2510ca3..696f871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -288,6 +288,20 @@ TS_ARG_ENABLE_VAR([has],[wccp])
 AC_SUBST(has_wccp)
 AM_CONDITIONAL([BUILD_WCCP], [test 0 -ne $has_wccp])
 
+#
+# CPP 11 API
+#
+AC_MSG_CHECKING([whether to enable c++11 api])
+AC_ARG_WITH([cpp11api],
+  [AS_HELP_STRING([--with-cpp11api],[enable support for cpp11api 
[default=no]])],
+  [cpp11api=$withval],
+  [cpp11api=no]
+)
+AC_MSG_RESULT([$cpp11api])
+AM_CONDITIONAL([BUILD_CPP11API], [test "$cpp11api" = yes])
+
+
+
 # Google profiler
 AC_MSG_CHECKING([whether to enable profiler])
 AC_ARG_WITH([profiler],
@@ -1485,6 +1499,7 @@ AC_CONFIG_FILES([iocore/utils/Makefile])
 AC_CONFIG_FILES([lib/Makefile])
 AC_CONFIG_FILES([lib/ts/Makefile])
 AC_CONFIG_FILES([lib/records/Makefile])
+AC_CONFIG_FILES([lib/cpp11api/Makefile])
 AC_CONFIG_FILES([lib/tsconfig/Makefile])
 AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([proxy/config/body_factory/default/Makefile])

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7986be61/lib/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3507cfb..7f70234 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -22,3 +22,7 @@ SUBDIRS = ts records
 if BUILD_WCCP
 SUBDIRS += tsconfig wccp
 endif
+
+if BUILD_CPP11API
+SUBDIRS += cpp11api
+endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7986be61/lib/cpp11api/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/cpp11api/Makefile.am b/lib/cpp11api/Makefile.am
new file mode 100644
index 0000000..6ea5e8b
--- /dev/null
+++ b/lib/cpp11api/Makefile.am
@@ -0,0 +1,28 @@
+# Makefile.am for C++11 API
+#
+#  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)/proxy/api/ts -std=c++11
+  
+lib_LTLIBRARIES = libatscpp11api.la
+
+libatscpp11api_la_SOURCES = \
+  cpp11api.cc
+  
+includedir=$(prefix)/include/ts
+include_HEADERS = \
+  ts-cpp11.h
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7986be61/lib/cpp11api/cpp11api.cc
----------------------------------------------------------------------
diff --git a/lib/cpp11api/cpp11api.cc b/lib/cpp11api/cpp11api.cc
new file mode 100644
index 0000000..d20ee3f
--- /dev/null
+++ b/lib/cpp11api/cpp11api.cc
@@ -0,0 +1,231 @@
+/** @file
+    @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.h>
+#include "ts-cpp11.h"
+
+using namespace ats::api;
+
+TSHttpHookID TSHookIDFromHookType(HookType hook);
+
+class HookContinuationData {
+public:
+  GlobalHookCallback callback;
+  HookType hooktype;
+  TSHttpHookID ts_hook_id;
+};
+
+class ats::api::Transaction {
+public:
+  TSHttpTxn ts_http_txn_ = NULL;
+  TSCont ts_contp_ = NULL;
+};
+
+extern "C" void TSPluginInit(int argc, const char *argv[]) {
+
+  TSPluginRegistrationInfo registration_info;
+
+  const char *api_version_string = "cpp11api";
+
+  registration_info.plugin_name = const_cast<char*>(api_version_string);
+  registration_info.vendor_name = const_cast<char*>(api_version_string);
+  registration_info.support_email = const_cast<char*>(api_version_string);
+
+  if (TSPluginRegister(TS_SDK_VERSION_3_0, &registration_info) != TS_SUCCESS) {
+    return;
+  }
+
+  StringVector arguments;
+  for (int i = 0; i < argc; ++i) {
+    arguments.push_back(std::string(argv[i]));
+  }
+
+  // Finally we will call the wrapper API registration point
+  PluginRegister(arguments);
+}
+
+TSHttpHookID TSHookIDFromHookType(HookType hook) {
+  switch (hook) {
+  case ats::api::HookType::HOOK_PRE_REMAP:
+    return TS_HTTP_PRE_REMAP_HOOK;
+    break;
+  case ats::api::HookType::HOOK_POST_REMAP:
+    return TS_HTTP_POST_REMAP_HOOK;
+    break;
+  case ats::api::HookType::HOOK_READ_REQUEST_HEADER:
+    return TS_HTTP_READ_REQUEST_HDR_HOOK;
+    break;
+  case ats::api::HookType::HOOK_READ_RESPONSE_HEADER:
+    return TS_HTTP_READ_RESPONSE_HDR_HOOK;
+    break;
+  case ats::api::HookType::HOOK_SEND_RESPONSE_HEADER:
+    return TS_HTTP_SEND_RESPONSE_HDR_HOOK;
+    break;
+  }
+
+  return TS_HTTP_READ_REQUEST_HDR_HOOK;
+}
+
+std::string ats::api::GetPristineRequestUrl(Transaction &t) {
+  TSMBuffer bufp;
+  TSMLoc url_loc;
+
+  if (TSHttpTxnPristineUrlGet(t.ts_http_txn_, &bufp, &url_loc) != TS_SUCCESS)
+    return std::string();
+
+  int url_len;
+  char *urlp = TSUrlStringGet(bufp, url_loc, &url_len);
+  std::string url(urlp, url_len);
+
+  TSfree(urlp);
+
+  TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc);
+
+  return url;
+}
+
+std::string ats::api::GetRequestUrl(Transaction &t) {
+  TSMBuffer bufp;
+  TSMLoc hdr_loc;
+  TSMLoc url_loc;
+
+  if (TSHttpTxnClientReqGet(t.ts_http_txn_, &bufp, &hdr_loc) != TS_SUCCESS)
+    return std::string();
+
+  TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc);
+
+  int url_len;
+  char *urlp = TSUrlStringGet(bufp, url_loc, &url_len);
+  std::string url(urlp, url_len);
+
+  TSfree(urlp);
+
+  TSHandleMLocRelease(bufp, hdr_loc, url_loc);
+  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+
+  return url;
+}
+
+std::string ats::api::GetRequestUrlPath(Transaction &t) {
+  TSMBuffer bufp;
+  TSMLoc hdr_loc;
+  TSMLoc url_loc;
+
+  if (TSHttpTxnClientReqGet(t.ts_http_txn_, &bufp, &hdr_loc) != TS_SUCCESS)
+    return std::string();
+
+  TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc);
+
+  int path_length;
+  const char *path = TSUrlPathGet(bufp, url_loc, &path_length);
+
+  std::string ret(path, path_length);
+
+  TSHandleMLocRelease(bufp, hdr_loc, url_loc);
+  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+
+  return ret;
+}
+
+void inline ReenableBasedOnNextState(TSHttpTxn txnp, NextState ns)
+{
+  switch (ns) {
+    case NextState::HTTP_DONT_CONTINUE:
+      return;
+      break;
+    case NextState::HTTP_ERROR:
+      TSHttpTxnReenable(txnp, static_cast<TSEvent>(TS_EVENT_HTTP_ERROR));
+      break;
+    case NextState::HTTP_CONTINUE:
+    default:
+      TSHttpTxnReenable(txnp, static_cast<TSEvent>(TS_EVENT_HTTP_CONTINUE));
+      break;
+    }
+}
+
+static int GlobalContinuationHandler(TSCont contp, TSEvent event, void *edata) 
{
+  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
+
+  Transaction transaction;
+  transaction.ts_http_txn_ = txnp;
+  transaction.ts_contp_ = contp;
+
+  HookContinuationData *data = 
static_cast<HookContinuationData*>(TSContDataGet(contp));
+  auto ns = data->callback(transaction);
+  ReenableBasedOnNextState(txnp, ns);
+
+  return 0;
+}
+
+static int TransactionContinuationHandler(TSCont contp, TSEvent event, void 
*edata) {
+  TSHttpTxn txnp = static_cast<TSHttpTxn>(edata);
+
+  Transaction transaction;
+  transaction.ts_http_txn_ = txnp;
+  transaction.ts_contp_ = contp;
+
+  NextState ns = NextState::HTTP_CONTINUE;
+  HookContinuationData *data = 
static_cast<HookContinuationData*>(TSContDataGet(contp));
+  if(event != TS_EVENT_HTTP_TXN_CLOSE || (event == TS_EVENT_HTTP_TXN_CLOSE && 
data->ts_hook_id == TS_HTTP_TXN_CLOSE_HOOK))
+  {
+    ns = data->callback(transaction);
+  }
+
+  // We must free the HookContinuationData structure and continuation
+  // If this transaction is complete
+  if(event == TS_EVENT_HTTP_TXN_CLOSE) {
+    delete data;
+    TSContDestroy(contp);
+  }
+
+  ReenableBasedOnNextState(txnp, ns);
+  return 0;
+}
+
+void ats::api::CreateTransactionHook(Transaction &txn, HookType hook, 
GlobalHookCallback callback) {
+  TSHttpHookID ts_hook_id = TSHookIDFromHookType(hook);
+  TSCont contp = TSContCreate(TransactionContinuationHandler, NULL);
+
+  HookContinuationData *data = new HookContinuationData();
+  data->callback = callback;
+  data->hooktype = hook;
+  data->ts_hook_id = ts_hook_id;
+
+  TSContDataSet(contp, static_cast<void*>(data));
+  TSHttpTxnHookAdd(txn.ts_http_txn_,ts_hook_id, contp);
+
+  if(ts_hook_id != TS_HTTP_TXN_CLOSE_HOOK) {
+    TSHttpTxnHookAdd(txn.ts_http_txn_,TS_HTTP_TXN_CLOSE_HOOK, contp);
+  }
+}
+
+void ats::api::CreateGlobalHook(HookType hook, GlobalHookCallback callback) {
+
+  TSHttpHookID ts_hook_id = TSHookIDFromHookType(hook);
+  TSCont contp = TSContCreate(GlobalContinuationHandler, NULL);
+
+  HookContinuationData *data = new HookContinuationData();
+  data->callback = callback;
+  data->hooktype = hook;
+
+  TSContDataSet(contp, static_cast<void*>(data));
+  TSHttpHookAdd(ts_hook_id, contp);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7986be61/lib/cpp11api/ts-cpp11.h
----------------------------------------------------------------------
diff --git a/lib/cpp11api/ts-cpp11.h b/lib/cpp11api/ts-cpp11.h
new file mode 100644
index 0000000..3fdd2ed
--- /dev/null
+++ b/lib/cpp11api/ts-cpp11.h
@@ -0,0 +1,70 @@
+/** @file
+    @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.
+ */
+
+#ifndef TS_CPP11_H_
+#define TS_CPP11_H_
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#error The C++ Apache Traffic Server API wrapper requires C++11 support.
+#endif
+
+#include <functional>
+#include <string>
+#include <vector>
+
+namespace ats {
+namespace api {
+typedef std::vector<std::string> StringVector;
+
+enum class HookType {
+  HOOK_PRE_REMAP = 100, HOOK_POST_REMAP, HOOK_READ_RESPONSE_HEADER, 
HOOK_READ_REQUEST_HEADER, HOOK_SEND_RESPONSE_HEADER
+};
+
+enum class NextState {
+  HTTP_CONTINUE = 200, HTTP_ERROR, HTTP_DONT_CONTINUE
+};
+
+class Transaction;
+
+/*
+ * This is the type our global hook callbacks will take
+ */
+typedef std::function<NextState(Transaction &)> GlobalHookCallback;
+
+/*
+ * Create a new hook
+ */
+void CreateGlobalHook(HookType, GlobalHookCallback);
+void CreateTransactionHook(Transaction &, HookType, GlobalHookCallback);
+
+std::string GetPristineRequestUrl(Transaction &);
+std::string GetRequestUrl(Transaction &);
+std::string GetRequestUrlPath(Transaction &);
+
+}
+}
+
+/*
+ * Every plugin must have a simple entry point
+ */
+void PluginRegister(const ats::api::StringVector &);
+
+
+#endif /* TS_CPP11_H_ */

Reply via email to