This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 36bbf69aca Foundation laid for global Cripts (#11793)
36bbf69aca is described below
commit 36bbf69acafc889f3b0a23c5b9d1ebedf87d19fc
Author: Leif Hedstrom <[email protected]>
AuthorDate: Tue Oct 15 20:11:14 2024 -0600
Foundation laid for global Cripts (#11793)
* Foundation laid for global Cripts
* Try to fix the enumerated and non-enumerated type errors
* Added documentation for the global hooks
* Fix doc typos, thanks bcall
---
doc/developer-guide/cripts/cripts-global.en.rst | 153 +++++++
doc/developer-guide/cripts/index.en.rst | 1 +
example/cripts/global.cc | 83 ++++
include/cripts/Bundle.hpp | 2 +-
include/cripts/Context.hpp | 10 +-
include/cripts/Epilogue.hpp | 518 +++++++++++++++++++++---
include/cripts/Instance.hpp | 8 +-
include/cripts/Preamble.hpp | 26 +-
include/cripts/Transaction.hpp | 29 +-
src/cripts/Instance.cc | 22 +-
src/cripts/Urls.cc | 17 +-
11 files changed, 773 insertions(+), 96 deletions(-)
diff --git a/doc/developer-guide/cripts/cripts-global.en.rst
b/doc/developer-guide/cripts/cripts-global.en.rst
new file mode 100644
index 0000000000..56fd35bb35
--- /dev/null
+++ b/doc/developer-guide/cripts/cripts-global.en.rst
@@ -0,0 +1,153 @@
+.. 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:: ../../common.defs
+
+.. highlight:: cpp
+.. default-domain:: cpp
+
+.. _cripts-global:
+
+Cripts for global plugin
+************************
+
+In addition to be a scripting language for per-property, or remap rules,
Cripts can
+also be used to write global ATS plugins. This is a more advanced use case,
and requires
+some knowledge of how ATS works.
+
+The automatic building of plugins that Cripts supports as a remap rule is not
available
+(yet) to global plugins. As such, you must compile any global plugin manually.
You can
+see this as an alternative to writing a plugin in regular C++, in fact you can
still
+combine a global plugin with a remap rule plugin in the same Cript file.
+
+Usage
+=====
+
+As with remap rules, global Cripts still requires both the preamble as well as
the epilogue.
+However, all callbacks are prefixed with ``glb_`` to indicate that they are
global hooks.
+See the hooks below for more details. Example:
+
+The third step is to put the Cript file in either the configuration or plugin
installation,
+depending on your preference. The file must be readable by the ATS process.
Example:
+
+.. code-block:: cpp
+
+ #include <cripts/Preamble.hpp>
+
+ glb_read_request()
+ {
+ borrow url = cripts::Client::URL::get();
+
+ url.query.keep({"foo", "bar"});
+ }
+
+ #include <cripts/Epilogue.hpp>
+
+Hooks
+=====
+
+Hooks are the main way to interact with ATS. The hooks are the same as the ATS
hooks,
+but with a few differences. The hooks are all in the global namespace, and the
hooks
+are all functions. Cripts provides a core set of hooks which are always
available,
+but they are not required to be used.
+
+Not all ATS hooks are available in Cripts, but the most common ones are. Hooks
are
+implicitly called if they are defined in the Cript file. The Cript will never
explicitly
+setup the hooks, as this is done by the ATS process.
+
+Normal Hooks
+------------
+
+Lets look at the normal hooks that are available in Cripts. Note here that the
name
+of the function dictates the underlying ATS hook.
+
+.. _cripts-global-hooks-txn-start:
+
+glb_txn_start()
+^^^^^^^^^^^^^^^
+
+The ``glb_txn_start()`` hook is called at the beginning of a transaction. This
is also
+where Cripts will setup other HTTP hooks as necessary. Note that in this hook,
the
+client request has not yet been read, so you cannot access the request headers.
+
+.. _cripts-global-hooks-read-request:
+
+glb_read_request()
+^^^^^^^^^^^^^^^^^^
+
+The ``glb_read_request()`` hook is called after the client request has been
read. This
+means that you can access the request headers, and the request URL. However,
remap rules
+has not yet been applied, so the URL may not be the final URL, or even
complete.
+
+.. _cripts-global-hooks-pre-remap:
+
+glb_pre_remap()
+^^^^^^^^^^^^^^^
+
+This hook may not be particularly useful in Cripts, as remap rules are not
applied here yet
+as well. We've added it for completeness.
+
+.. _cripts-global-hooks-post-remap:
+
+glb_post_remap()
+^^^^^^^^^^^^^^^^
+
+The ``glb_post_remap()`` hook is called after remap rules have been applied.
This is the
+closest to the ``do_remap()`` hook in remap rules.
+
+.. _cripts-global-hooks-cache_lookup:
+
+glb_cache_lookup()
+^^^^^^^^^^^^^^^^^^
+
+This is identical to the :ref:`cripts-overview-hooks-do-cache-lookup` hook in
remap rules.
+
+.. _cripts-global-hooks-send-request:
+
+glb_send_request()
+^^^^^^^^^^^^^^^^^^
+
+This is identical to the :ref:`cripts-overview-hooks-do-send-request` hook in
remap rules.
+
+.. _cripts-global-hooks-read_response:
+
+glb_read_response()
+^^^^^^^^^^^^^^^^^^^
+
+This is identical to the :ref:`cripts-overview-hooks-do-read-response` hook in
remap rules.
+
+.. _cripts-global-hooks-send_response:
+
+glb_send_response()
+^^^^^^^^^^^^^^^^^^^
+
+This is identical to the :ref:`cripts-overview-hooks-do-send-response` hook in
remap rules.
+
+.. _cripts-global-hooks-txn-close:
+
+glb_txn_close()
+^^^^^^^^^^^^^^^
+
+This is identical to the :ref:`cripts-overview-hooks-do-txn-close` hook in
remap rules.
+
+.. _cripts-global-hooks-init:
+
+glb_init()
+^^^^^^^^^^
+
+This callback is called when the plugin is loaded. This is where you can setup
any
+global state that you need etc.
diff --git a/doc/developer-guide/cripts/index.en.rst
b/doc/developer-guide/cripts/index.en.rst
index 155b055deb..c1fb057817 100644
--- a/doc/developer-guide/cripts/index.en.rst
+++ b/doc/developer-guide/cripts/index.en.rst
@@ -26,6 +26,7 @@ Cripts
:maxdepth: 2
cripts-overview.en
+ cripts-global.en
cripts-variables.en
cripts-urls.en
cripts-headers.en
diff --git a/example/cripts/global.cc b/example/cripts/global.cc
new file mode 100644
index 0000000000..d598884c63
--- /dev/null
+++ b/example/cripts/global.cc
@@ -0,0 +1,83 @@
+/*
+ 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.
+*/
+
+// The primary include file, this has to always be included
+#include <cripts/Preamble.hpp>
+
+glb_init()
+{
+ CDebug("Called glb_init()");
+}
+
+glb_txn_start()
+{
+ CDebug("Called glb_txn_start()");
+}
+
+glb_txn_close()
+{
+ CDebug("Called glb_txn_close()");
+}
+
+glb_read_request()
+{
+ borrow req = cripts::Client::Request::Get();
+ borrow url = cripts::Client::URL::Get();
+
+ CDebug("Called glb_read_request()");
+ CDebug("Host Header: {}", req["Host"]);
+ CDebug("Path: {}", url.path);
+}
+
+glb_pre_remap()
+{
+ borrow url = cripts::Client::URL::Get();
+
+ CDebug("Called glb_pre_remap()");
+ CDebug("Client URL: {}", url.String());
+}
+
+glb_post_remap()
+{
+ borrow url = cripts::Client::URL::Get();
+
+ CDebug("Called glb_post_remap()");
+ CDebug("Client URL: {}", url.String());
+}
+
+glb_cache_lookup()
+{
+ CDebug("Called glb_cache_lookup()");
+}
+
+glb_send_request()
+{
+ CDebug("Called glb_send_request()");
+}
+
+glb_read_response()
+{
+ CDebug("Called glb_read_response()");
+}
+
+glb_send_response()
+{
+ CDebug("Called glb_send_response()");
+}
+
+#include <cripts/Epilogue.hpp>
diff --git a/include/cripts/Bundle.hpp b/include/cripts/Bundle.hpp
index 87d5cb30f1..8ba0749ab5 100644
--- a/include/cripts/Bundle.hpp
+++ b/include/cripts/Bundle.hpp
@@ -147,7 +147,7 @@ namespace Bundle
}
protected:
- unsigned _callbacks = 0;
+ uint32_t _callbacks = 0;
}; // Class Base
} // namespace Bundle
diff --git a/include/cripts/Context.hpp b/include/cripts/Context.hpp
index ccc40a2842..6e1520e283 100644
--- a/include/cripts/Context.hpp
+++ b/include/cripts/Context.hpp
@@ -59,11 +59,11 @@ public:
void Release();
// These fields are preserving the parameters as setup in DoRemap()
- cripts::Transaction state;
- std::array<DataType, CONTEXT_DATA_SLOTS> data;
- TSCont default_cont = nullptr;
- TSRemapRequestInfo *rri = nullptr;
- cripts::Instance &p_instance; // p_ == public_, since
we can't use "instance"
+ cripts::Transaction state; // This is the
transaction state
+ std::array<DataType, CONTEXT_DATA_SLOTS> data; // Context data
+ TSCont contp = nullptr; // Remap or global
continuation
+ TSRemapRequestInfo *rri = nullptr; // This may be
nullptr, if not a remap
+ cripts::Instance &p_instance; // p_ == public_,
since we can't use "instance"
// These are private, but needs to be visible to our friend classes that
// depends on the Context.
diff --git a/include/cripts/Epilogue.hpp b/include/cripts/Epilogue.hpp
index 836e677c36..6c63818faf 100644
--- a/include/cripts/Epilogue.hpp
+++ b/include/cripts/Epilogue.hpp
@@ -68,7 +68,7 @@ wrap_do_remap(T * /* context ATS_UNUSED */, bool /* execute
ATS_UNUSED */, CaseT
return false;
}
-// send-response-header hook caller
+// post-remap-header hook caller
template <typename T>
auto
wrap_post_remap(T *context, bool execute, CaseTag<1>) ->
decltype(_do_post_remap(context), bool())
@@ -233,120 +233,382 @@ wrap_delete_instance(T * /* context ATS_UNUSED */, bool
/* execute ATS_UNUSED */
return false;
}
-// This is the default continuation handler, for all do_*() callbacks
+// Next are all the wrappers for the global hooks. We intentionally name and
handle these different,
+// to allow a Cript to define both global and per remap hooks.
+
+// global txn-start hook caller
+template <typename T>
+auto
+wrap_glb_txn_start(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_txn_start(context), bool())
+{
+ if (execute) {
+ _glb_txn_start(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_txn_start(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global read-request hook caller
+template <typename T>
+auto
+wrap_glb_read_request(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_read_request(context), bool())
+{
+ if (execute) {
+ _glb_read_request(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_read_request(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global pre-remap hook caller
+template <typename T>
+auto
+wrap_glb_pre_remap(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_pre_remap(context), bool())
+{
+ if (execute) {
+ _glb_pre_remap(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_pre_remap(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global post-remap hook caller
+template <typename T>
+auto
+wrap_glb_post_remap(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_post_remap(context), bool())
+{
+ if (execute) {
+ _glb_post_remap(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_post_remap(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global cache-lookup hook caller
+template <typename T>
+auto
+wrap_glb_cache_lookup(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_cache_lookup(context), bool())
+{
+ if (execute) {
+ _glb_cache_lookup(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_cache_lookup(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global send-request hook caller
+template <typename T>
+auto
+wrap_glb_send_request(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_send_request(context), bool())
+{
+ if (execute) {
+ _glb_send_request(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_send_request(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global read-response hook caller
+template <typename T>
+auto
+wrap_glb_read_response(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_read_response(context), bool())
+{
+ if (execute) {
+ _glb_read_response(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_read_response(T * /* context ATS_UNUSED */, bool /* execute
ATS_UNUSED */, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global send-response hook caller
+template <typename T>
+auto
+wrap_glb_send_response(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_send_response(context), bool())
+{
+ if (execute) {
+ _glb_send_response(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_send_response(T * /* context ATS_UNUSED */, bool /* execute
ATS_UNUSED */, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// global txn-close hook caller
+template <typename T>
+auto
+wrap_glb_txn_close(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_txn_close(context), bool())
+{
+ if (execute) {
+ _glb_txn_close(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_txn_close(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED
*/, CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// glb_init caller (not a hook, called when the global plugin is initialized).
+template <typename T>
+auto
+wrap_glb_init(T *context, bool execute, CaseTag<1>) ->
decltype(_glb_init(context), bool())
+{
+ if (execute) {
+ _glb_init(context);
+ }
+ return true;
+}
+
+template <typename T>
+auto
+wrap_glb_init(T * /* context ATS_UNUSED */, bool /* execute ATS_UNUSED */,
CaseTag<0>) -> bool
+{
+ return false;
+}
+
+// This is the HTTP transaction continuation, which is used for all the HTTP
hooks.
int
-default_cont(TSCont contp, TSEvent event, void *edata)
+http_txn_cont(TSCont contp, TSEvent event, void *edata)
{
auto txnp = static_cast<TSHttpTxn>(edata);
auto *context = static_cast<cripts::Context *>(TSContDataGet(contp));
+ // ToDo: We can optimize this once we have header heap generation IDs in
place.
context->reset(); // Clears the cached handles to internal ATS data (mloc's
etc.)
switch (event) {
- case TS_EVENT_HTTP_SEND_REQUEST_HDR:
- context->state.hook = TS_HTTP_SEND_REQUEST_HDR_HOOK;
+ // This is only used for global plugin, sine DoRemap() is handled without
a continuation
+ case TS_EVENT_HTTP_READ_REQUEST_HDR: // 60002
+ context->state.hook = TS_HTTP_READ_REQUEST_HDR_HOOK;
if (!context->state.error.Failed()) {
- CDebug("Entering do_send_request()");
+ // Call any bundle callbacks that are registered for this hook
+ if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::GLB_READ_REQUEST) {
+ for (auto &bundle : context->p_instance.bundles) {
+ if (bundle->Callbacks() & cripts::Callbacks::GLB_READ_REQUEST) {
+ bundle->doSendRequest(context);
+ }
+ }
+ }
+ CDebug("Entering glb_read_request()");
+ wrap_glb_read_request(context, true, CaseArg);
+ cripts::Client::URL::_get(context).Update(); // Make sure any changes to
the request URL is updated
+ }
+ break;
+ case TS_EVENT_HTTP_SEND_REQUEST_HDR: // 60004
+ context->state.hook = TS_HTTP_SEND_REQUEST_HDR_HOOK;
+ if (!context->state.error.Failed()) {
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_SEND_REQUEST) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() &
(cripts::Callbacks::DO_SEND_REQUEST | cripts::Callbacks::GLB_SEND_REQUEST)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_SEND_REQUEST) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_SEND_REQUEST |
cripts::Callbacks::GLB_SEND_REQUEST)) {
bundle->doSendRequest(context);
}
}
}
- wrap_send_request(context, true, CaseArg);
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_TXN_CLOSE) {
+ CDebug("Entering do_send_request()");
+ wrap_send_request(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_SEND_REQUEST) {
+ CDebug("Entering glb_send_request()");
+ wrap_glb_send_request(context, true, CaseArg);
+ }
cripts::Client::URL::_get(context).Update(); // Make sure any changes to
the request URL is updated
}
break;
+
case TS_EVENT_HTTP_READ_RESPONSE_HDR: // 60006
context->state.hook = TS_HTTP_READ_RESPONSE_HDR_HOOK;
if (!context->state.error.Failed()) {
- CDebug("Entering do_read_response()");
-
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_READ_RESPONSE) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() &
(cripts::Callbacks::DO_READ_RESPONSE | cripts::Callbacks::GLB_READ_RESPONSE)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_READ_RESPONSE) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_READ_RESPONSE |
cripts::Callbacks::GLB_READ_RESPONSE)) {
bundle->doReadResponse(context);
}
}
}
- wrap_read_response(context, true, CaseArg);
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_READ_RESPONSE) {
+ CDebug("Entering do_read_response()");
+ wrap_read_response(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_READ_RESPONSE) {
+ CDebug("Entering glb_read_response()");
+ wrap_glb_read_response(context, true, CaseArg);
+ }
}
break;
+
case TS_EVENT_HTTP_SEND_RESPONSE_HDR: // 60007
context->state.hook = TS_HTTP_SEND_RESPONSE_HDR_HOOK;
if (!context->state.error.Failed()) {
CDebug("Entering do_send_response()");
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_SEND_RESPONSE) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() &
(cripts::Callbacks::DO_SEND_RESPONSE | cripts::Callbacks::GLB_SEND_RESPONSE)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_SEND_RESPONSE) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_SEND_RESPONSE |
cripts::Callbacks::GLB_SEND_RESPONSE)) {
bundle->doSendResponse(context);
}
}
}
- wrap_send_response(context, true, CaseArg);
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_SEND_RESPONSE) {
+ wrap_send_response(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_SEND_RESPONSE) {
+ wrap_glb_send_response(context, true, CaseArg);
+ }
}
break;
+
case TS_EVENT_HTTP_TXN_CLOSE: // 60012
context->state.hook = TS_HTTP_TXN_CLOSE_HOOK;
- if (context->state.enabled_hooks & cripts::Callbacks::DO_TXN_CLOSE) {
- CDebug("Entering do_txn_close()");
-
+ if (context->state.enabled_hooks & (cripts::Callbacks::DO_TXN_CLOSE |
cripts::Callbacks::GLB_TXN_CLOSE)) {
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_TXN_CLOSE) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() & (cripts::Callbacks::DO_TXN_CLOSE |
cripts::Callbacks::GLB_TXN_CLOSE)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_TXN_CLOSE) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_TXN_CLOSE |
cripts::Callbacks::GLB_TXN_CLOSE)) {
bundle->doTxnClose(context);
}
}
}
- wrap_txn_close(context, true, CaseArg);
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_TXN_CLOSE) {
+ CDebug("Entering do_txn_close()");
+ wrap_txn_close(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_TXN_CLOSE) {
+ CDebug("Entering glb_txn_close()");
+ wrap_glb_txn_close(context, true, CaseArg);
+ }
}
TSContDestroy(contp);
context->Release();
break;
+
case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: // 60015
context->state.hook = TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK;
if (!context->state.error.Failed()) {
- CDebug("Entering do_cache_lookup()");
-
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_CACHE_LOOKUP) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() &
(cripts::Callbacks::DO_CACHE_LOOKUP | cripts::Callbacks::GLB_CACHE_LOOKUP)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_CACHE_LOOKUP) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_CACHE_LOOKUP |
cripts::Callbacks::GLB_CACHE_LOOKUP)) {
bundle->doCacheLookup(context);
}
}
}
- wrap_cache_lookup(context, true, CaseArg);
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_CACHE_LOOKUP) {
+ CDebug("Entering do_cache_lookup()");
+ wrap_cache_lookup(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_CACHE_LOOKUP) {
+ CDebug("Entering glb_cache_lookup()");
+ wrap_cache_lookup(context, true, CaseArg);
+ }
}
break;
+
+ case TS_EVENT_HTTP_PRE_REMAP: // 60016, this is never usable in a remap
plugin
+ context->state.hook = TS_HTTP_PRE_REMAP_HOOK;
+
+ // Call any bundle callbacks that are registered for this hook
+ if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::GLB_PRE_REMAP) {
+ for (auto &bundle : context->p_instance.bundles) {
+ if (bundle->Callbacks() & (cripts::Callbacks::GLB_PRE_REMAP)) {
+ bundle->doPostRemap(context);
+ }
+ }
+ }
+
+ if (context->state.enabled_hooks & cripts::Callbacks::GLB_PRE_REMAP) {
+ CDebug("Entering glb_pre_remap()");
+ wrap_glb_pre_remap(context, true, CaseArg);
+ }
+
+ if (!context->state.error.Failed()) {
+ cripts::Cache::URL::_get(context).Update(); // Make sure the cache-key
gets updated, if modified
+ cripts::Client::URL::_get(context).Update(); // Make sure any changes to
the request URL is updated
+ }
+ break;
+
case TS_EVENT_HTTP_POST_REMAP: // 60017
context->state.hook = TS_HTTP_POST_REMAP_HOOK;
- CDebug("Entering do_post_remap()");
// Call any bundle callbacks that are registered for this hook
- if (!context->state.error.Failed() && context->p_instance.Callbacks() &
cripts::Callbacks::DO_POST_REMAP) {
+ if (!context->state.error.Failed() &&
+ context->p_instance.Callbacks() & (cripts::Callbacks::DO_POST_REMAP |
cripts::Callbacks::GLB_POST_REMAP)) {
for (auto &bundle : context->p_instance.bundles) {
- if (bundle->Callbacks() & cripts::Callbacks::DO_POST_REMAP) {
+ if (bundle->Callbacks() & (cripts::Callbacks::DO_POST_REMAP |
cripts::Callbacks::GLB_POST_REMAP)) {
bundle->doPostRemap(context);
}
}
}
- wrap_post_remap(context, true, CaseArg);
+
+ if (context->state.enabled_hooks & cripts::Callbacks::DO_POST_REMAP) {
+ CDebug("Entering do_post_remap()");
+ wrap_post_remap(context, true, CaseArg);
+ } else if (context->state.enabled_hooks &
cripts::Callbacks::GLB_POST_REMAP) {
+ CDebug("Entering glb_post_remap()");
+ wrap_glb_post_remap(context, true, CaseArg);
+ }
if (!context->state.error.Failed()) {
cripts::Cache::URL::_get(context).Update(); // Make sure the cache-key
gets updated, if modified
cripts::Client::URL::_get(context).Update(); // Make sure any changes to
the request URL is updated
}
break;
- // This is for cleanup, and should always be called / wrapped
+
default:
CFatal("Cripts continuation: Unknown event %d", event);
break;
@@ -356,6 +618,137 @@ default_cont(TSCont contp, TSEvent event, void *edata)
return 0;
}
+// This is the global continuation, used to deal with various hooks as well as
setting up
+// a per TXN continuation if needed. ToDo: Other non-TXN hooks should be added
here.
+int
+global_cont(TSCont contp, TSEvent event, void *edata)
+{
+ // Duplicated, but this is cheap and we don't need it in the instance.
+ static bool has_glb_txn_start =
wrap_glb_txn_start(static_cast<cripts::Context *>(nullptr), false, CaseArg);
+
+ auto glb_ctx = static_cast<cripts::InstanceContext
*>(TSContDataGet(contp));
+ auto txnp = static_cast<TSHttpTxn>(edata);
+ auto ssnp = TSHttpTxnSsnGet(txnp);
+ auto enabled_hooks = glb_ctx->p_instance.Callbacks();
+
+ switch (event) {
+ case TS_EVENT_HTTP_TXN_START: {
+ auto *context = cripts::Context::Factory(txnp, ssnp, nullptr,
glb_ctx->p_instance);
+
+ context->state.hook = TS_HTTP_TXN_START_HOOK;
+ context->state.enabled_hooks = enabled_hooks;
+
+ if (has_glb_txn_start) {
+ wrap_glb_txn_start(context, true, CaseArg);
+ }
+
+ if (enabled_hooks) {
+ context->contp = TSContCreate(http_txn_cont, nullptr);
+ TSContDataSet(context->contp, context);
+ if (enabled_hooks & cripts::Callbacks::GLB_READ_REQUEST) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_PRE_REMAP) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_PRE_REMAP_HOOK, context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_POST_REMAP) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_POST_REMAP_HOOK, context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_CACHE_LOOKUP) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK,
context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_SEND_REQUEST) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_REQUEST_HDR_HOOK, context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_READ_RESPONSE) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, context->contp);
+ }
+ if (enabled_hooks & cripts::Callbacks::GLB_SEND_RESPONSE) {
+ TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, context->contp);
+ }
+ TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, context->contp); //
Release the context later
+ } else {
+ context->Release();
+ }
+ } break;
+
+ // ToDo: Add handlers for other non-HTTP hooks here.
+
+ default:
+ CFatal("Cripts continuation: Unknown event %d", event);
+ break;
+ }
+
+ TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
+ return 0;
+}
+
+extern void global_initialization();
+extern pthread_once_t init_once_control;
+
+// This sets up this Cript as a global plugin. This uses the glb_ prefix for
all
+// the callbacks. This would only be called if the cript is added to
plugins.config.
+void
+TSPluginInit(int argc, const char *argv[])
+{
+ static bool has_glb_txn_start =
wrap_glb_txn_start(static_cast<cripts::Context *>(nullptr), false, CaseArg);
+ static unsigned enabled_txn_hooks =
+ (wrap_glb_read_request(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_READ_REQUEST :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_pre_remap(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_PRE_REMAP :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_post_remap(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_POST_REMAP :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_cache_lookup(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_CACHE_LOOKUP :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_send_request(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_SEND_REQUEST :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_read_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_READ_RESPONSE :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_send_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_SEND_RESPONSE :
+
cripts::Callbacks::NONE) |
+ (wrap_glb_txn_close(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::GLB_TXN_CLOSE :
+
cripts::Callbacks::NONE);
+ // ToDo: Add more global hooks here in enabled_other_hooks
+
+ TSPluginRegistrationInfo info;
+ auto *inst = new cripts::Instance(argc, argv, false);
+
+ info.plugin_name = (char *)inst->plugin_debug_tag.c_str();
+ info.vendor_name = (char *)"Apache Software Foundation";
+ info.support_email = (char *)"[email protected]";
+
+ if (TS_SUCCESS != TSPluginRegister(&info)) {
+ TSError("[%s] plugin registration failed", info.plugin_name);
+ delete inst;
+ return;
+ }
+
+ // ToDo: This InstanceContext should also be usabled / used by other
non-HTTP hooks.
+ cripts::InstanceContext *context = new cripts::InstanceContext(*inst);
+
+ pthread_once(&init_once_control, global_initialization);
+ bool needs_glb_init = wrap_glb_init(context, false, CaseArg);
+
+ if (needs_glb_init) {
+ wrap_glb_init(context, true, CaseArg);
+ }
+
+ if (has_glb_txn_start || enabled_txn_hooks > 0) {
+ auto contp = TSContCreate(global_cont, nullptr);
+
+ inst->NeedCallback(enabled_txn_hooks);
+ TSContDataSet(contp, context);
+ TSHttpHookAdd(TS_HTTP_TXN_START_HOOK, contp); // This acts similarly to
the DoRemap callback
+ } else {
+ delete context;
+ delete inst;
+ TSError("[%s] - No global hooks enabled", info.plugin_name);
+ }
+}
+
+// This section is for Cripts as a remap plugin. They all use the do_ prefix
for all
+// callbacks.
TSReturnCode
TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
{
@@ -375,28 +768,25 @@ TSRemapInit(TSRemapInterface *api_info, char *errbuf, int
errbuf_size)
return TS_ERROR;
}
- // This is to check, and call, the Cript's do_init() if provided.
- // Note that the context here is not a Cript context, but rather tha API info
- extern void global_initialization();
- extern pthread_once_t init_once_control;
-
pthread_once(&init_once_control, global_initialization);
+ // This is to check, and call, the Cript's do_init() if provided.
+ // Note that the context here is not a Cript context, but rather tha API info
bool needs_plugin_init = wrap_plugin_init(api_info, false, CaseArg);
if (needs_plugin_init) {
wrap_plugin_init(api_info, true, CaseArg);
}
- // TSDebug("Cript", "Remap plugin %s is successfully initialized",
__BASE_FILE__);
-
return TS_SUCCESS;
}
TSReturnCode
-TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf
ATS_UNUSED */, int /* errbuf_size ATS_UNUSED */)
+TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf
ATS_UNUSED */
+ ,
+ int /* errbuf_size ATS_UNUSED */)
{
- auto *inst = new cripts::Instance(argc, argv);
+ auto *inst = new cripts::Instance(argc, const_cast<const
char **>(argv));
cripts::InstanceContext context(*inst);
bool needs_create_instance =
wrap_create_instance(&context, false, CaseArg);
@@ -461,14 +851,20 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp,
TSRemapRequestInfo *rri)
{
// Check to see if we need to setup future hooks with a continuation. This
// should only happen once.
- static bool cript_needs_do_remap =
wrap_do_remap(static_cast<cripts::Context *>(nullptr), false, CaseArg);
- static unsigned cript_enabled_hooks =
- (wrap_post_remap(static_cast<cripts::Context *>(nullptr), false, CaseArg)
? cripts::Callbacks::DO_POST_REMAP : 0) |
- (wrap_send_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_SEND_RESPONSE : 0) |
- (wrap_send_request(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_SEND_REQUEST : 0) |
- (wrap_read_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_READ_RESPONSE : 0) |
- (wrap_cache_lookup(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_CACHE_LOOKUP : 0) |
- (wrap_txn_close(static_cast<cripts::Context *>(nullptr), false, CaseArg) ?
cripts::Callbacks::DO_TXN_CLOSE : 0);
+ static bool needs_do_remap = wrap_do_remap(static_cast<cripts::Context
*>(nullptr), false, CaseArg);
+ static uint32_t enabled_hooks =
+ (wrap_post_remap(static_cast<cripts::Context *>(nullptr), false, CaseArg)
? cripts::Callbacks::DO_POST_REMAP :
+
cripts::Callbacks::NONE) |
+ (wrap_cache_lookup(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_CACHE_LOOKUP :
+
cripts::Callbacks::NONE) |
+ (wrap_send_request(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_SEND_REQUEST :
+
cripts::Callbacks::NONE) |
+ (wrap_read_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_READ_RESPONSE :
+
cripts::Callbacks::NONE) |
+ (wrap_send_response(static_cast<cripts::Context *>(nullptr), false,
CaseArg) ? cripts::Callbacks::DO_SEND_RESPONSE :
+
cripts::Callbacks::NONE) |
+ (wrap_txn_close(static_cast<cripts::Context *>(nullptr), false, CaseArg) ?
cripts::Callbacks::DO_TXN_CLOSE :
+
cripts::Callbacks::NONE);
TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp);
auto *inst = static_cast<cripts::Instance *>(ih);
@@ -477,9 +873,9 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo
*rri)
bool keep_context = false;
context->state.hook = TS_HTTP_READ_REQUEST_HDR_HOOK; // Not quite
true
- context->state.enabled_hooks = (cript_enabled_hooks | bundle_cbs);
+ context->state.enabled_hooks = (enabled_hooks | bundle_cbs);
- if (cript_needs_do_remap || bundle_cbs & cripts::Callbacks::DO_REMAP) {
+ if (needs_do_remap || bundle_cbs & cripts::Callbacks::DO_REMAP) {
CDebug("Entering do_remap()");
for (auto &bundle : context->p_instance.bundles) {
bundle->doRemap(context);
@@ -495,32 +891,32 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp,
TSRemapRequestInfo *rri)
cripts::Client::URL::_get(context).Update(); // Make sure any changes to
the request URL is updated
if (context->state.enabled_hooks >= cripts::Callbacks::DO_POST_REMAP) {
- context->default_cont = TSContCreate(default_cont, nullptr);
- TSContDataSet(context->default_cont, context);
+ context->contp = TSContCreate(http_txn_cont, nullptr);
+ TSContDataSet(context->contp, context);
if (context->state.enabled_hooks & cripts::Callbacks::DO_POST_REMAP) {
- TSHttpTxnHookAdd(txnp, TS_HTTP_POST_REMAP_HOOK, context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_POST_REMAP_HOOK, context->contp);
}
if (context->state.enabled_hooks & cripts::Callbacks::DO_SEND_RESPONSE) {
- TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK,
context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, context->contp);
}
if (context->state.enabled_hooks & cripts::Callbacks::DO_SEND_REQUEST) {
- TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_REQUEST_HDR_HOOK,
context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_REQUEST_HDR_HOOK, context->contp);
}
if (context->state.enabled_hooks & cripts::Callbacks::DO_READ_RESPONSE) {
- TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK,
context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, context->contp);
}
if (context->state.enabled_hooks & cripts::Callbacks::DO_CACHE_LOOKUP) {
- TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK,
context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK,
context->contp);
}
- // This is always needed when we have at least one Txn Hook. It will also
+ // This iremaps needed when we have at least one Txn Hook. It will also
// call the Cript's callback, if it exists.
- TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, context->default_cont);
+ TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, context->contp);
// Make sure we keep the context
keep_context = true;
diff --git a/include/cripts/Instance.hpp b/include/cripts/Instance.hpp
index ca6ae766b4..b5317f9efd 100644
--- a/include/cripts/Instance.hpp
+++ b/include/cripts/Instance.hpp
@@ -44,7 +44,7 @@ public:
void operator=(const self_type &) = delete;
// This has to be in the .hpp file, otherwise we will not get the correct
debug tag!
- Instance(int argc, char *argv[]) { _initialize(argc, argv, __BASE_FILE__); }
+ Instance(int argc, const char *argv[], bool remap = true) {
_initialize(argc, argv, __BASE_FILE__, remap); }
~Instance()
{
plugins.clear();
@@ -58,7 +58,7 @@ public:
bool DeletePlugin(const cripts::string &tag);
void AddBundle(cripts::Bundle::Base *bundle);
- // This allows Bundles to require hooks as well.
+ // This allows Bundles and global plugins to require hooks as well.
void
NeedCallback(cripts::Callbacks cb)
{
@@ -121,11 +121,11 @@ public:
std::vector<cripts::Bundle::Base *> bundles;
private:
- void _initialize(int argc, char *argv[], const char *filename);
+ void _initialize(int argc, const char *argv[], const char *filename, bool
remap);
size_t _size = 0;
bool _failed = false;
- unsigned _callbacks = 0;
+ uint32_t _callbacks = 0;
DbgCtl dbg_ctl_cript;
}; // End class Instance
diff --git a/include/cripts/Preamble.hpp b/include/cripts/Preamble.hpp
index 64a6c254d9..518b3bfec2 100644
--- a/include/cripts/Preamble.hpp
+++ b/include/cripts/Preamble.hpp
@@ -41,10 +41,10 @@
// Having both of these for now, until we decide which we like better...
#define do_remap() void _do_remap(cripts::Context *context)
#define do_post_remap() void _do_post_remap(cripts::Context *context)
-#define do_send_response() void _do_send_response(cripts::Context *context)
#define do_cache_lookup() void _do_cache_lookup(cripts::Context *context)
#define do_send_request() void _do_send_request(cripts::Context *context)
#define do_read_response() void _do_read_response(cripts::Context *context)
+#define do_send_response() void _do_send_response(cripts::Context *context)
#define do_txn_close() void _do_txn_close(cripts::Context *context)
#define do_init() void _do_init(TSRemapInterface *)
#define do_create_instance() void _do_create_instance(cripts::InstanceContext
*context)
@@ -52,15 +52,37 @@
#define DoRemap() void _do_remap(cripts::Context *context)
#define DoPostRemap() void _do_post_remap(cripts::Context *context)
-#define DoSendResponse() void _do_send_response(cripts::Context *context)
#define DoCacheLookup() void _do_cache_lookup(cripts::Context *context)
#define DoSendRequest() void _do_send_request(cripts::Context *context)
#define DoReadResponse() void _do_read_response(cripts::Context *context)
+#define DoSendResponse() void _do_send_response(cripts::Context *context)
#define DoTxnClose() void _do_txn_close(cripts::Context *context)
#define DoInit() void _do_init(TSRemapInterface *)
#define DoCreateInstance() void _do_create_instance(cripts::InstanceContext
*context)
#define DoDeleteInstance() void _do_delete_instance(cripts::InstanceContext
*context)
+// For the global plugins
+#define glb_txn_start() void _glb_txn_start(cripts::Context *context)
+#define glb_read_request() void _glb_read_request(cripts::Context *context)
+#define glb_pre_remap() void _glb_pre_remap(cripts::Context *context)
+#define glb_post_remap() void _glb_post_remap(cripts::Context *context)
+#define glb_cache_lookup() void _glb_cache_lookup(cripts::Context *context)
+#define glb_send_request() void _glb_send_request(cripts::Context *context)
+#define glb_read_response() void _glb_read_response(cripts::Context *context)
+#define glb_send_response() void _glb_send_response(cripts::Context *context)
+#define glb_txn_close() void _glb_txn_close(cripts::Context *context)
+#define glb_init() void _glb_init(cripts::InstanceContext *context)
+
+#define GlbTxnStart() void _glb_txn_start(cripts::Context *context)
+#define GlbReadRequest() void _glb_read_request(cripts::Context *context)
+#define GlbPreRemap() void _glb_pre_remap(cripts::Context *context)
+#define GlbPostRemap() void _glb_post_remap(cripts::Context *context)
+#define GlbSendRequest() void _glb_send_request(cripts::Context *context)
+#define GlbReadResponse() void _glb_read_response(cripts::Context *context)
+#define GlbSendResponse() void _glb_send_response(cripts::Context *context)
+#define GlbTxnClose() void _glb_txn_close(cripts::Context *context)
+#define GlbInit() void _glb_init(cripts::InstanceContext *context)
+
#include "cripts/Headers.hpp"
#include "cripts/Urls.hpp"
#include "cripts/Configs.hpp"
diff --git a/include/cripts/Transaction.hpp b/include/cripts/Transaction.hpp
index 82a5c8c69e..9bcdb83d33 100644
--- a/include/cripts/Transaction.hpp
+++ b/include/cripts/Transaction.hpp
@@ -29,15 +29,24 @@
namespace cripts
{
// This is a bitfield, used to disable a particular callback from a previous
hook
-enum Callbacks : std::uint8_t {
- NONE = 0,
- DO_REMAP = 1,
- DO_POST_REMAP = 2,
- DO_SEND_RESPONSE = 4,
- DO_CACHE_LOOKUP = 8,
- DO_SEND_REQUEST = 16,
- DO_READ_RESPONSE = 32,
- DO_TXN_CLOSE = 64
+enum Callbacks : std::uint32_t {
+ NONE = 0,
+ DO_REMAP = 1 << 0,
+ DO_POST_REMAP = 1 << 1,
+ DO_CACHE_LOOKUP = 1 << 2,
+ DO_SEND_REQUEST = 1 << 3,
+ DO_READ_RESPONSE = 1 << 4,
+ DO_SEND_RESPONSE = 1 << 5,
+ DO_TXN_CLOSE = 1 << 6,
+ GLB_TXN_START = 1 << 7,
+ GLB_READ_REQUEST = 1 << 8,
+ GLB_PRE_REMAP = 1 << 9,
+ GLB_POST_REMAP = 1 << 10,
+ GLB_CACHE_LOOKUP = 1 << 11,
+ GLB_SEND_REQUEST = 1 << 12,
+ GLB_READ_RESPONSE = 1 << 13,
+ GLB_SEND_RESPONSE = 1 << 14,
+ GLB_TXN_CLOSE = 1 << 15,
};
class Transaction
@@ -58,7 +67,7 @@ public:
// Keep track of which hook we're currently in. ToDo: Do we still need this
with the
// tests being moved out to the linter?
TSHttpHookID hook = TS_HTTP_LAST_HOOK;
- unsigned enabled_hooks = 0; // Which hooks are enabled, other than the
mandatory ones
+ uint32_t enabled_hooks = 0; // Which hooks are enabled, other than the
mandatory ones
[[nodiscard]] bool
Aborted() const
diff --git a/src/cripts/Instance.cc b/src/cripts/Instance.cc
index af387a08a2..598e992d17 100644
--- a/src/cripts/Instance.cc
+++ b/src/cripts/Instance.cc
@@ -25,17 +25,19 @@ namespace cripts
{
void
-Instance::_initialize(int argc, char *argv[], const char *filename)
+Instance::_initialize(int argc, const char *argv[], const char *filename, bool
remap)
{
- from_url = argv[0];
- to_url = argv[1];
- for (int i = 2; i < argc; i++) {
- auto s = cripts::string(argv[i]);
-
- s.trim("\"\'");
- data[i - 2] = s;
+ if (remap) {
+ from_url = argv[0];
+ to_url = argv[1];
+ for (int i = 2; i < argc; i++) {
+ auto s = cripts::string(argv[i]);
+
+ s.trim("\"\'");
+ data[i - 2] = s;
+ }
+ _size = argc - 2;
}
- _size = argc - 2;
// Set the debug tag for this plugin, slightly annoying that we have to
calculate
// this for every instantiation, but in general, each Cript is used
primarily for
@@ -53,7 +55,7 @@ Instance::_initialize(int argc, char *argv[], const char
*filename)
}
dbg_ctl_cript.set(plugin_debug_tag.c_str());
-} // namespace Instance::_initialize(intargc,char*argv[],constchar*filename)
+}
bool
Instance::AddPlugin(const cripts::string &tag, const cripts::string &plugin,
const Plugin::Options &options)
diff --git a/src/cripts/Urls.cc b/src/cripts/Urls.cc
index 7fcdfd2ba9..9d0423371a 100644
--- a/src/cripts/Urls.cc
+++ b/src/cripts/Urls.cc
@@ -445,9 +445,20 @@ Client::URL::_initialize(cripts::Context *context)
{
Url::_initialize(&context->state);
- _bufp = context->rri->requestBufp;
- _hdr_loc = context->rri->requestHdrp;
- _urlp = context->rri->requestUrl;
+ if (context->rri) {
+ _bufp = context->rri->requestBufp;
+ _hdr_loc = context->rri->requestHdrp;
+ _urlp = context->rri->requestUrl;
+ } else {
+ Client::Request &req = Client::Request::_get(context); // Repurpose /
create the shared request object
+
+ _bufp = req.BufP();
+ _hdr_loc = req.MLoc();
+
+ if (TSHttpHdrUrlGet(_bufp, _hdr_loc, &_urlp) != TS_SUCCESS) {
+ context->state.error.Fail();
+ }
+ }
}
Client::URL &