This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit e7bfdf2764903985123da6b1b88add3bb76700cf
Author: Leif Hedstrom <[email protected]>
AuthorDate: Thu Jun 20 14:23:51 2024 -0600

    More cripts (#11460)
    
    * Add new bundles, cleanup others
    
    * Low leel acess to Records configurations
    
    (cherry picked from commit 433bb35e3334e21d7040d23c12bca06e4aa81a95)
---
 doc/developer-guide/cripts/cripts-bundles.en.rst   |  34 ++-
 doc/developer-guide/cripts/cripts-misc.en.rst      |  10 +-
 doc/developer-guide/cripts/cripts-urls.en.rst      |   5 +-
 doc/developer-guide/cripts/cripts-variables.en.rst |  13 ++
 example/cripts/example1.cc                         |   4 +-
 include/cripts/Bundle.hpp                          |   7 +-
 include/cripts/Bundles/{Common.hpp => Caching.hpp} |  35 ++-
 include/cripts/Bundles/Common.hpp                  |  33 ++-
 include/cripts/Bundles/Headers.hpp                 |  25 +-
 include/cripts/Bundles/LogsMetrics.hpp             |   8 +-
 include/cripts/Configs.hpp                         | 253 ++++++++++-----------
 include/cripts/ConfigsBase.hpp                     | 104 +++++++++
 include/cripts/Connections.hpp                     |  53 ++---
 include/cripts/Context.hpp                         |   2 +-
 include/cripts/Crypto.hpp                          |  59 ++---
 include/cripts/Epilogue.hpp                        |   3 +-
 include/cripts/Error.hpp                           |  24 +-
 include/cripts/Files.hpp                           |  19 +-
 include/cripts/Headers.hpp                         |  34 ++-
 include/cripts/Instance.hpp                        |  16 +-
 include/cripts/Lulu.hpp                            |  38 ++--
 include/cripts/Matcher.hpp                         |  24 +-
 include/cripts/Plugins.hpp                         |  14 +-
 include/cripts/Preamble.hpp                        |   5 +-
 include/cripts/Time.hpp                            |  15 +-
 include/cripts/Transaction.hpp                     |   2 +-
 include/cripts/UUID.hpp                            |  19 +-
 include/cripts/Urls.hpp                            | 119 ++++++----
 src/cripts/Bundles/{Common.cc => Caching.cc}       |  35 +--
 src/cripts/Bundles/Common.cc                       | 111 ++++++++-
 src/cripts/Bundles/HRWBridge.cc                    |  70 +++++-
 src/cripts/Bundles/Headers.cc                      |  32 +--
 src/cripts/Bundles/LogsMetrics.cc                  |  13 +-
 src/cripts/CMakeLists.txt                          |   4 +
 src/cripts/Configs.cc                              |  92 ++++++++
 src/cripts/Context.cc                              |   3 +
 src/cripts/Error.cc                                |   6 +
 src/cripts/Files.cc                                |  13 ++
 src/cripts/Instance.cc                             |   2 -
 src/cripts/Urls.cc                                 |  28 +++
 tools/cripts/genconfig.py                          |  41 +---
 41 files changed, 936 insertions(+), 491 deletions(-)

diff --git a/doc/developer-guide/cripts/cripts-bundles.en.rst 
b/doc/developer-guide/cripts/cripts-bundles.en.rst
index ad77b03746..f5182c93dc 100644
--- a/doc/developer-guide/cripts/cripts-bundles.en.rst
+++ b/doc/developer-guide/cripts/cripts-bundles.en.rst
@@ -41,7 +41,8 @@ Bundle                         Description
 ============================   
====================================================================
 ``Bundle::Common``             For DSCP and an overridable Cache-Control 
header.
 ``Bundle::LogsMetrics``        Log sampling, TCPInfo  and per-remap metrics.
-``Bundle::Headers``            For removing or adding headers
+``Bundle::Headers``            For removing or adding headers.
+``Bundle::Caching``            Various cache controlling behavior.
 ============================   
====================================================================
 
 This example shows how a Cript would enable both of these bundles with all 
features:
@@ -55,14 +56,23 @@ This example shows how a Cript would enable both of these 
bundles with all featu
 
    do_create_instance()
    {
-     Bundle::Common::activate().dscp(0x2e)
-                               .cache_control("max-age=3600");
+     Bundle::Common::activate().dscp(10)
+                               .via_header("client", "basic")
+                               .set_config({{"proxy.config.srv_enabled", 0},
+                                            
{"proxy.config.http.response_server_str", "ATS"});
 
      Bundle::LogsMetrics::activate().logsample(100)
                                     .tcpinfo(true)
                                     .propstats("example.com");
+
+     Bundle::Caching::activate().cache_control("max-age=259200")
+                                .disable(true)
+
    }
 
+The ``set_config()`` function can also take a single configuration and value, 
without the need
+to make a list.
+
 .. note::
    You don't have to activate all components of a Bundle, just leave it out if 
you don't need it.
 
@@ -71,6 +81,24 @@ This example shows how a Cript would enable both of these 
bundles with all featu
    with the appropriate include directives. This is because the list of 
Bundles may grow over time,
    as well as the build system allowing for custom bundles locally.
 
+.. _cripts-bundles-via-header:
+
+Via Header
+==========
+
+The ``Bundle::Common`` bundle has a function called ``via_header()`` that adds 
a Via header to the
+client response or the origin request. The first argument is ``client`` or 
``origin``, and the second
+argument is the type of Via header to be used:
+
+============================   
====================================================================
+Type                           Description
+============================   
====================================================================
+``disable``                    No Via header added.
+``protocol``                   Add the basic protocol and proxy identifier.
+``basic``                      Add basic transaction codes.
+``detailed``                   Add detailed transaction codes.
+``full``                       Add full user agent connection protocol tags.
+============================   
====================================================================
 
 .. _cripts-bundles-headers:
 
diff --git a/doc/developer-guide/cripts/cripts-misc.en.rst 
b/doc/developer-guide/cripts/cripts-misc.en.rst
index 085731f6d8..f5f6566c43 100644
--- a/doc/developer-guide/cripts/cripts-misc.en.rst
+++ b/doc/developer-guide/cripts/cripts-misc.en.rst
@@ -45,8 +45,9 @@ making this easy.
 =========================   
=======================================================================
 Function                    Description
 =========================   
=======================================================================
-``Error::Status::set``      Sets the response to the status code, and force 
the request to error.
-``Error::Reason::set``      Sets an explicit reason message with the status 
code. **TBD**
+``Error::Status::set()``    Sets the response to the status code, and force 
the request to error.
+``Error::Status::get()``    Get the current response status for the request.
+``Error::Reason::set()``    Sets an explicit reason message with the status 
code. **TBD**
 =========================   
=======================================================================
 
 Example:
@@ -60,6 +61,11 @@ Example:
      if (req["X-Header"] == "yes") {
        Error::Status::set(403);
      }
+     // Do more stuff here
+
+     if (Error::status::get() != 403) {
+       // Do even more stuff here if we're not in error state
+     }
    }
 
 .. _cripts-misc-transaction:
diff --git a/doc/developer-guide/cripts/cripts-urls.en.rst 
b/doc/developer-guide/cripts/cripts-urls.en.rst
index 05f07595e0..73eca4fc4d 100644
--- a/doc/developer-guide/cripts/cripts-urls.en.rst
+++ b/doc/developer-guide/cripts/cripts-urls.en.rst
@@ -62,11 +62,12 @@ Every URL object has the following components:
 ===============   
=================================================================================
 Component         Description
 ===============   
=================================================================================
+``scheme``        The scheme (http, https, etc).
 ``host``          The host name.
 ``port``          The port number, this is an integer value.
-``scheme``        The scheme (http, https, etc).
 ``path``          The path.
-``query``         The query.
+``query``         The query parameters.
+``matrix``        The matrix parameters: Note: This is currently treated as a 
single string.
 ===============   
=================================================================================
 
 .. note::
diff --git a/doc/developer-guide/cripts/cripts-variables.en.rst 
b/doc/developer-guide/cripts/cripts-variables.en.rst
index 0b7b7f23ab..a271e43934 100644
--- a/doc/developer-guide/cripts/cripts-variables.en.rst
+++ b/doc/developer-guide/cripts/cripts-variables.en.rst
@@ -122,6 +122,19 @@ Best way to understand this is to look at an example:
 This is a pretty artificial example, but shows the name space of these 
configurations, and how they
 match the documented ATS configuration names.
 
+The configurations can also be access via a more advanced API, typically used 
for embedding existing
+control planes with Cripts. This is done using the ``Records`` object, for 
example:
+
+.. code-block:: cpp
+
+   do_remap() {
+     auto http_cache = Cript::Records("proxy.config.http.cache.http");
+
+     if (AsInteger(http_cache.get()) > 0) {
+       CDebug("HTTP Cache is on");
+     }
+   }
+
 .. _cripts-variables-control:
 
 Control Variable
diff --git a/example/cripts/example1.cc b/example/cripts/example1.cc
index 6b62f4faaa..971a10b599 100644
--- a/example/cripts/example1.cc
+++ b/example/cripts/example1.cc
@@ -20,6 +20,7 @@
 #include <cripts/Preamble.hpp>
 
 #include <cripts/Bundles/Common.hpp>
+#include <cripts/Bundles/Caching.hpp>
 
 // Globals for this Cript
 static Matcher::Range::IP CRIPT_ALLOW({"192.168.201.0/24", "10.0.0.0/8"});
@@ -42,7 +43,8 @@ do_create_instance()
   instance.metrics[7] = Metrics::Counter::create("cript.example1.c7");
   instance.metrics[8] = Metrics::Counter::create("cript.example1.c8"); // This 
one should resize() the storage
 
-  Bundle::Common::activate().dscp(10).cache_control("max-age=259200");
+  Bundle::Common::activate().dscp(10);
+  Bundle::Caching::activate().cache_control("max-age=259200");
 }
 
 do_txn_close()
diff --git a/include/cripts/Bundle.hpp b/include/cripts/Bundle.hpp
index 955ec9b88f..d147c096e0 100644
--- a/include/cripts/Bundle.hpp
+++ b/include/cripts/Bundle.hpp
@@ -17,6 +17,11 @@
 */
 #pragma once
 
+#include <vector>
+
+#include "cripts/Lulu.hpp"
+#include "cripts/Transaction.hpp"
+
 namespace Cript
 {
 // We have to forward declare this, to avoid some circular dependencies
@@ -72,7 +77,7 @@ namespace Bundle
     void operator=(const self_type &) = delete;
     virtual ~Base()                   = default;
 
-    virtual const Cript::string &name() const = 0;
+    [[nodiscard]] virtual const Cript::string &name() const = 0;
 
     void
     needCallback(Cript::Callbacks cb)
diff --git a/include/cripts/Bundles/Common.hpp 
b/include/cripts/Bundles/Caching.hpp
similarity index 80%
copy from include/cripts/Bundles/Common.hpp
copy to include/cripts/Bundles/Caching.hpp
index 9bf07c898c..cc3123c9bd 100644
--- a/include/cripts/Bundles/Common.hpp
+++ b/include/cripts/Bundles/Caching.hpp
@@ -15,27 +15,26 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
-
-// This is an example bundle for some common tasks.
-//
-//  Bundle::Common::activate().dscp(10)
-//                            .cache_control("max-age=259200");
 #pragma once
 
+//  Cache specific features:
+//  Bundle::Caching::activate().cache_control("max-age=259200")
+//                             .disable(true)
+
+#include "cripts/Lulu.hpp"
+#include "cripts/Instance.hpp"
 #include "cripts/Bundle.hpp"
 
 namespace Bundle
 {
-class Common : public Cript::Bundle::Base
+class Caching : public Cript::Bundle::Base
 {
   using super_type = Cript::Bundle::Base;
-  using self_type  = Common;
+  using self_type  = Caching;
 
 public:
   using super_type::Base;
 
-  bool validate(std::vector<Cript::Bundle::Error> &errors) const override;
-
   // This is the factory to create an instance of this bundle
   static self_type &
   _activate(Cript::Instance &inst)
@@ -47,27 +46,27 @@ public:
     return *entry;
   }
 
-  const Cript::string &
+  [[nodiscard]] const Cript::string &
   name() const override
   {
     return _name;
   }
 
   self_type &
-  dscp(int val)
+  cache_control(Cript::string_view cc, bool force = false)
   {
-    needCallback(Cript::Callbacks::DO_REMAP);
-    _dscp = val;
+    needCallback(Cript::Callbacks::DO_READ_RESPONSE);
+    _cc       = cc;
+    _force_cc = force;
 
     return *this;
   }
 
   self_type &
-  cache_control(Cript::string_view cc, bool force = false)
+  disable(bool disable = true)
   {
-    needCallback(Cript::Callbacks::DO_READ_RESPONSE);
-    _cc       = cc;
-    _force_cc = force;
+    needCallback(Cript::Callbacks::DO_REMAP);
+    _disabled = disable;
 
     return *this;
   }
@@ -78,8 +77,8 @@ public:
 private:
   static const Cript::string _name;
   Cript::string              _cc       = "";
-  int                        _dscp     = 0;
   bool                       _force_cc = false;
+  bool                       _disabled = false;
 };
 
 } // namespace Bundle
diff --git a/include/cripts/Bundles/Common.hpp 
b/include/cripts/Bundles/Common.hpp
index 9bf07c898c..fdbd1f79eb 100644
--- a/include/cripts/Bundles/Common.hpp
+++ b/include/cripts/Bundles/Common.hpp
@@ -15,14 +15,17 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
+#pragma once
 
 // This is an example bundle for some common tasks.
-//
 //  Bundle::Common::activate().dscp(10)
-//                            .cache_control("max-age=259200");
-#pragma once
+//                            .via_header("Client|Origin", 
"disable|protocol|basic|detailed|full")
+//                            .set_config("config", value);
 
+#include "cripts/Lulu.hpp"
+#include "cripts/Instance.hpp"
 #include "cripts/Bundle.hpp"
+#include <cripts/ConfigsBase.hpp>
 
 namespace Bundle
 {
@@ -31,6 +34,8 @@ class Common : public Cript::Bundle::Base
   using super_type = Cript::Bundle::Base;
   using self_type  = Common;
 
+  using RecordsList = std::vector<std::pair<Cript::Records, const 
Cript::Records::ValueType>>;
+
 public:
   using super_type::Base;
 
@@ -47,7 +52,7 @@ public:
     return *entry;
   }
 
-  const Cript::string &
+  [[nodiscard]] const Cript::string &
   name() const override
   {
     return _name;
@@ -62,24 +67,18 @@ public:
     return *this;
   }
 
-  self_type &
-  cache_control(Cript::string_view cc, bool force = false)
-  {
-    needCallback(Cript::Callbacks::DO_READ_RESPONSE);
-    _cc       = cc;
-    _force_cc = force;
-
-    return *this;
-  }
+  self_type &via_header(const Cript::string_view &destination, const 
Cript::string_view &value);
+  self_type &set_config(const Cript::string_view name, const 
Cript::Records::ValueType value);
+  self_type &set_config(std::vector<std::pair<const Cript::string_view, const 
Cript::Records::ValueType>> configs);
 
-  void doReadResponse(Cript::Context *context) override;
   void doRemap(Cript::Context *context) override;
 
 private:
   static const Cript::string _name;
-  Cript::string              _cc       = "";
-  int                        _dscp     = 0;
-  bool                       _force_cc = false;
+  int                        _dscp       = 0;
+  std::pair<int, bool>       _client_via = {0, false}; // Flag indicates if 
it's been set at all
+  std::pair<int, bool>       _origin_via = {0, false};
+  RecordsList                _configs;
 };
 
 } // namespace Bundle
diff --git a/include/cripts/Bundles/Headers.hpp 
b/include/cripts/Bundles/Headers.hpp
index db65e42f1b..0a0652d5c8 100644
--- a/include/cripts/Bundles/Headers.hpp
+++ b/include/cripts/Bundles/Headers.hpp
@@ -15,13 +15,14 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
+#pragma once
 
+// Bundle for common header operations
 //  Bundle::Headers::activate().rm_headers("Client::Request", 
["X-ATS-Request-ID", "X-ATS-Request-Start", "X-ATS-Request-End"])
 //                             .set_headers("Client::Response", {{"X-Foo", 
"bar", {"X-Fie", "fum"}});
-#pragma once
-
-#include <vector>
 
+#include "cripts/Lulu.hpp"
+#include "cripts/Instance.hpp"
 #include "cripts/Bundle.hpp"
 
 namespace detail
@@ -31,10 +32,10 @@ class HRWBridge
   using self_type = HRWBridge;
 
 public:
+  HRWBridge()                       = delete;
   HRWBridge(const self_type &)      = delete;
   void operator=(const self_type &) = delete;
 
-  HRWBridge() = delete;
   HRWBridge(const Cript::string_view &str) : _value(str) {}
 
   virtual ~HRWBridge() = default;
@@ -56,6 +57,9 @@ class HeadersType
   using self_type = HeadersType;
 
 public:
+  using HeaderList      = std::vector<Cript::string>;
+  using HeaderValueList = std::vector<std::pair<const Cript::string, 
detail::HRWBridge *>>;
+
   HeadersType()                     = default;
   HeadersType(const self_type &)    = delete;
   void operator=(const self_type &) = delete;
@@ -67,8 +71,8 @@ public:
     }
   }
 
-  std::vector<Cript::string>                                 rm_headers;
-  std::vector<std::pair<Cript::string, detail::HRWBridge *>> set_headers;
+  HeaderList      rm_headers;
+  HeaderValueList set_headers;
 };
 } // namespace detail
 
@@ -80,6 +84,9 @@ class Headers : public Cript::Bundle::Base
   using self_type  = Headers;
 
 public:
+  using HeaderList      = std::vector<Cript::string>;
+  using HeaderValueList = std::vector<std::pair<const Cript::string, const 
Cript::string>>;
+
   using super_type::Base;
 
   // This is the factory to create an instance of this bundle
@@ -93,7 +100,7 @@ public:
     return *entry;
   }
 
-  const Cript::string &
+  [[nodiscard]] const Cript::string &
   name() const override
   {
     return _name;
@@ -101,8 +108,8 @@ public:
 
   static detail::HRWBridge *bridgeFactory(const Cript::string &source);
 
-  self_type &rm_headers(const Cript::string_view target, const 
std::vector<Cript::string> &headers);
-  self_type &set_headers(const Cript::string_view target, const 
std::vector<std::pair<Cript::string, Cript::string>> &headers);
+  self_type &rm_headers(const Cript::string_view target, const HeaderList 
&headers);
+  self_type &set_headers(const Cript::string_view target, const 
HeaderValueList &headers);
 
   void doRemap(Cript::Context *context) override;
   void doSendResponse(Cript::Context *context) override;
diff --git a/include/cripts/Bundles/LogsMetrics.hpp 
b/include/cripts/Bundles/LogsMetrics.hpp
index e5e8c8ad8b..e10683fe28 100644
--- a/include/cripts/Bundles/LogsMetrics.hpp
+++ b/include/cripts/Bundles/LogsMetrics.hpp
@@ -15,15 +15,15 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
+#pragma once
 
 // This is a bundle for some per-remap metrics and logging.
-//
 //  Bundle::LogsMetrics::activate().propstats("property-name")
 //                                 .logsample(2000)
 //                                 .tcpinfo();
-//
-#pragma once
 
+#include "cripts/Lulu.hpp"
+#include "cripts/Instance.hpp"
 #include "cripts/Bundle.hpp"
 
 namespace Bundle
@@ -46,7 +46,7 @@ public:
     return *entry;
   }
 
-  const Cript::string &
+  [[nodiscard]] const Cript::string &
   name() const override
   {
     return _name;
diff --git a/include/cripts/Configs.hpp b/include/cripts/Configs.hpp
index 092c437a12..5d70fae07e 100644
--- a/include/cripts/Configs.hpp
+++ b/include/cripts/Configs.hpp
@@ -20,37 +20,12 @@
 /*
   THIS FILE IS AUTOGENERATED, DO NOT EDIT
 
-  Regenerate this file with the 'generate-cripts-config' target
+  Regenerate this file with the 'generate-cripts-config' target. Remember
+  to run the format target on the generated file as well.
 */
 #pragma once
 
-class IntConfig
-{
-public:
-  IntConfig() = delete;
-  explicit IntConfig(TSOverridableConfigKey key) : _key(key) {}
-
-  // Implemented later in Configs.cc
-  integer _get(Cript::Context *context) const;
-  void    _set(Cript::Context *context, integer value);
-
-private:
-  const TSOverridableConfigKey _key;
-};
-
-class FloatConfig
-{
-public:
-  FloatConfig() = delete;
-  explicit FloatConfig(TSOverridableConfigKey key) : _key(key) {}
-
-  // Implemented later in Configs.cc
-  float _get(Cript::Context *context) const;
-  void  _set(Cript::Context *context, float value);
-
-private:
-  const TSOverridableConfigKey _key;
-};
+#include "cripts/ConfigsBase.hpp"
 
 class Proxy
 {
@@ -63,7 +38,7 @@ private:
     class Body_Factory
     {
     public:
-      IntConfig 
response_suppression_mode{TS_CONFIG_BODY_FACTORY_RESPONSE_SUPPRESSION_MODE};
+      Cript::IntConfig 
response_suppression_mode{TS_CONFIG_BODY_FACTORY_RESPONSE_SUPPRESSION_MODE};
     }; // End class Body_Factory
 
   public:
@@ -82,61 +57,61 @@ private:
     class Http
     {
     public:
-      IntConfig   allow_half_open{TS_CONFIG_HTTP_ALLOW_HALF_OPEN};
-      IntConfig   allow_multi_range{TS_CONFIG_HTTP_ALLOW_MULTI_RANGE};
-      IntConfig   
anonymize_remove_client_ip{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_CLIENT_IP};
-      IntConfig   
anonymize_remove_cookie{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_COOKIE};
-      IntConfig   anonymize_remove_from{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_FROM};
-      IntConfig   
anonymize_remove_referer{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_REFERER};
-      IntConfig   
anonymize_remove_user_agent{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_USER_AGENT};
-      IntConfig   
attach_server_session_to_client{TS_CONFIG_HTTP_ATTACH_SERVER_SESSION_TO_CLIENT};
-      IntConfig   
auth_server_session_private{TS_CONFIG_HTTP_AUTH_SERVER_SESSION_PRIVATE};
-      IntConfig   
background_fill_active_timeout{TS_CONFIG_HTTP_BACKGROUND_FILL_ACTIVE_TIMEOUT};
-      FloatConfig 
background_fill_completed_threshold{TS_CONFIG_HTTP_BACKGROUND_FILL_COMPLETED_THRESHOLD};
+      Cript::IntConfig   allow_half_open{TS_CONFIG_HTTP_ALLOW_HALF_OPEN};
+      Cript::IntConfig   allow_multi_range{TS_CONFIG_HTTP_ALLOW_MULTI_RANGE};
+      Cript::IntConfig   
anonymize_remove_client_ip{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_CLIENT_IP};
+      Cript::IntConfig   
anonymize_remove_cookie{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_COOKIE};
+      Cript::IntConfig   
anonymize_remove_from{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_FROM};
+      Cript::IntConfig   
anonymize_remove_referer{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_REFERER};
+      Cript::IntConfig   
anonymize_remove_user_agent{TS_CONFIG_HTTP_ANONYMIZE_REMOVE_USER_AGENT};
+      Cript::IntConfig   
attach_server_session_to_client{TS_CONFIG_HTTP_ATTACH_SERVER_SESSION_TO_CLIENT};
+      Cript::IntConfig   
auth_server_session_private{TS_CONFIG_HTTP_AUTH_SERVER_SESSION_PRIVATE};
+      Cript::IntConfig   
background_fill_active_timeout{TS_CONFIG_HTTP_BACKGROUND_FILL_ACTIVE_TIMEOUT};
+      Cript::FloatConfig 
background_fill_completed_threshold{TS_CONFIG_HTTP_BACKGROUND_FILL_COMPLETED_THRESHOLD};
 
     private:
       class Cache
       {
       public:
-        IntConfig   
cache_responses_to_cookies{TS_CONFIG_HTTP_CACHE_CACHE_RESPONSES_TO_COOKIES};
-        IntConfig   
cache_urls_that_look_dynamic{TS_CONFIG_HTTP_CACHE_CACHE_URLS_THAT_LOOK_DYNAMIC};
-        IntConfig   generation{TS_CONFIG_HTTP_CACHE_GENERATION};
-        IntConfig   
guaranteed_max_lifetime{TS_CONFIG_HTTP_CACHE_GUARANTEED_MAX_LIFETIME};
-        IntConfig   
guaranteed_min_lifetime{TS_CONFIG_HTTP_CACHE_GUARANTEED_MIN_LIFETIME};
-        FloatConfig 
heuristic_lm_factor{TS_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR};
-        IntConfig   
heuristic_max_lifetime{TS_CONFIG_HTTP_CACHE_HEURISTIC_MAX_LIFETIME};
-        IntConfig   
heuristic_min_lifetime{TS_CONFIG_HTTP_CACHE_HEURISTIC_MIN_LIFETIME};
-        IntConfig   http{TS_CONFIG_HTTP_CACHE_HTTP};
-        IntConfig   
ignore_accept_charset_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_CHARSET_MISMATCH};
-        IntConfig   
ignore_accept_encoding_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_ENCODING_MISMATCH};
-        IntConfig   
ignore_accept_language_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_LANGUAGE_MISMATCH};
-        IntConfig   
ignore_accept_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_MISMATCH};
-        IntConfig   
ignore_authentication{TS_CONFIG_HTTP_CACHE_IGNORE_AUTHENTICATION};
-        IntConfig   
ignore_client_cc_max_age{TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_CC_MAX_AGE};
-        IntConfig   
ignore_client_no_cache{TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_NO_CACHE};
-        IntConfig   ignore_query{TS_CONFIG_HTTP_CACHE_IGNORE_QUERY};
-        IntConfig   
ignore_server_no_cache{TS_CONFIG_HTTP_CACHE_IGNORE_SERVER_NO_CACHE};
-        IntConfig   
ims_on_client_no_cache{TS_CONFIG_HTTP_CACHE_IMS_ON_CLIENT_NO_CACHE};
-        IntConfig   
max_open_read_retries{TS_CONFIG_HTTP_CACHE_MAX_OPEN_READ_RETRIES};
-        IntConfig   
max_open_write_retries{TS_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRIES};
-        IntConfig   
max_open_write_retry_timeout{TS_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRY_TIMEOUT};
-        IntConfig   max_stale_age{TS_CONFIG_HTTP_CACHE_MAX_STALE_AGE};
-        IntConfig   
open_read_retry_time{TS_CONFIG_HTTP_CACHE_OPEN_READ_RETRY_TIME};
-        IntConfig   
open_write_fail_action{TS_CONFIG_HTTP_CACHE_OPEN_WRITE_FAIL_ACTION};
+        Cript::IntConfig   
cache_responses_to_cookies{TS_CONFIG_HTTP_CACHE_CACHE_RESPONSES_TO_COOKIES};
+        Cript::IntConfig   
cache_urls_that_look_dynamic{TS_CONFIG_HTTP_CACHE_CACHE_URLS_THAT_LOOK_DYNAMIC};
+        Cript::IntConfig   generation{TS_CONFIG_HTTP_CACHE_GENERATION};
+        Cript::IntConfig   
guaranteed_max_lifetime{TS_CONFIG_HTTP_CACHE_GUARANTEED_MAX_LIFETIME};
+        Cript::IntConfig   
guaranteed_min_lifetime{TS_CONFIG_HTTP_CACHE_GUARANTEED_MIN_LIFETIME};
+        Cript::FloatConfig 
heuristic_lm_factor{TS_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR};
+        Cript::IntConfig   
heuristic_max_lifetime{TS_CONFIG_HTTP_CACHE_HEURISTIC_MAX_LIFETIME};
+        Cript::IntConfig   
heuristic_min_lifetime{TS_CONFIG_HTTP_CACHE_HEURISTIC_MIN_LIFETIME};
+        Cript::IntConfig   http{TS_CONFIG_HTTP_CACHE_HTTP};
+        Cript::IntConfig   
ignore_accept_charset_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_CHARSET_MISMATCH};
+        Cript::IntConfig   
ignore_accept_encoding_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_ENCODING_MISMATCH};
+        Cript::IntConfig   
ignore_accept_language_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_LANGUAGE_MISMATCH};
+        Cript::IntConfig   
ignore_accept_mismatch{TS_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_MISMATCH};
+        Cript::IntConfig   
ignore_authentication{TS_CONFIG_HTTP_CACHE_IGNORE_AUTHENTICATION};
+        Cript::IntConfig   
ignore_client_cc_max_age{TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_CC_MAX_AGE};
+        Cript::IntConfig   
ignore_client_no_cache{TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_NO_CACHE};
+        Cript::IntConfig   ignore_query{TS_CONFIG_HTTP_CACHE_IGNORE_QUERY};
+        Cript::IntConfig   
ignore_server_no_cache{TS_CONFIG_HTTP_CACHE_IGNORE_SERVER_NO_CACHE};
+        Cript::IntConfig   
ims_on_client_no_cache{TS_CONFIG_HTTP_CACHE_IMS_ON_CLIENT_NO_CACHE};
+        Cript::IntConfig   
max_open_read_retries{TS_CONFIG_HTTP_CACHE_MAX_OPEN_READ_RETRIES};
+        Cript::IntConfig   
max_open_write_retries{TS_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRIES};
+        Cript::IntConfig   
max_open_write_retry_timeout{TS_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRY_TIMEOUT};
+        Cript::IntConfig   max_stale_age{TS_CONFIG_HTTP_CACHE_MAX_STALE_AGE};
+        Cript::IntConfig   
open_read_retry_time{TS_CONFIG_HTTP_CACHE_OPEN_READ_RETRY_TIME};
+        Cript::IntConfig   
open_write_fail_action{TS_CONFIG_HTTP_CACHE_OPEN_WRITE_FAIL_ACTION};
 
       private:
         class Range
         {
         public:
-          IntConfig lookup{TS_CONFIG_HTTP_CACHE_RANGE_LOOKUP};
-          IntConfig write{TS_CONFIG_HTTP_CACHE_RANGE_WRITE};
+          Cript::IntConfig lookup{TS_CONFIG_HTTP_CACHE_RANGE_LOOKUP};
+          Cript::IntConfig write{TS_CONFIG_HTTP_CACHE_RANGE_WRITE};
         }; // End class Range
 
       public:
         Range range;
 
-        IntConfig required_headers{TS_CONFIG_HTTP_CACHE_REQUIRED_HEADERS};
-        IntConfig when_to_revalidate{TS_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE};
+        Cript::IntConfig 
required_headers{TS_CONFIG_HTTP_CACHE_REQUIRED_HEADERS};
+        Cript::IntConfig 
when_to_revalidate{TS_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE};
       }; // End class Cache
 
     public:
@@ -146,13 +121,13 @@ private:
       class Chunking
       {
       public:
-        IntConfig size{TS_CONFIG_HTTP_CHUNKING_SIZE};
+        Cript::IntConfig size{TS_CONFIG_HTTP_CHUNKING_SIZE};
       }; // End class Chunking
 
     public:
       Chunking chunking;
 
-      IntConfig chunking_enabled{TS_CONFIG_HTTP_CHUNKING_ENABLED};
+      Cript::IntConfig chunking_enabled{TS_CONFIG_HTTP_CHUNKING_ENABLED};
 
     private:
       class Connect
@@ -161,7 +136,7 @@ private:
         class Down
         {
         public:
-          IntConfig policy{TS_CONFIG_HTTP_CONNECT_DOWN_POLICY};
+          Cript::IntConfig policy{TS_CONFIG_HTTP_CONNECT_DOWN_POLICY};
         }; // End class Down
 
       public:
@@ -172,19 +147,19 @@ private:
     public:
       Connect connect;
 
-      IntConfig 
connect_attempts_max_retries{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES};
-      IntConfig 
connect_attempts_max_retries_down_server{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DOWN_SERVER};
-      IntConfig 
connect_attempts_rr_retries{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES};
-      IntConfig 
connect_attempts_timeout{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT};
-      IntConfig default_buffer_size{TS_CONFIG_HTTP_DEFAULT_BUFFER_SIZE};
-      IntConfig 
default_buffer_water_mark{TS_CONFIG_HTTP_DEFAULT_BUFFER_WATER_MARK};
-      IntConfig doc_in_cache_skip_dns{TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS};
+      Cript::IntConfig 
connect_attempts_max_retries{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES};
+      Cript::IntConfig 
connect_attempts_max_retries_down_server{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DOWN_SERVER};
+      Cript::IntConfig 
connect_attempts_rr_retries{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES};
+      Cript::IntConfig 
connect_attempts_timeout{TS_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT};
+      Cript::IntConfig default_buffer_size{TS_CONFIG_HTTP_DEFAULT_BUFFER_SIZE};
+      Cript::IntConfig 
default_buffer_water_mark{TS_CONFIG_HTTP_DEFAULT_BUFFER_WATER_MARK};
+      Cript::IntConfig 
doc_in_cache_skip_dns{TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS};
 
     private:
       class Down_Server
       {
       public:
-        IntConfig cache_time{TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME};
+        Cript::IntConfig cache_time{TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME};
       }; // End class Down_Server
 
     public:
@@ -194,9 +169,9 @@ private:
       class Flow_Control
       {
       public:
-        IntConfig enabled{TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED};
-        IntConfig high_water{TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK};
-        IntConfig low_water{TS_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER_MARK};
+        Cript::IntConfig enabled{TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED};
+        Cript::IntConfig 
high_water{TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK};
+        Cript::IntConfig low_water{TS_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER_MARK};
       }; // End class Flow_Control
 
     public:
@@ -206,43 +181,43 @@ private:
       class Forward
       {
       public:
-        IntConfig 
proxy_auth_to_parent{TS_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT};
+        Cript::IntConfig 
proxy_auth_to_parent{TS_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT};
       }; // End class Forward
 
     public:
       Forward forward;
 
-      IntConfig forward_connect_method{TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD};
-      IntConfig insert_age_in_response{TS_CONFIG_HTTP_INSERT_AGE_IN_RESPONSE};
-      IntConfig insert_client_ip{TS_CONFIG_HTTP_ANONYMIZE_INSERT_CLIENT_IP};
-      IntConfig insert_request_via_str{TS_CONFIG_HTTP_INSERT_REQUEST_VIA_STR};
-      IntConfig 
insert_response_via_str{TS_CONFIG_HTTP_INSERT_RESPONSE_VIA_STR};
-      IntConfig 
insert_squid_x_forwarded_for{TS_CONFIG_HTTP_INSERT_SQUID_X_FORWARDED_FOR};
-      IntConfig keep_alive_enabled_in{TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN};
-      IntConfig keep_alive_enabled_out{TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT};
-      IntConfig 
keep_alive_no_activity_timeout_in{TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_IN};
-      IntConfig 
keep_alive_no_activity_timeout_out{TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_OUT};
-      IntConfig keep_alive_post_out{TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT};
-      IntConfig max_proxy_cycles{TS_CONFIG_HTTP_MAX_PROXY_CYCLES};
-      IntConfig 
negative_caching_enabled{TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED};
-      IntConfig 
negative_caching_lifetime{TS_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME};
-      IntConfig 
negative_revalidating_enabled{TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED};
-      IntConfig 
negative_revalidating_lifetime{TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME};
-      IntConfig 
no_dns_just_forward_to_parent{TS_CONFIG_HTTP_NO_DNS_JUST_FORWARD_TO_PARENT};
-      IntConfig normalize_ae{TS_CONFIG_HTTP_NORMALIZE_AE};
-      IntConfig number_of_redirections{TS_CONFIG_HTTP_NUMBER_OF_REDIRECTIONS};
+      Cript::IntConfig 
forward_connect_method{TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD};
+      Cript::IntConfig 
insert_age_in_response{TS_CONFIG_HTTP_INSERT_AGE_IN_RESPONSE};
+      Cript::IntConfig 
insert_client_ip{TS_CONFIG_HTTP_ANONYMIZE_INSERT_CLIENT_IP};
+      Cript::IntConfig 
insert_request_via_str{TS_CONFIG_HTTP_INSERT_REQUEST_VIA_STR};
+      Cript::IntConfig 
insert_response_via_str{TS_CONFIG_HTTP_INSERT_RESPONSE_VIA_STR};
+      Cript::IntConfig 
insert_squid_x_forwarded_for{TS_CONFIG_HTTP_INSERT_SQUID_X_FORWARDED_FOR};
+      Cript::IntConfig 
keep_alive_enabled_in{TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN};
+      Cript::IntConfig 
keep_alive_enabled_out{TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT};
+      Cript::IntConfig 
keep_alive_no_activity_timeout_in{TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_IN};
+      Cript::IntConfig 
keep_alive_no_activity_timeout_out{TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_OUT};
+      Cript::IntConfig keep_alive_post_out{TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT};
+      Cript::IntConfig max_proxy_cycles{TS_CONFIG_HTTP_MAX_PROXY_CYCLES};
+      Cript::IntConfig 
negative_caching_enabled{TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED};
+      Cript::IntConfig 
negative_caching_lifetime{TS_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME};
+      Cript::IntConfig 
negative_revalidating_enabled{TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED};
+      Cript::IntConfig 
negative_revalidating_lifetime{TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME};
+      Cript::IntConfig 
no_dns_just_forward_to_parent{TS_CONFIG_HTTP_NO_DNS_JUST_FORWARD_TO_PARENT};
+      Cript::IntConfig normalize_ae{TS_CONFIG_HTTP_NORMALIZE_AE};
+      Cript::IntConfig 
number_of_redirections{TS_CONFIG_HTTP_NUMBER_OF_REDIRECTIONS};
 
     private:
       class Parent_Proxy
       {
       public:
-        IntConfig 
disable_parent_markdowns{TS_CONFIG_HTTP_DISABLE_PARENT_MARKDOWNS};
-        IntConfig 
enable_parent_timeout_markdowns{TS_CONFIG_HTTP_ENABLE_PARENT_TIMEOUT_MARKDOWNS};
-        IntConfig fail_threshold{TS_CONFIG_HTTP_PARENT_PROXY_FAIL_THRESHOLD};
-        IntConfig mark_down_hostdb{TS_CONFIG_PARENT_FAILURES_UPDATE_HOSTDB};
-        IntConfig 
per_parent_connect_attempts{TS_CONFIG_HTTP_PER_PARENT_CONNECT_ATTEMPTS};
-        IntConfig retry_time{TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME};
-        IntConfig 
total_connect_attempts{TS_CONFIG_HTTP_PARENT_PROXY_TOTAL_CONNECT_ATTEMPTS};
+        Cript::IntConfig 
disable_parent_markdowns{TS_CONFIG_HTTP_DISABLE_PARENT_MARKDOWNS};
+        Cript::IntConfig 
enable_parent_timeout_markdowns{TS_CONFIG_HTTP_ENABLE_PARENT_TIMEOUT_MARKDOWNS};
+        Cript::IntConfig 
fail_threshold{TS_CONFIG_HTTP_PARENT_PROXY_FAIL_THRESHOLD};
+        Cript::IntConfig 
mark_down_hostdb{TS_CONFIG_PARENT_FAILURES_UPDATE_HOSTDB};
+        Cript::IntConfig 
per_parent_connect_attempts{TS_CONFIG_HTTP_PER_PARENT_CONNECT_ATTEMPTS};
+        Cript::IntConfig retry_time{TS_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME};
+        Cript::IntConfig 
total_connect_attempts{TS_CONFIG_HTTP_PARENT_PROXY_TOTAL_CONNECT_ATTEMPTS};
       }; // End class Parent_Proxy
 
     public:
@@ -258,7 +233,7 @@ private:
           class Content_Length
           {
           public:
-            IntConfig 
enabled{TS_CONFIG_HTTP_POST_CHECK_CONTENT_LENGTH_ENABLED};
+            Cript::IntConfig 
enabled{TS_CONFIG_HTTP_POST_CHECK_CONTENT_LENGTH_ENABLED};
           }; // End class Content_Length
 
         public:
@@ -274,13 +249,13 @@ private:
     public:
       Post post;
 
-      IntConfig proxy_protocol_out{TS_CONFIG_HTTP_PROXY_PROTOCOL_OUT};
-      IntConfig 
redirect_use_orig_cache_key{TS_CONFIG_HTTP_REDIRECT_USE_ORIG_CACHE_KEY};
-      IntConfig request_buffer_enabled{TS_CONFIG_HTTP_REQUEST_BUFFER_ENABLED};
-      IntConfig 
request_header_max_size{TS_CONFIG_HTTP_REQUEST_HEADER_MAX_SIZE};
-      IntConfig 
response_header_max_size{TS_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE};
-      IntConfig 
response_server_enabled{TS_CONFIG_HTTP_RESPONSE_SERVER_ENABLED};
-      IntConfig send_http11_requests{TS_CONFIG_HTTP_SEND_HTTP11_REQUESTS};
+      Cript::IntConfig proxy_protocol_out{TS_CONFIG_HTTP_PROXY_PROTOCOL_OUT};
+      Cript::IntConfig 
redirect_use_orig_cache_key{TS_CONFIG_HTTP_REDIRECT_USE_ORIG_CACHE_KEY};
+      Cript::IntConfig 
request_buffer_enabled{TS_CONFIG_HTTP_REQUEST_BUFFER_ENABLED};
+      Cript::IntConfig 
request_header_max_size{TS_CONFIG_HTTP_REQUEST_HEADER_MAX_SIZE};
+      Cript::IntConfig 
response_header_max_size{TS_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE};
+      Cript::IntConfig 
response_server_enabled{TS_CONFIG_HTTP_RESPONSE_SERVER_ENABLED};
+      Cript::IntConfig 
send_http11_requests{TS_CONFIG_HTTP_SEND_HTTP11_REQUESTS};
 
     private:
       class Server_Session_Sharing
@@ -298,7 +273,7 @@ private:
         class Log
         {
         public:
-          IntConfig threshold{TS_CONFIG_HTTP_SLOW_LOG_THRESHOLD};
+          Cript::IntConfig threshold{TS_CONFIG_HTTP_SLOW_LOG_THRESHOLD};
         }; // End class Log
 
       public:
@@ -309,11 +284,11 @@ private:
     public:
       Slow slow;
 
-      IntConfig 
transaction_active_timeout_in{TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN};
-      IntConfig 
transaction_active_timeout_out{TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_OUT};
-      IntConfig 
transaction_no_activity_timeout_in{TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_IN};
-      IntConfig 
transaction_no_activity_timeout_out{TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_OUT};
-      IntConfig 
uncacheable_requests_bypass_parent{TS_CONFIG_HTTP_UNCACHEABLE_REQUESTS_BYPASS_PARENT};
+      Cript::IntConfig 
transaction_active_timeout_in{TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN};
+      Cript::IntConfig 
transaction_active_timeout_out{TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_OUT};
+      Cript::IntConfig 
transaction_no_activity_timeout_in{TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_IN};
+      Cript::IntConfig 
transaction_no_activity_timeout_out{TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_OUT};
+      Cript::IntConfig 
uncacheable_requests_bypass_parent{TS_CONFIG_HTTP_UNCACHEABLE_REQUESTS_BYPASS_PARENT};
     }; // End class Http
 
   public:
@@ -323,13 +298,13 @@ private:
     class Net
     {
     public:
-      IntConfig 
default_inactivity_timeout{TS_CONFIG_NET_DEFAULT_INACTIVITY_TIMEOUT};
-      IntConfig sock_notsent_lowat{TS_CONFIG_NET_SOCK_NOTSENT_LOWAT};
-      IntConfig sock_option_flag_out{TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT};
-      IntConfig sock_packet_mark_out{TS_CONFIG_NET_SOCK_PACKET_MARK_OUT};
-      IntConfig sock_packet_tos_out{TS_CONFIG_NET_SOCK_PACKET_TOS_OUT};
-      IntConfig 
sock_recv_buffer_size_out{TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT};
-      IntConfig 
sock_send_buffer_size_out{TS_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT};
+      Cript::IntConfig 
default_inactivity_timeout{TS_CONFIG_NET_DEFAULT_INACTIVITY_TIMEOUT};
+      Cript::IntConfig sock_notsent_lowat{TS_CONFIG_NET_SOCK_NOTSENT_LOWAT};
+      Cript::IntConfig 
sock_option_flag_out{TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT};
+      Cript::IntConfig 
sock_packet_mark_out{TS_CONFIG_NET_SOCK_PACKET_MARK_OUT};
+      Cript::IntConfig sock_packet_tos_out{TS_CONFIG_NET_SOCK_PACKET_TOS_OUT};
+      Cript::IntConfig 
sock_recv_buffer_size_out{TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT};
+      Cript::IntConfig 
sock_send_buffer_size_out{TS_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT};
     }; // End class Net
 
   public:
@@ -342,8 +317,8 @@ private:
       class Vc
       {
       public:
-        IntConfig 
default_buffer_index{TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX};
-        IntConfig 
default_buffer_water_mark{TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK};
+        Cript::IntConfig 
default_buffer_index{TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX};
+        Cript::IntConfig 
default_buffer_water_mark{TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK};
       }; // End class Vc
 
     public:
@@ -355,7 +330,7 @@ private:
     Plugin plugin;
 
   public:
-    IntConfig srv_enabled{TS_CONFIG_SRV_ENABLED};
+    Cript::IntConfig srv_enabled{TS_CONFIG_SRV_ENABLED};
 
   private:
     class Ssl
@@ -422,8 +397,8 @@ private:
       Client client;
 
     public:
-      IntConfig hsts_include_subdomains{TS_CONFIG_SSL_HSTS_INCLUDE_SUBDOMAINS};
-      IntConfig hsts_max_age{TS_CONFIG_SSL_HSTS_MAX_AGE};
+      Cript::IntConfig 
hsts_include_subdomains{TS_CONFIG_SSL_HSTS_INCLUDE_SUBDOMAINS};
+      Cript::IntConfig hsts_max_age{TS_CONFIG_SSL_HSTS_MAX_AGE};
     }; // End class Ssl
 
   public:
@@ -433,7 +408,7 @@ private:
     class Url_Remap
     {
     public:
-      IntConfig pristine_host_hdr{TS_CONFIG_URL_REMAP_PRISTINE_HOST_HDR};
+      Cript::IntConfig 
pristine_host_hdr{TS_CONFIG_URL_REMAP_PRISTINE_HOST_HDR};
     }; // End class Url_Remap
 
   public:
@@ -443,8 +418,8 @@ private:
     class Websocket
     {
     public:
-      IntConfig active_timeout{TS_CONFIG_WEBSOCKET_ACTIVE_TIMEOUT};
-      IntConfig no_activity_timeout{TS_CONFIG_WEBSOCKET_NO_ACTIVITY_TIMEOUT};
+      Cript::IntConfig active_timeout{TS_CONFIG_WEBSOCKET_ACTIVE_TIMEOUT};
+      Cript::IntConfig 
no_activity_timeout{TS_CONFIG_WEBSOCKET_NO_ACTIVITY_TIMEOUT};
     }; // End class Websocket
 
   public:
diff --git a/include/cripts/ConfigsBase.hpp b/include/cripts/ConfigsBase.hpp
new file mode 100644
index 0000000000..4ceb27fcfa
--- /dev/null
+++ b/include/cripts/ConfigsBase.hpp
@@ -0,0 +1,104 @@
+
+/*
+  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.
+*/
+
+#pragma once
+
+#include "ts/ts.h"
+
+#include "cripts/Lulu.hpp"
+#include "cripts/Context.hpp"
+
+namespace Cript
+{
+class IntConfig
+{
+public:
+  IntConfig() = delete;
+  explicit IntConfig(TSOverridableConfigKey key) : _key(key) {}
+
+  // Implemented later in Configs.cc
+  integer _get(Cript::Context *context) const;
+  void    _set(Cript::Context *context, integer value);
+
+private:
+  const TSOverridableConfigKey _key;
+}; // namespace Criptclass IntConfig
+
+class FloatConfig
+{
+public:
+  FloatConfig() = delete;
+  explicit FloatConfig(TSOverridableConfigKey key) : _key(key) {}
+
+  // Implemented later in Configs.cc
+  float _get(Cript::Context *context) const;
+  void  _set(Cript::Context *context, float value);
+
+private:
+  const TSOverridableConfigKey _key;
+};
+
+class Records
+{
+  using self_type = Records;
+
+public:
+  using ValueType = std::variant<TSMgmtInt, TSMgmtFloat, std::string>;
+
+  Records(const self_type &)              = delete;
+  Records()                               = delete;
+  self_type &operator=(const self_type &) = delete;
+
+  Records(self_type &&that) = default;
+
+  explicit Records(const Cript::string_view name);
+
+  ValueType _get(const Cript::Context *context) const;
+  bool      _set(const Cript::Context *context, const ValueType value);
+
+  [[nodiscard]] TSOverridableConfigKey
+  key() const
+  {
+    return _key;
+  }
+
+  [[nodiscard]] TSRecordDataType
+  type() const
+  {
+    return _type;
+  }
+
+  [[nodiscard]] Cript::string_view
+  name() const
+  {
+    return _name;
+  }
+
+  [[nodiscard]] bool
+  loaded() const
+  {
+    return (_key != TS_CONFIG_NULL && _type != TS_RECORDDATATYPE_NULL);
+  }
+
+private:
+  Cript::string          _name;
+  TSOverridableConfigKey _key  = TS_CONFIG_NULL;
+  TSRecordDataType       _type = TS_RECORDDATATYPE_NULL;
+};
+} // namespace Cript
diff --git a/include/cripts/Connections.hpp b/include/cripts/Connections.hpp
index c3bb85d508..02d2e87a70 100644
--- a/include/cripts/Connections.hpp
+++ b/include/cripts/Connections.hpp
@@ -25,6 +25,7 @@ class Context;
 #include "ts/apidefs.h"
 #include "ts/ts.h"
 
+#include "cripts/Lulu.hpp"
 #include "cripts/Matcher.hpp"
 
 namespace Cript
@@ -42,9 +43,8 @@ class IP : public swoc::IPAddr
 
 public:
   using super_type::IPAddr;
-
-  IP(const IP &)             = delete;
-  void operator=(const IP &) = delete;
+  IP(const self_type &)             = delete;
+  void operator=(const self_type &) = delete;
 
   Cript::string_view getSV(unsigned ipv4_cidr = 32, unsigned ipv6_cidr = 128);
   Cript::string_view
@@ -77,8 +77,8 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    Dscp()                       = default;
-    void operator=(const Dscp &) = delete;
+    Dscp()                            = default;
+    void operator=(const self_type &) = delete;
 
     // This is not perfect, but there's currently no ATS Get() mechanism to 
see a connections
     // current DSCP options.
@@ -105,8 +105,8 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    Pacing()                       = default;
-    void operator=(const Pacing &) = delete;
+    Pacing()                          = default;
+    void operator=(const self_type &) = delete;
 
     // This is not perfect, but there's currently no ATS Get() mechanism to 
see a connections
     // current PACING options.
@@ -147,8 +147,8 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    Congestion()                       = default;
-    void operator=(const Congestion &) = delete;
+    Congestion()                      = default;
+    void operator=(const self_type &) = delete;
 
     self_type &
     operator=(Cript::string_view const &str)
@@ -179,8 +179,8 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    Mark()                       = default;
-    void operator=(const Mark &) = delete;
+    Mark()                            = default;
+    void operator=(const self_type &) = delete;
 
     // Same here, no API in ATS to Get() the mark on a VC.
     operator integer() const { return _val; }
@@ -206,8 +206,8 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    Geo()                       = default;
-    void operator=(const Geo &) = delete;
+    Geo()                             = default;
+    void operator=(const self_type &) = delete;
 
     [[nodiscard]] Cript::string ASN() const;
     [[nodiscard]] Cript::string ASNName() const;
@@ -225,8 +225,9 @@ class ConnBase
   public:
     friend class ConnBase;
 
-    TcpInfo()                       = default;
-    void operator=(const TcpInfo &) = delete;
+    TcpInfo()                         = default;
+    TcpInfo(const self_type &)        = delete;
+    void operator=(const self_type &) = delete;
 
     Cript::string_view log();
 
@@ -306,10 +307,11 @@ class ConnBase
   }; // End class ConnBase::TcpInfo
 
 public:
-  void operator=(const ConnBase &) = delete;
-
   ConnBase() { dscp._owner = congestion._owner = tcpinfo._owner = geo._owner = 
pacing._owner = mark._owner = this; }
 
+  ConnBase(const self_type &)       = delete;
+  void operator=(const self_type &) = delete;
+
   [[nodiscard]] virtual int fd() const = 0; // This needs the txnp from the 
Context
 
   [[nodiscard]] struct sockaddr const *
@@ -370,10 +372,9 @@ class Connection : public detail::ConnBase
   using self_type = Connection;
 
 public:
-  Connection() = default;
-
-  void operator=(const Connection &) = delete;
-  Connection(const Connection &)     = delete;
+  Connection()                      = default;
+  Connection(const self_type &)     = delete;
+  void operator=(const self_type &) = delete;
 
   [[nodiscard]] int  fd() const override;
   [[nodiscard]] int  count() const override;
@@ -394,7 +395,7 @@ public:
   [[nodiscard]] Cript::IP
   localIP() const override
   {
-    return Cript::IP(TSHttpTxnIncomingAddrGet(_state->txnp));
+    return Cript::IP{TSHttpTxnIncomingAddrGet(_state->txnp)};
   }
 
 }; // End class Client::Connection
@@ -409,9 +410,9 @@ class Connection : public detail::ConnBase
   using self_type = Connection;
 
 public:
-  Connection()                       = default;
-  void operator=(const Connection &) = delete;
-  Connection(const Connection &)     = delete;
+  Connection()                      = default;
+  Connection(const self_type &)     = delete;
+  void operator=(const self_type &) = delete;
 
   [[nodiscard]] int  fd() const override;
   [[nodiscard]] int  count() const override;
@@ -432,7 +433,7 @@ public:
   [[nodiscard]] Cript::IP
   localIP() const override
   {
-    return Cript::IP(TSHttpTxnOutgoingAddrGet(_state->txnp));
+    return Cript::IP{TSHttpTxnOutgoingAddrGet(_state->txnp)};
   }
 
 }; // End class Server::Connection
diff --git a/include/cripts/Context.hpp b/include/cripts/Context.hpp
index 07436f1d8c..d6eedc24a3 100644
--- a/include/cripts/Context.hpp
+++ b/include/cripts/Context.hpp
@@ -19,8 +19,8 @@
 
 #include <array>
 #include <variant>
-#include "ts/remap.h"
 #include "ts/ts.h"
+#include "ts/remap.h"
 
 #include "cripts/Instance.hpp"
 #include "cripts/Headers.hpp"
diff --git a/include/cripts/Crypto.hpp b/include/cripts/Crypto.hpp
index 5ddfd9653c..a45b604873 100644
--- a/include/cripts/Crypto.hpp
+++ b/include/cripts/Crypto.hpp
@@ -29,6 +29,8 @@
 #include "ts/ts.h"
 #include "ts/remap.h"
 
+#include "cripts/Lulu.hpp"
+
 namespace Crypto
 {
 class Base64
@@ -36,9 +38,9 @@ class Base64
   using self_type = Base64;
 
 public:
-  Base64()                       = delete;
-  Base64(const Base64 &)         = delete;
-  void operator=(const Base64 &) = delete;
+  Base64()                          = delete;
+  Base64(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
   static Cript::string encode(Cript::string_view str);
   static Cript::string decode(Cript::string_view str);
@@ -50,9 +52,9 @@ class Escape
   using self_type = Escape;
 
 public:
-  Escape()                       = delete;
-  Escape(const Escape &)         = delete;
-  void operator=(const Escape &) = delete;
+  Escape()                          = delete;
+  Escape(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
   static Cript::string encode(Cript::string_view str);
   static Cript::string decode(Cript::string_view str);
@@ -67,10 +69,11 @@ namespace detail
     using self_type = Digest;
 
   public:
-    Digest() = delete;
+    Digest()                          = delete;
+    void operator=(const self_type &) = delete;
+    Digest(self_type &&that)          = default; // For later use
+
     Digest(size_t len) : _length(len) { TSAssert(len <= EVP_MAX_MD_SIZE); }
-    // ToDo: Not sure why, but some compilers says this is deprecated
-    // void operator=(const Digest &) = delete;
 
     [[nodiscard]] Cript::string
     hex() const
@@ -110,8 +113,8 @@ namespace detail
     using self_type = Cipher;
 
   public:
-    void operator=(const Cipher &) = delete;
-    Cipher()                       = delete;
+    Cipher()                          = delete;
+    void operator=(const self_type &) = delete;
 
     ~Cipher() { EVP_CIPHER_CTX_free(_ctx); }
 
@@ -165,10 +168,10 @@ class SHA256 : public detail::Digest
 public:
   SHA256() : detail::Digest(SHA256_DIGEST_LENGTH){};
 
-  SHA256(const SHA256 &)         = delete;
-  void operator=(const SHA256 &) = delete;
+  SHA256(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
-  static SHA256 encode(Cript::string_view str);
+  static self_type encode(Cript::string_view str);
 }; // End class SHA256
 
 class SHA512 : public detail::Digest
@@ -181,10 +184,10 @@ class SHA512 : public detail::Digest
 public:
   SHA512() : detail::Digest(SHA512_DIGEST_LENGTH){};
 
-  SHA512(const SHA512 &)         = delete;
-  void operator=(const SHA512 &) = delete;
+  SHA512(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
-  static SHA512 encode(Cript::string_view str);
+  static self_type encode(Cript::string_view str);
 }; // End class SHA512
 
 class MD5 : public detail::Digest
@@ -197,10 +200,10 @@ class MD5 : public detail::Digest
 public:
   MD5() : detail::Digest(MD5_DIGEST_LENGTH){};
 
-  MD5(const MD5 &)            = delete;
-  void operator=(const MD5 &) = delete;
+  MD5(const self_type &)            = delete;
+  void operator=(const self_type &) = delete;
 
-  static MD5 encode(Cript::string_view str);
+  static self_type encode(Cript::string_view str);
 }; // End class MD5
 
 class AES256 : public detail::Cipher
@@ -208,7 +211,7 @@ class AES256 : public detail::Cipher
   using super_type = detail::Cipher;
   using self_type  = AES256;
 
-  AES256(AES256 &&that) = default;
+  AES256(AES256 &&that) noexcept = default;
 
 public:
   using super_type::Cipher;
@@ -217,13 +220,13 @@ public:
   AES256(const SHA256 &key) : super_type(key.hash(), SHA256_DIGEST_LENGTH) {}
   AES256(const unsigned char *key) : super_type(key, SHA256_DIGEST_LENGTH) {}
 
-  AES256(const AES256 &)         = delete;
-  void operator=(const AES256 &) = delete;
+  AES256(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
   // The key has to be 256-bit afaik
-  static AES256 encrypt(Cript::string_view str, const unsigned char *key);
+  static self_type encrypt(Cript::string_view str, const unsigned char *key);
 
-  static AES256
+  static self_type
   encrypt(Cript::string_view str, SHA256 &key)
   {
     return encrypt(str, key.hash());
@@ -251,10 +254,10 @@ namespace HMAC
   public:
     SHA256() : detail::Digest(SHA256_DIGEST_LENGTH){};
 
-    SHA256(const SHA256 &)         = delete;
-    void operator=(const SHA256 &) = delete;
+    SHA256(const self_type &)         = delete;
+    void operator=(const self_type &) = delete;
 
-    static SHA256 encrypt(Cript::string_view str, const Cript::string &key);
+    static self_type encrypt(Cript::string_view str, const Cript::string &key);
   }; // End class SHA256
 } // namespace HMAC
 
diff --git a/include/cripts/Epilogue.hpp b/include/cripts/Epilogue.hpp
index 0a710a5b99..6b26d62a1a 100644
--- a/include/cripts/Epilogue.hpp
+++ b/include/cripts/Epilogue.hpp
@@ -17,10 +17,11 @@
 */
 #pragma once
 
-#include "ts/remap.h"
 #include "ts/ts.h"
+#include "ts/remap.h"
 
 #include "cripts/Bundle.hpp"
+#include "cripts/Context.hpp"
 
 // Case hierarchy, this is from ATS ts_meta.h.
 template <unsigned N> struct CaseTag : public CaseTag<N - 1> {
diff --git a/include/cripts/Error.hpp b/include/cripts/Error.hpp
index 3d1aa4380b..e1085ffafa 100644
--- a/include/cripts/Error.hpp
+++ b/include/cripts/Error.hpp
@@ -17,10 +17,12 @@
 */
 #pragma once
 
+#include <utility>
+
 #include "ts/ts.h"
 #include "ts/remap.h"
 
-#include <utility>
+#include "cripts/Lulu.hpp"
 
 namespace Cript
 {
@@ -35,9 +37,9 @@ public:
     using self_type = Reason;
 
   public:
-    Reason()                       = default;
-    Reason(const Reason &)         = delete;
-    void operator=(const Reason &) = delete;
+    Reason()                          = default;
+    Reason(const self_type &)         = delete;
+    void operator=(const self_type &) = delete;
 
     static void _set(Cript::Context *context, const Cript::string_view msg);
 
@@ -64,9 +66,9 @@ public:
     using self_type = Status;
 
   public:
-    Status()                       = default;
-    Status(const Status &)         = delete;
-    void operator=(const Status &) = delete;
+    Status()                          = default;
+    Status(const self_type &)         = delete;
+    void operator=(const self_type &) = delete;
 
     static void _set(Cript::Context *context, TSHttpStatus _status);
 
@@ -76,6 +78,8 @@ public:
       _set(context, static_cast<TSHttpStatus>(_status));
     }
 
+    static TSHttpStatus _get(Cript::Context *context);
+
     [[nodiscard]] TSHttpStatus
     status() const
     {
@@ -89,6 +93,12 @@ public:
       _status = status;
     }
 
+    [[nodiscard]] TSHttpStatus
+    getter() const
+    {
+      return _status;
+    }
+
   private:
     TSHttpStatus _status = TS_HTTP_STATUS_NONE;
   }; // End class Status
diff --git a/include/cripts/Files.hpp b/include/cripts/Files.hpp
index cc2b0bffc4..624a72e015 100644
--- a/include/cripts/Files.hpp
+++ b/include/cripts/Files.hpp
@@ -18,7 +18,6 @@
 #pragma once
 
 #include <filesystem>
-#include <iostream>
 #include <fstream>
 
 #include "cripts/Lulu.hpp"
@@ -26,7 +25,17 @@
 namespace File
 {
 
-using Path = std::filesystem::path;
+class Path : public std::filesystem::path
+{
+  using super_type = std::filesystem::path;
+  using self_type  = Path;
+
+public:
+  using super_type::super_type;
+
+  self_type &rebase();
+};
+
 using Type = std::filesystem::file_type;
 
 std::filesystem::file_status Status(const Path &path);
@@ -38,9 +47,9 @@ namespace Line
     using self_type = Reader;
 
   public:
-    Reader()                       = delete;
-    Reader(const Reader &)         = delete;
-    void operator=(const Reader &) = delete;
+    Reader()                          = delete;
+    Reader(const self_type &)         = delete;
+    void operator=(const self_type &) = delete;
 
     explicit Reader(const std::string &path) : _path(path), _stream{path} {}
     explicit Reader(const Cript::string_view path) : _path(path), 
_stream{_path} {}
diff --git a/include/cripts/Headers.hpp b/include/cripts/Headers.hpp
index 55ab969863..22ec36d088 100644
--- a/include/cripts/Headers.hpp
+++ b/include/cripts/Headers.hpp
@@ -470,13 +470,12 @@ class Request : public RequestHeader
   using self_type  = Request;
 
 public:
-  Request() = default;
-
-  Request(const Request &)        = delete;
-  void operator=(const Request &) = delete;
+  Request()                         = default;
+  Request(const self_type &)        = delete;
+  void operator=(const self_type &) = delete;
 
   // Implemented later, because needs the context.
-  static Request &_get(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
 
 }; // End class Client::Request
 
@@ -486,13 +485,12 @@ class Response : public ResponseHeader
   using self_type  = Response;
 
 public:
-  Response() = default;
-
-  Response(const Response &)       = delete;
-  void operator=(const Response &) = delete;
+  Response()                        = default;
+  Response(const self_type &)       = delete;
+  void operator=(const self_type &) = delete;
 
   // Implemented later, because needs the context.
-  static Response &_get(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
 
 }; // End class Client::Response
 
@@ -506,10 +504,9 @@ class Request : public RequestHeader
   using self_type  = Request;
 
 public:
-  Request() = default;
-
-  Request(const Request &)        = delete;
-  void operator=(const Request &) = delete;
+  Request()                         = default;
+  Request(const self_type &)        = delete;
+  void operator=(const self_type &) = delete;
 
   // Implemented later, because needs the context.
   static Request &_get(Cript::Context *context);
@@ -521,13 +518,12 @@ class Response : public ResponseHeader
   using self_type  = Response;
 
 public:
-  Response() = default;
-
-  Response(const Response &)       = delete;
-  void operator=(const Response &) = delete;
+  Response()                        = default;
+  Response(const self_type &)       = delete;
+  void operator=(const self_type &) = delete;
 
   // Implemented later, because needs the context.
-  static Response &_get(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
 
 }; // End class Server::Response
 
diff --git a/include/cripts/Instance.hpp b/include/cripts/Instance.hpp
index 7b6cf13c53..a3b4742e2d 100644
--- a/include/cripts/Instance.hpp
+++ b/include/cripts/Instance.hpp
@@ -21,8 +21,8 @@
 #include <variant>
 #include <unordered_map>
 
-#include "ts/remap.h"
 #include "ts/ts.h"
+#include "ts/remap.h"
 
 #include "cripts/Plugins.hpp"
 #include "cripts/Metrics.hpp"
@@ -39,9 +39,9 @@ class Instance
 public:
   using DataType = std::variant<integer, double, boolean, void *, 
Cript::string>;
 
-  Instance()                       = delete;
-  Instance(const Instance &)       = delete;
-  void operator=(const Instance &) = delete;
+  Instance()                        = delete;
+  Instance(const self_type &)       = delete;
+  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__); }
@@ -142,9 +142,11 @@ private:
 // A little wrapper / hack to make the do_create_instance take what looks like 
a context.
 // This is only used during instantiation, not at runtime when the instance is 
used.
 struct InstanceContext {
-  InstanceContext()                        = delete;
-  void operator=(const InstanceContext &)  = delete;
-  InstanceContext(const InstanceContext &) = delete;
+  using self_type = InstanceContext;
+
+  InstanceContext()                  = delete;
+  InstanceContext(const self_type &) = delete;
+  void operator=(const self_type &)  = delete;
 
   InstanceContext(Cript::Instance &inst) : p_instance(inst) {}
 
diff --git a/include/cripts/Lulu.hpp b/include/cripts/Lulu.hpp
index af79a69a00..e32dbc05b8 100644
--- a/include/cripts/Lulu.hpp
+++ b/include/cripts/Lulu.hpp
@@ -314,7 +314,7 @@ public:
 
   // This allows for a std::string to be moved to a Cript::string
   string(super_type &&that) : super_type(std::move(that)) {}
-  string(self_type &&that) : super_type(std::move(that)) {}
+  string(self_type &&that) noexcept : super_type(that) {}
 
   operator Cript::string_view() const { return {this->c_str(), this->size()}; }
 
@@ -423,9 +423,9 @@ class Control
     using self_type = Base;
 
   public:
-    Base()                       = delete;
-    Base(const Base &)           = delete;
-    void operator=(const Base &) = delete;
+    Base()                            = delete;
+    Base(const self_type &)           = delete;
+    void operator=(const self_type &) = delete;
 
     explicit Base(TSHttpCntlType ctrl) : _ctrl(ctrl) {}
     bool _get(Cript::Context *context) const;
@@ -440,9 +440,9 @@ class Control
     using self_type = Cache;
 
   public:
-    Cache()                       = default;
-    Cache(const Cache &)          = delete;
-    void operator=(const Cache &) = delete;
+    Cache()                           = default;
+    Cache(const self_type &)          = delete;
+    void operator=(const self_type &) = delete;
 
     Base response{TS_HTTP_CNTL_RESPONSE_CACHEABLE};
     Base request{TS_HTTP_CNTL_REQUEST_CACHEABLE};
@@ -463,9 +463,9 @@ class Versions
   using self_type = Versions;
 
 public:
-  Versions()                       = default;
-  Versions(const Versions &)       = delete;
-  void operator=(const Versions &) = delete;
+  Versions()                        = default;
+  Versions(const self_type &)       = delete;
+  void operator=(const self_type &) = delete;
 
   Cript::string_view
   getSV()
@@ -505,9 +505,9 @@ private:
     using self_type = Major;
 
   public:
-    Major()                       = default;
-    Major(const Major &)          = delete;
-    void operator=(const Major &) = delete;
+    Major()                           = default;
+    Major(const self_type &)          = delete;
+    void operator=(const self_type &) = delete;
 
     operator integer() const // This should not be explicit
     {
@@ -521,9 +521,9 @@ private:
     using self_type = Minor;
 
   public:
-    Minor()                       = default;
-    Minor(const Minor &)          = delete;
-    void operator=(const Minor &) = delete;
+    Minor()                           = default;
+    Minor(const self_type &)          = delete;
+    void operator=(const self_type &) = delete;
 
     operator integer() const // This should not be explicit
     {
@@ -537,9 +537,9 @@ private:
     using self_type = Minor;
 
   public:
-    Patch()                       = default;
-    Patch(const Patch &)          = delete;
-    void operator=(const Patch &) = delete;
+    Patch()                           = default;
+    Patch(const self_type &)          = delete;
+    void operator=(const self_type &) = delete;
 
     operator integer() const // This should not be explicit
     {
diff --git a/include/cripts/Matcher.hpp b/include/cripts/Matcher.hpp
index 20e0defd41..0027c7f230 100644
--- a/include/cripts/Matcher.hpp
+++ b/include/cripts/Matcher.hpp
@@ -38,18 +38,19 @@ namespace Range
     using self_type  = Range::IP;
 
   public:
-    IP() = delete;
+    IP()                              = delete;
+    void operator=(const self_type &) = delete;
+
     explicit IP(Cript::string_view ip) { add(ip); }
-    void operator=(const IP &) = delete;
 
-    IP(IP const &ip)
+    IP(self_type const &ip)
     {
       for (auto &it : ip) {
         mark(it);
       }
     }
 
-    IP(const std::initializer_list<IP> &list)
+    IP(const std::initializer_list<self_type> &list)
     {
       for (auto &it : list) {
         for (auto &it2 : it) {
@@ -102,11 +103,11 @@ namespace List
   public:
     Method() = delete;
     explicit Method(Header::Method method) : std::vector<Header::Method>() { 
push_back(method); }
-    void operator=(const Method &) = delete;
+    void operator=(const self_type &) = delete;
 
-    Method(Method const &method) : std::vector<Header::Method>() { 
insert(end(), std::begin(method), std::end(method)); }
+    Method(self_type const &method) : std::vector<Header::Method>() { 
insert(end(), std::begin(method), std::end(method)); }
 
-    Method(const std::initializer_list<Method> &list)
+    Method(const std::initializer_list<self_type> &list)
     {
       for (auto &it : list) {
         insert(end(), std::begin(it), std::end(it));
@@ -148,6 +149,8 @@ public:
   using Regex        = std::tuple<Cript::string, pcre2_code *>;
   using RegexEntries = std::vector<Regex>;
 
+  using self_type = PCRE;
+
   class Result
   {
   public:
@@ -206,10 +209,11 @@ public:
     Cript::string_view      _subject;
   };
 
-  PCRE() = default;
+  PCRE()                            = default;
+  PCRE(const self_type &)           = delete;
+  void operator=(const self_type &) = delete;
+
   PCRE(Cript::string_view regex, uint32_t options = 0) { add(regex, options); }
-  PCRE(const PCRE &)           = delete;
-  void operator=(const PCRE &) = delete;
 
   PCRE(std::initializer_list<Cript::string_view> list, uint32_t options = 0)
   {
diff --git a/include/cripts/Plugins.hpp b/include/cripts/Plugins.hpp
index afde5c862b..dbf9a0bcf0 100644
--- a/include/cripts/Plugins.hpp
+++ b/include/cripts/Plugins.hpp
@@ -17,6 +17,8 @@
 */
 #pragma once
 
+#include "cripts/Lulu.hpp"
+
 // This is not awesome, but these APIs are internal to ATS. Once Cripts becomes
 // part of the ATS core, we can remove this.
 
@@ -31,22 +33,20 @@ class Remap
   using self_type = Remap;
 
 public:
-  Remap() = default;
+  Remap()                                 = default;
+  Remap(const self_type &)                = delete;
+  self_type &operator=(const self_type &) = delete;
+  self_type &operator=(self_type &&)      = default;
 
-  Remap(Remap &&other)
+  Remap(Remap &&other) noexcept
   {
     _plugin       = other._plugin;
     _valid        = other._valid;
     other._plugin = nullptr;
   }
 
-  Remap(const Remap &) = delete;
-
   ~Remap() { cleanup(); }
 
-  Remap &operator=(Remap &&)      = default;
-  Remap &operator=(const Remap &) = delete;
-
   void _runRemap(Cript::Context *context);
 
   void cleanup();
diff --git a/include/cripts/Preamble.hpp b/include/cripts/Preamble.hpp
index 6e96b15751..f15531af10 100644
--- a/include/cripts/Preamble.hpp
+++ b/include/cripts/Preamble.hpp
@@ -17,13 +17,15 @@
 */
 #pragma once
 
-#include <memory>
+// These are technically not needed, but useful to have around for advanced
+// Cripters.
 #include <algorithm>
 #include <vector>
 #include <string>
 #include <string_view>
 #include <chrono>
 #include <climits>
+#include <iostream> // Useful for debugging
 
 #include <fmt/core.h>
 
@@ -50,6 +52,7 @@
 #include "cripts/Headers.hpp"
 #include "cripts/Urls.hpp"
 #include "cripts/Configs.hpp"
+#include "cripts/ConfigsBase.hpp"
 #include "cripts/Connections.hpp"
 #include "cripts/UUID.hpp"
 #include "cripts/Matcher.hpp"
diff --git a/include/cripts/Time.hpp b/include/cripts/Time.hpp
index 982628e58e..c24234a5b6 100644
--- a/include/cripts/Time.hpp
+++ b/include/cripts/Time.hpp
@@ -19,8 +19,10 @@
 
 #include <ctime>
 
-#include "ts/remap.h"
 #include "ts/ts.h"
+#include "ts/remap.h"
+
+#include "cripts/Lulu.hpp"
 
 // This is lame, but until C++20, we're missing important features from
 // std::chrono :-/ Todo: Rewrite this with std::chrono when it has things like
@@ -33,9 +35,9 @@ class BaseTime
   using self_type = detail::BaseTime;
 
 public:
-  BaseTime()                       = default;
-  BaseTime(const BaseTime &)       = delete;
-  void operator=(const BaseTime &) = delete;
+  BaseTime()                        = default;
+  BaseTime(const self_type &)       = delete;
+  void operator=(const self_type &) = delete;
 
   operator integer() const { return epoch(); }
 
@@ -109,9 +111,10 @@ class Local : public detail::BaseTime
   using self_type  = Local;
 
 public:
+  Local(const self_type &)          = delete;
+  void operator=(const self_type &) = delete;
+
   Local() { localtime_r(&_now, static_cast<struct tm *>(&_result)); }
-  Local(const Local &)          = delete;
-  void operator=(const Local &) = delete;
 
   // Factory, for consistency with ::get()
   static Local
diff --git a/include/cripts/Transaction.hpp b/include/cripts/Transaction.hpp
index 18dda388b8..879f34c925 100644
--- a/include/cripts/Transaction.hpp
+++ b/include/cripts/Transaction.hpp
@@ -29,7 +29,7 @@
 namespace Cript
 {
 // This is a bitfield, used to disable a particular callback from a previous 
hook
-enum Callbacks {
+enum Callbacks : std::uint8_t {
   NONE             = 0,
   DO_REMAP         = 1,
   DO_POST_REMAP    = 2,
diff --git a/include/cripts/UUID.hpp b/include/cripts/UUID.hpp
index b1b28ec396..74005d0176 100644
--- a/include/cripts/UUID.hpp
+++ b/include/cripts/UUID.hpp
@@ -17,6 +17,7 @@
 */
 #pragma once
 
+#include "cripts/Lulu.hpp"
 namespace Cript
 {
 class Context;
@@ -32,9 +33,9 @@ class Process
   using self_type = Process;
 
 public:
-  Process()                       = delete;
-  Process(const Process &)        = delete;
-  void operator=(const Process &) = delete;
+  Process()                         = delete;
+  Process(const self_type &)        = delete;
+  void operator=(const self_type &) = delete;
 
   // This doesn't use the context so we can implement it here
   static Cript::string
@@ -52,9 +53,9 @@ class Unique
   using self_type = Unique;
 
 public:
-  Unique()                       = delete;
-  Unique(const Unique &)         = delete;
-  void operator=(const Unique &) = delete;
+  Unique()                          = delete;
+  Unique(const self_type &)         = delete;
+  void operator=(const self_type &) = delete;
 
   static Cript::string _get(Cript::Context *context);
 
@@ -65,9 +66,9 @@ class Request
   using self_type = Request;
 
 public:
-  Request()                       = delete;
-  Request(const Request &)        = delete;
-  void operator=(const Request &) = delete;
+  Request()                         = delete;
+  Request(const self_type &)        = delete;
+  void operator=(const self_type &) = delete;
 
   static Cript::string _get(Cript::Context *context);
 
diff --git a/include/cripts/Urls.hpp b/include/cripts/Urls.hpp
index 51f3ba42d0..2c37334e27 100644
--- a/include/cripts/Urls.hpp
+++ b/include/cripts/Urls.hpp
@@ -17,16 +17,13 @@
 */
 #pragma once
 
-#include <cstring>
-#include <iostream>
-#include <sstream>
 #include <string>
 #include <string_view>
 #include <unordered_map>
 #include <vector>
 
-#include "ts/remap.h"
 #include "ts/ts.h"
+#include "ts/remap.h"
 
 #include "cripts/Headers.hpp"
 
@@ -514,11 +511,23 @@ public:
 
   }; // End class Url::Query
 
+  class Matrix : public Component
+  {
+    using super_type = Component;
+    using self_type  = Matrix;
+
+    friend class Url;
+
+  public:
+    Matrix() = default;
+    Cript::string_view getSV() override;
+    self_type          operator=(Cript::string_view matrix);
+
+  }; // End class Url::Matrix
+
 public:
   Url() = default;
 
-  ~Url() { reset(); }
-
   // Clear anything "cached" in the Url, this is rather draconian, but it's 
safe...
   virtual void
   reset()
@@ -534,45 +543,46 @@ public:
     _state = nullptr;
   }
 
-  bool
+  [[nodiscard]] bool
   initialized() const
   {
     return (_state != nullptr);
   }
 
-  bool
+  [[nodiscard]] bool
   modified() const
   {
     return _modified;
   }
 
-  TSMLoc
+  [[nodiscard]] TSMLoc
   urlp() const
   {
     return _urlp;
   }
 
-  virtual bool
+  [[nodiscard]] virtual bool
   readOnly() const
   {
     return false;
   }
 
   // Getters / setters for the full URL
-  Cript::string url() const;
+  [[nodiscard]] Cript::string url() const;
 
-  Host   host;
   Scheme scheme;
+  Host   host;
+  Port   port;
   Path   path;
   Query  query;
-  Port   port;
+  Matrix matrix;
 
 protected:
   void
   _initialize(Cript::Transaction *state)
   {
-    _state      = state;
-    host._owner = path._owner = scheme._owner = query._owner = port._owner = 
this;
+    _state        = state;
+    scheme._owner = host._owner = port._owner = path._owner = query._owner = 
matrix._owner = this;
   }
 
   TSMBuffer           _bufp     = nullptr; // These two gets setup via 
initializing, to appropriate headers
@@ -594,13 +604,13 @@ class URL : public Cript::Url
   using self_type  = URL;
 
 public:
-  URL()                       = default;
-  URL(const URL &)            = delete;
-  void operator=(const URL &) = delete;
+  URL()                             = default;
+  URL(const self_type &)            = delete;
+  void operator=(const self_type &) = delete;
 
-  static URL &_get(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
 
-  bool
+  [[nodiscard]] bool
   readOnly() const override
   {
     return true;
@@ -618,9 +628,9 @@ class URL : public Cript::Url
   using self_type  = URL;
 
 public:
-  URL()                       = default;
-  URL(const URL &)            = delete;
-  void operator=(const URL &) = delete;
+  URL()                             = default;
+  URL(const self_type &)            = delete;
+  void operator=(const self_type &) = delete;
 
   // We must not release the bufp etc. since it comes from the RRI structure
   void
@@ -628,8 +638,8 @@ public:
   {
   }
 
-  static URL &_get(Cript::Context *context);
-  bool        _update(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
+  bool              _update(Cript::Context *context);
 
 private:
   void _initialize(Cript::Context *context);
@@ -648,9 +658,9 @@ namespace From
     using self_type  = URL;
 
   public:
-    URL()                       = default;
-    URL(const URL &)            = delete;
-    void operator=(const URL &) = delete;
+    URL()                             = default;
+    URL(const self_type &)            = delete;
+    void operator=(const self_type &) = delete;
 
     // We must not release the bufp etc. since it comes from the RRI structure
     void
@@ -658,14 +668,14 @@ namespace From
     {
     }
 
-    bool
+    [[nodiscard]] bool
     readOnly() const override
     {
       return true;
     }
 
-    static URL &_get(Cript::Context *context);
-    bool        _update(Cript::Context *context);
+    static self_type &_get(Cript::Context *context);
+    bool              _update(Cript::Context *context);
 
   private:
     void _initialize(Cript::Context *context);
@@ -682,9 +692,9 @@ namespace To
     using self_type  = URL;
 
   public:
-    URL()                       = default;
-    URL(const URL &)            = delete;
-    void operator=(const URL &) = delete;
+    URL()                             = default;
+    URL(const self_type &)            = delete;
+    void operator=(const self_type &) = delete;
 
     // We must not release the bufp etc. since it comes from the RRI structure
     void
@@ -692,14 +702,14 @@ namespace To
     {
     }
 
-    bool
+    [[nodiscard]] bool
     readOnly() const override
     {
       return true;
     }
 
-    static URL &_get(Cript::Context *context);
-    bool        _update(Cript::Context *context);
+    static self_type &_get(Cript::Context *context);
+    bool              _update(Cript::Context *context);
 
   private:
     void _initialize(Cript::Context *context);
@@ -718,12 +728,12 @@ class URL : public Cript::Url // ToDo: This can maybe be 
a subclass of Client::U
   using self_type  = URL;
 
 public:
-  URL()                       = default;
-  URL(const URL &)            = delete;
-  void operator=(const URL &) = delete;
+  URL()                             = default;
+  URL(const self_type &)            = delete;
+  void operator=(const self_type &) = delete;
 
-  static URL &_get(Cript::Context *context);
-  bool        _update(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
+  bool              _update(Cript::Context *context);
 
 private:
   void
@@ -747,12 +757,12 @@ class URL : public Cript::Url
   using self_type  = URL;
 
 public:
-  URL()                       = default;
-  URL(const URL &)            = delete;
-  void operator=(const URL &) = delete;
+  URL()                             = default;
+  URL(const self_type &)            = delete;
+  void operator=(const self_type &) = delete;
 
-  static URL &_get(Cript::Context *context);
-  bool        _update(Cript::Context *context);
+  static self_type &_get(Cript::Context *context);
+  bool              _update(Cript::Context *context);
 
 private:
   void
@@ -876,4 +886,19 @@ template <> struct formatter<Cript::Url::Query> {
   }
 };
 
+template <> struct formatter<Cript::Url::Matrix> {
+  constexpr auto
+  parse(format_parse_context &ctx) -> decltype(ctx.begin())
+  {
+    return ctx.begin();
+  }
+
+  template <typename FormatContext>
+  auto
+  format(Cript::Url::Matrix &matrix, FormatContext &ctx) -> decltype(ctx.out())
+  {
+    return fmt::format_to(ctx.out(), "{}", matrix.getSV());
+  }
+};
+
 } // namespace fmt
diff --git a/src/cripts/Bundles/Common.cc b/src/cripts/Bundles/Caching.cc
similarity index 63%
copy from src/cripts/Bundles/Common.cc
copy to src/cripts/Bundles/Caching.cc
index cb9f663771..6ca3816e1c 100644
--- a/src/cripts/Bundles/Common.cc
+++ b/src/cripts/Bundles/Caching.cc
@@ -16,30 +16,25 @@
   limitations under the License.
 */
 
-#include "cripts/Lulu.hpp"
 #include "cripts/Preamble.hpp"
-#include "cripts/Bundles/Common.hpp"
+#include "cripts/Bundles/Caching.hpp"
 
 namespace Bundle
 {
-const Cript::string Common::_name = "Bundle::Common";
+const Cript::string Caching::_name = "Bundle::Caching";
 
-bool
-Common::validate(std::vector<Cript::Bundle::Error> &errors) const
+void
+Caching::doRemap(Cript::Context *context)
 {
-  bool good = true;
-
-  // The .dscp() can only be 0 - 63
-  if (_dscp < 0 || _dscp > 63) {
-    errors.emplace_back("dscp must be between 0 and 63", name(), "dscp");
-    good = false;
+  // .disable(bool)
+  if (_disabled) {
+    proxy.config.http.cache.http.set(0);
+    CDebug("Caching disabled");
   }
-
-  return good;
 }
 
 void
-Common::doReadResponse(Cript::Context *context)
+Caching::doReadResponse(Cript::Context *context)
 {
   borrow resp = Server::Response::get();
 
@@ -49,16 +44,4 @@ Common::doReadResponse(Cript::Context *context)
   }
 }
 
-void
-Common::doRemap(Cript::Context *context)
-{
-  borrow conn = Client::Connection::get();
-
-  // .dscp(int)
-  if (_dscp > 0) {
-    CDebug("Setting DSCP = {}", _dscp);
-    conn.dscp = _dscp;
-  }
-}
-
 } // namespace Bundle
diff --git a/src/cripts/Bundles/Common.cc b/src/cripts/Bundles/Common.cc
index cb9f663771..2956c35bfd 100644
--- a/src/cripts/Bundles/Common.cc
+++ b/src/cripts/Bundles/Common.cc
@@ -16,7 +16,6 @@
   limitations under the License.
 */
 
-#include "cripts/Lulu.hpp"
 #include "cripts/Preamble.hpp"
 #include "cripts/Bundles/Common.hpp"
 
@@ -35,30 +34,124 @@ Common::validate(std::vector<Cript::Bundle::Error> 
&errors) const
     good = false;
   }
 
+  // Make sure we didn't encounter an error setting up the via headers
+  if (_client_via.first == 999 || _origin_via.first == 999) {
+    errors.emplace_back("via_header must be one of: disable, protocol, basic, 
detailed, full", name(), "via_header");
+    good = false;
+  }
+
+  // Make sure all configurations are of the correct type
+  for (auto &[rec, value] : _configs) {
+    switch (rec.type()) {
+    case TS_RECORDDATATYPE_INT:
+      if (!std::holds_alternative<TSMgmtInt>(value)) {
+        errors.emplace_back("Invalid value for config, expecting an integer", 
name(), rec.name());
+        good = false;
+      }
+      break;
+    case TS_RECORDDATATYPE_FLOAT:
+      if (!std::holds_alternative<TSMgmtFloat>(value)) {
+        errors.emplace_back("Invalid value for config, expecting a float", 
name(), rec.name());
+        good = false;
+      }
+      break;
+    case TS_RECORDDATATYPE_STRING:
+      if (!std::holds_alternative<std::string>(value)) {
+        errors.emplace_back("Invalid value for config, expecting an integer", 
name(), rec.name());
+        good = false;
+      }
+      break;
+
+    default:
+      errors.emplace_back("Invalid configuration type", name(), rec.name());
+      good = false;
+      break;
+    }
+  }
+
   return good;
 }
 
-void
-Common::doReadResponse(Cript::Context *context)
+Common::self_type &
+Common::via_header(const Cript::string_view &destination, const 
Cript::string_view &value)
+{
+  static const std::unordered_map<Cript::string_view, int> SettingValues = {
+    {"disable",  0  },
+    {"protocol", 1  },
+    {"basic",    2  },
+    {"detailed", 3  },
+    {"full",     4  },
+    {"none",     999}  // This is an error
+  };
+
+  needCallback(Cript::Callbacks::DO_REMAP);
+
+  int  val = 999;
+  auto it  = SettingValues.find(value);
+
+  if (it != SettingValues.end()) {
+    val = it->second;
+  }
+
+  if (destination.starts_with("client")) {
+    _client_via = {val, true};
+  } else if (destination.starts_with("origin") || 
destination.starts_with("server")) {
+    _origin_via = {val, true};
+  } else {
+    _client_via = _origin_via = {999, false};
+  }
+
+  return *this;
+}
+
+Common &
+Common::set_config(const Cript::string_view name, const 
Cript::Records::ValueType value)
 {
-  borrow resp = Server::Response::get();
+  Cript::Records rec(name);
+
+  if (rec.loaded()) {
+    needCallback(Cript::Callbacks::DO_REMAP);
+    _configs.emplace_back(std::move(rec), value);
+  }
 
-  // .cache_control(str)
-  if (!_cc.empty() && (resp.status > 199) && (resp.status < 400) && 
(resp["Cache-Control"].empty() || _force_cc)) {
-    resp["Cache-Control"] = _cc;
+  return *this;
+}
+
+Common &
+Common::set_config(std::vector<std::pair<const Cript::string_view, const 
Cript::Records::ValueType>> configs)
+{
+  for (auto &[name, value] : configs) {
+    set_config(name, value);
   }
+
+  return *this;
 }
 
 void
 Common::doRemap(Cript::Context *context)
 {
-  borrow conn = Client::Connection::get();
-
   // .dscp(int)
   if (_dscp > 0) {
+    borrow conn = Client::Connection::get();
+
     CDebug("Setting DSCP = {}", _dscp);
     conn.dscp = _dscp;
   }
+
+  // .via_header()
+  if (_client_via.second) {
+    CDebug("Setting Client Via = {}", _client_via.first);
+    proxy.config.http.insert_response_via_str.set(_client_via.first);
+  }
+  if (_origin_via.second) {
+    CDebug("Setting Origin Via = {}", _origin_via.first);
+    proxy.config.http.insert_request_via_str.set(_origin_via.first);
+  }
+
+  // .set_config()
+  for (auto &[rec, value] : _configs) {
+    rec._set(context, value);
+  }
 }
 
 } // namespace Bundle
diff --git a/src/cripts/Bundles/HRWBridge.cc b/src/cripts/Bundles/HRWBridge.cc
index 0f0f3ccd4b..bba4727bb6 100644
--- a/src/cripts/Bundles/HRWBridge.cc
+++ b/src/cripts/Bundles/HRWBridge.cc
@@ -80,7 +80,7 @@ ID::value(Cript::Context *context)
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// Bridge for the ID class
+// Bridge for the IP class
 class IP : public detail::HRWBridge
 {
   using self_type  = IP;
@@ -92,7 +92,7 @@ public:
   IP(const self_type &)             = delete;
   void operator=(const self_type &) = delete;
 
-  IP(const Cript::string_view &iP);
+  IP(const Cript::string_view &ip);
   ~IP() override = default;
 
   Cript::string_view value(Cript::Context *context) override;
@@ -101,18 +101,18 @@ private:
   Type _type = Type::none;
 };
 
-IP::IP(const Cript::string_view &ip) : super_type(ip)
+IP::IP(const Cript::string_view &type) : super_type(type)
 {
-  if (ip == "CLIENT") {
+  if (type == "CLIENT") {
     _type = Type::CLIENT;
-  } else if (ip == "INBOUND") {
+  } else if (type == "INBOUND") {
     _type = Type::INBOUND;
-  } else if (ip == "SERVER") {
+  } else if (type == "SERVER") {
     _type = Type::SERVER;
-  } else if (ip == "OUTBOUND") {
+  } else if (type == "OUTBOUND") {
     _type = Type::INBOUND;
   } else {
-    TSReleaseAssert(!"Invalid IP type in HRWBridge");
+    TSReleaseAssert(!"Invalid TYPE IP in HRWBridge");
   }
 }
 
@@ -144,6 +144,55 @@ IP::value(Cript::Context *context)
   return _value;
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// Bridge for the CIDR class, this only deals with the client IP
+class CIDR : public detail::HRWBridge
+{
+  using self_type  = CIDR;
+  using super_type = detail::HRWBridge;
+
+public:
+  CIDR(const self_type &)           = delete;
+  void operator=(const self_type &) = delete;
+
+  CIDR(Cript::string_view &cidr);
+  ~CIDR() override = default;
+
+  Cript::string_view value(Cript::Context *context) override;
+
+private:
+  unsigned int _ipv4_cidr = 32;
+  unsigned int _ipv6_cidr = 128;
+};
+
+CIDR::CIDR(Cript::string_view &cidr) : super_type(cidr)
+{
+  auto ipv4 = cidr.split_prefix_at(',');
+
+  TSReleaseAssert(ipv4 != cidr); // No ' found
+
+  auto result = std::from_chars(ipv4.data(), ipv4.data() + ipv4.size(), 
_ipv4_cidr);
+
+  if (result.ec != std::errc()) {
+    TSReleaseAssert(!"Invalid CIDR parameters in HRWBridge");
+  }
+
+  result = std::from_chars(cidr.data(), cidr.data() + cidr.size(), _ipv6_cidr);
+  if (result.ec != std::errc()) {
+    TSReleaseAssert(!"Invalid CIDR parameters in HRWBridge");
+  }
+}
+
+Cript::string_view
+CIDR::value(Cript::Context *context)
+{
+  auto ip = Client::Connection::get().ip();
+
+  _value = ip.string(_ipv4_cidr, _ipv6_cidr);
+
+  return _value;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // Bridge for all URLs
 class URL : public detail::HRWBridge
@@ -285,7 +334,7 @@ Bundle::Headers::bridgeFactory(const Cript::string &source)
 {
   Cript::string_view str = source;
 
-  str.trim_if(&isspace);
+  str.trim_if([](char c) { return std::isspace(c) || c == '"' || c == '\''; });
 
   if (str.starts_with("%{") && str.ends_with("}")) {
     str.remove_prefix_at('{');
@@ -297,7 +346,8 @@ Bundle::Headers::bridgeFactory(const Cript::string &source)
       return new detail::ID(str);
     } else if (key == "IP") {
       return new detail::IP(str);
-      // ToDo: We need CIDR:x,y support here, on the IP:CLIENT
+    } else if (key == "CIDR") {
+      return new detail::CIDR(str);
     } else if (key == "FROM-URL") {
       return new detail::URL(detail::URL::Type::REMAP_FROM, str);
     } else if (key == "TO-URL") {
diff --git a/src/cripts/Bundles/Headers.cc b/src/cripts/Bundles/Headers.cc
index 595f0e5128..ddd3ec4d50 100644
--- a/src/cripts/Bundles/Headers.cc
+++ b/src/cripts/Bundles/Headers.cc
@@ -53,23 +53,23 @@ namespace Bundle
 const Cript::string Headers::_name = "Bundle::Headers";
 
 Headers::self_type &
-Headers::rm_headers(const Cript::string_view target, const 
std::vector<Cript::string> &headers)
+Headers::rm_headers(const Cript::string_view target, const HeaderList &headers)
 {
   switch (header_target(target)) {
   case CLIENT_REQUEST:
-    _client_request.rm_headers = headers;
+    _client_request.rm_headers.insert(_client_request.rm_headers.end(), 
headers.begin(), headers.end());
     needCallback(Cript::Callbacks::DO_REMAP);
     break;
   case CLIENT_RESPONSE:
-    _client_response.rm_headers = headers;
+    _client_response.rm_headers.insert(_client_response.rm_headers.end(), 
headers.begin(), headers.end());
     needCallback(Cript::Callbacks::DO_SEND_RESPONSE);
     break;
   case SERVER_REQUEST:
-    _server_request.rm_headers = headers;
+    _client_response.rm_headers.insert(_client_response.rm_headers.end(), 
headers.begin(), headers.end());
     needCallback(Cript::Callbacks::DO_SEND_REQUEST);
     break;
   case SERVER_RESPONSE:
-    _server_response.rm_headers = headers;
+    _client_response.rm_headers.insert(_client_response.rm_headers.end(), 
headers.begin(), headers.end());
     needCallback(Cript::Callbacks::DO_READ_RESPONSE);
     break;
   default:
@@ -80,36 +80,36 @@ Headers::rm_headers(const Cript::string_view target, const 
std::vector<Cript::st
 }
 
 Headers::self_type &
-Headers::set_headers(const Cript::string_view target, const 
std::vector<std::pair<Cript::string, Cript::string>> &headers)
+Headers::set_headers(const Cript::string_view target, const HeaderValueList 
&headers)
 {
-  std::vector<std::pair<Cript::string, detail::HRWBridge *>> hdrs;
-
-  hdrs.reserve(headers.size());
-  for (const auto &hdr : headers) {
-    hdrs.emplace_back(hdr.first, Headers::bridgeFactory(hdr.second));
-  }
+  detail::HeadersType::HeaderValueList *hdrs = nullptr;
 
   switch (header_target(target)) {
   case CLIENT_REQUEST:
-    _client_request.set_headers = hdrs;
+    hdrs = &_client_request.set_headers;
     needCallback(Cript::Callbacks::DO_REMAP);
     break;
   case CLIENT_RESPONSE:
-    _client_response.set_headers = hdrs;
+    hdrs = &_client_response.set_headers;
     needCallback(Cript::Callbacks::DO_SEND_RESPONSE);
     break;
   case SERVER_REQUEST:
-    _server_request.set_headers = hdrs;
+    hdrs = &_server_request.set_headers;
     needCallback(Cript::Callbacks::DO_SEND_REQUEST);
     break;
   case SERVER_RESPONSE:
-    _server_response.set_headers = hdrs;
+    hdrs = &_server_response.set_headers;
     needCallback(Cript::Callbacks::DO_READ_RESPONSE);
     break;
   default:
     TSReleaseAssert(!"Invalid target for set_headers()");
   }
 
+  hdrs->reserve(headers.size());
+  for (const auto &hdr : headers) {
+    hdrs->emplace_back(hdr.first, Headers::bridgeFactory(hdr.second));
+  }
+
   return *this;
 }
 
diff --git a/src/cripts/Bundles/LogsMetrics.cc 
b/src/cripts/Bundles/LogsMetrics.cc
index 4e8c8af130..9084841eb6 100644
--- a/src/cripts/Bundles/LogsMetrics.cc
+++ b/src/cripts/Bundles/LogsMetrics.cc
@@ -177,16 +177,19 @@ LogsMetrics::doCacheLookup(Cript::Context *context)
 void
 LogsMetrics::doRemap(Cript::Context *context)
 {
-  bool sampled = false;
+  bool sampled = true;
 
   // .logsample(int)
-  if ((_log_sample > 0) && (Cript::random(_log_sample) != 1)) {
-    control.logging.set(false);
-    sampled = true;
+  if (_log_sample > 0) {
+    if (Cript::random(_log_sample) != 1) {
+      control.logging.set(false);
+      sampled = false;
+    }
+    CDebug("Log sampling: 1 in {} -> {}", _log_sample, sampled);
   }
 
   // .tcpinfo(bool)
-  if (_tcpinfo && !sampled) {
+  if (_tcpinfo && sampled) {
     borrow req      = Client::Request::get();
     borrow conn     = Client::Connection::get();
     req["@TCPInfo"] = fmt::format("TS; {}", conn.tcpinfo.log());
diff --git a/src/cripts/CMakeLists.txt b/src/cripts/CMakeLists.txt
index 034b1c1559..02efdf87ea 100644
--- a/src/cripts/CMakeLists.txt
+++ b/src/cripts/CMakeLists.txt
@@ -23,10 +23,13 @@ pkg_check_modules(PCRE2 REQUIRED IMPORTED_TARGET libpcre2-8)
 
 # The source files, globbed so we can drop in local / custom Bundles and 
extensions.
 file(GLOB CPP_FILES ${PROJECT_SOURCE_DIR}/src/cripts/*.cc 
${PROJECT_SOURCE_DIR}/src/cripts/*/*.cc)
+file(GLOB TEST_CPP_FILES ${PROJECT_SOURCE_DIR}/src/cripts/tests/*.cc)
+list(REMOVE_ITEM CPP_FILES ${TEST_CPP_FILES})
 
 set(CRIPTS_PUBLIC_HEADERS
     ${PROJECT_SOURCE_DIR}/include/cripts/Bundle.hpp
     ${PROJECT_SOURCE_DIR}/include/cripts/Configs.hpp
+    ${PROJECT_SOURCE_DIR}/include/cripts/ConfigsBase.hpp
     ${PROJECT_SOURCE_DIR}/include/cripts/Connections.hpp
     ${PROJECT_SOURCE_DIR}/include/cripts/Context.hpp
     ${PROJECT_SOURCE_DIR}/include/cripts/Crypto.hpp
@@ -50,6 +53,7 @@ set(CRIPTS_PUBLIC_HEADERS
 set(CRIPTS_BUNDLE_HEADERS
     ${PROJECT_SOURCE_DIR}/include/cripts/Bundles/Common.hpp 
${PROJECT_SOURCE_DIR}/include/cripts/Bundles/Headers.hpp
     ${PROJECT_SOURCE_DIR}/include/cripts/Bundles/LogsMetrics.hpp
+    ${PROJECT_SOURCE_DIR}/include/cripts/Bundles/Caching.hpp
 )
 
 add_library(cripts SHARED ${CPP_FILES})
diff --git a/src/cripts/Configs.cc b/src/cripts/Configs.cc
index 84f71ec920..0c6dfca2f8 100644
--- a/src/cripts/Configs.cc
+++ b/src/cripts/Configs.cc
@@ -19,6 +19,8 @@
 #include "cripts/Lulu.hpp"
 #include "cripts/Preamble.hpp"
 
+namespace Cript
+{
 integer
 IntConfig::_get(Cript::Context *context) const
 {
@@ -62,3 +64,93 @@ FloatConfig::_set(Cript::Context *context, float value)
     context->state.error.fail();
   }
 }
+
+Records::Records(const Cript::string_view name)
+{
+  TSOverridableConfigKey key;
+  TSRecordDataType       type;
+
+  if (TSHttpTxnConfigFind(name.data(), name.size(), &key, &type) != 
TS_SUCCESS) {
+    TSError("Invalid configuration variable '%.*s'", 
static_cast<int>(name.size()), name.data());
+    TSReleaseAssert(!"Invalid configuration variable");
+  } else {
+    _name = name;
+    _key  = key;
+    _type = type;
+  }
+}
+
+Records::ValueType
+Records::_get(const Cript::Context *context) const
+{
+  switch (_type) {
+  case TS_RECORDDATATYPE_INT: {
+    TSMgmtInt i;
+
+    if (TSHttpTxnConfigIntGet(context->state.txnp, _key, &i) == TS_SUCCESS) {
+      return i;
+    }
+  } break;
+  case TS_RECORDDATATYPE_FLOAT: {
+    TSMgmtFloat f;
+
+    if (TSHttpTxnConfigFloatGet(context->state.txnp, _key, &f) == TS_SUCCESS) {
+      return f;
+    }
+  } break;
+  case TS_RECORDDATATYPE_STRING: {
+    const char *s   = nullptr;
+    int         len = 0;
+
+    if (TSHttpTxnConfigStringGet(context->state.txnp, _key, &s, &len) == 
TS_SUCCESS) {
+      return std::string(s, len);
+    }
+  } break;
+  default:
+    TSReleaseAssert(!"Invalid configuration type");
+    return 0;
+  }
+
+  return 0;
+}
+
+bool
+Records::_set(const Cript::Context *context, const ValueType value)
+{
+  switch (_type) {
+  case TS_RECORDDATATYPE_INT: {
+    TSMgmtInt i = std::get<TSMgmtInt>(value);
+
+    if (TSHttpTxnConfigIntSet(context->state.txnp, _key, i) != TS_SUCCESS) {
+      TSError("Failed to set integer configuration '%s'", _name.c_str());
+      return false;
+    }
+    CDebug("Set integer configuration '{}' to {}", _name.c_str(), i);
+  } break;
+  case TS_RECORDDATATYPE_FLOAT: {
+    TSMgmtFloat f = std::get<TSMgmtFloat>(value);
+
+    if (TSHttpTxnConfigFloatSet(context->state.txnp, _key, f) != TS_SUCCESS) {
+      TSError("Failed to set float configuration '%s'", _name.c_str());
+      return false;
+    }
+    CDebug("Set float configuration '{}' to {}", _name.c_str(), f);
+  } break;
+  case TS_RECORDDATATYPE_STRING: {
+    auto &str = std::get<std::string>(value);
+
+    if (TSHttpTxnConfigStringSet(context->state.txnp, _key, str.c_str(), 
str.size()) != TS_SUCCESS) {
+      TSError("Failed to set string configuration '%s'", _name.c_str());
+      return false;
+    }
+    CDebug("Set string configuration '{}' to '{}'", _name.c_str(), 
str.c_str());
+  } break;
+  default:
+    TSReleaseAssert(!"Invalid configuration type");
+    return false;
+  }
+
+  return true; // Success
+}
+
+} // namespace Cript
diff --git a/src/cripts/Context.cc b/src/cripts/Context.cc
index c23a37c3ec..0c355efefa 100644
--- a/src/cripts/Context.cc
+++ b/src/cripts/Context.cc
@@ -43,6 +43,9 @@ Cript::Context::reset()
   }
 
   // Clear the initialized URLs before calling next hook
+  if (_pristine_url.initialized()) {
+    _pristine_url.reset();
+  }
   if (_cache_url.initialized()) {
     _cache_url.reset();
   }
diff --git a/src/cripts/Error.cc b/src/cripts/Error.cc
index 4dd2d700d8..906690de43 100644
--- a/src/cripts/Error.cc
+++ b/src/cripts/Error.cc
@@ -43,3 +43,9 @@ Error::Status::_set(Cript::Context *context, TSHttpStatus 
status)
   context->state.error.fail();
   context->state.error._status.setter(status);
 }
+
+TSHttpStatus
+Error::Status::_get(Cript::Context *context)
+{
+  return context->state.error._status.getter();
+}
diff --git a/src/cripts/Files.cc b/src/cripts/Files.cc
index fa45401ac2..0c870125f4 100644
--- a/src/cripts/Files.cc
+++ b/src/cripts/Files.cc
@@ -19,8 +19,21 @@
 #include "cripts/Lulu.hpp"
 #include "cripts/Preamble.hpp"
 
+// Our include depedenencies are unfortunate ...
+extern std::string RecConfigReadConfigDir();
+
 std::filesystem::file_status
 File::Status(const File::Path &path)
 {
   return std::filesystem::status(path);
 }
+
+File::Path &
+File::Path::rebase()
+{
+  if (std::filesystem::status(*this).type() != 
std::filesystem::file_type::regular) {
+    *this = RecConfigReadConfigDir() + "/" + this->string();
+  }
+
+  return *this;
+}
diff --git a/src/cripts/Instance.cc b/src/cripts/Instance.cc
index 04c39ace14..dd17a25fba 100644
--- a/src/cripts/Instance.cc
+++ b/src/cripts/Instance.cc
@@ -52,8 +52,6 @@ Cript::Instance::initialize(int argc, char *argv[], const 
char *filename)
   dbg_ctl_cript.set(plugin_debug_tag.c_str());
 }
 
-#include <iostream>
-
 bool
 Cript::Instance::addPlugin(const Cript::string &tag, const Cript::string 
&plugin, const Plugin::Options &options)
 {
diff --git a/src/cripts/Urls.cc b/src/cripts/Urls.cc
index 70a66072b2..e2406756e5 100644
--- a/src/cripts/Urls.cc
+++ b/src/cripts/Urls.cc
@@ -15,6 +15,7 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
+#include <sstream>
 
 #include "cripts/Lulu.hpp"
 #include "cripts/Preamble.hpp"
@@ -401,6 +402,33 @@ Cript::Url::Query::_parser()
   }
 }
 
+Cript::string_view
+Cript::Url::Matrix::getSV()
+{
+  if (_owner && _data.empty()) {
+    const char *value = nullptr;
+    int         len   = 0;
+
+    value   = TSUrlHttpParamsGet(_owner->_bufp, _owner->_urlp, &len);
+    _data   = Cript::string_view(value, len);
+    _loaded = true;
+  }
+
+  return _data;
+}
+
+Cript::Url::Matrix
+Cript::Url::Matrix::operator=(Cript::string_view matrix)
+{
+  TSReleaseAssert(!_owner->readOnly()); // This can not be a read-only URL
+  TSUrlHttpParamsSet(_owner->_bufp, _owner->_urlp, matrix.data(), 
matrix.size());
+  _owner->_modified = true;
+  reset();
+  _loaded = false;
+
+  return *this;
+}
+
 Cript::string
 Cript::Url::url() const
 {
diff --git a/tools/cripts/genconfig.py b/tools/cripts/genconfig.py
index e24ae47025..34bb4b2031 100755
--- a/tools/cripts/genconfig.py
+++ b/tools/cripts/genconfig.py
@@ -52,37 +52,12 @@ def print_header():
 /*
   THIS FILE IS AUTOGENERATED, DO NOT EDIT
 
-  Regenerate this file with the 'generate-cripts-config' target
+  Regenerate this file with the 'generate-cripts-config' target. Remember
+  to run the format target on the generated file as well.
 */
 #pragma once
 
-class IntConfig
-{
-public:
-  IntConfig() = delete;
-  explicit IntConfig(TSOverridableConfigKey key) : _key(key) {}
-
-  // Implemented later in Configs.cc
-  integer _get(Cript::Context *context) const;
-  void _set(Cript::Context *context, integer value);
-
-private:
-  const TSOverridableConfigKey _key;
-};
-
-class FloatConfig
-{
-public:
-  FloatConfig() = delete;
-  explicit FloatConfig(TSOverridableConfigKey key) : _key(key) {}
-
-  // Implemented later in Configs.cc
-  float _get(Cript::Context *context) const;
-  void _set(Cript::Context *context, float value);
-
-private:
-  const TSOverridableConfigKey _key;
-};
+#include "cripts/ConfigsBase.hpp"
 
 """)
 
@@ -101,12 +76,12 @@ def print_class(tree, cur="", indent=0):
             print_class(tree[k], k, indent + 1)
         else:
             if firstInstance:
-                indentp("public:", indent)
+                indentp("public:", indent - 1)
                 firstInstance = False
             if tree[k][1] == "TS_RECORDDATATYPE_INT":
-                indentp("IntConfig {}{{{}}};".format(k, tree[k][0]), indent + 
1)
+                indentp("Cript::IntConfig {}{{{}}};".format(k, tree[k][0]), 
indent)
             elif tree[k][1] == "TS_RECORDDATATYPE_FLOAT":
-                indentp("FloatConfig {}{{{}}};".format(k, tree[k][0]), indent 
+ 1)
+                indentp("Cript::FloatConfig {}{{{}}};".format(k, tree[k][0]), 
indent)
             elif tree[k][1] == "TS_RECORDDATATYPE_STRING":
                 pass
                 # ToDo: Support strings somehow??
@@ -117,8 +92,8 @@ def print_class(tree, cur="", indent=0):
         indentp("}}; // End class {}".format(cur.title()), indent - 1)
         print()
         if cur != "proxy":
-            indentp("public:", indent - 1)
-            indentp("{} {};".format(cur.title(), cur), indent)
+            indentp("public:", indent - 2)
+            indentp("{} {};".format(cur.title(), cur), indent - 1)
             print()
 
 

Reply via email to