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

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


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 5d5d4cc  cachekey: added --canonical-prefix parameter
5d5d4cc is described below

commit 5d5d4cc288e2101ae3987b4070f93bd41713c4b0
Author: Gancho Tenev <gan...@apache.org>
AuthorDate: Wed Aug 21 16:11:48 2019 -0700

    cachekey: added --canonical-prefix parameter
    
    In certain use-cases when calculating the prefix (the initial value
    of the new cache key) we need to have the scheme, host and port in
    their original form from the request URI, i.e. when hosting.config
    is used the cache key is expected to contain a valid URI authority
    element used for volume selection.
    
    More details about the new parameter and its functionality can be
    found in doc/admin-guide/plugins/cachekey.en.rst
    
    (cherry picked from commit 0f86efc7678248c09f87ec8b99bc026456edc3f7)
---
 doc/admin-guide/plugins/cachekey.en.rst | 21 +++++---
 plugins/cachekey/cachekey.cc            | 90 ++++++++++++++++++++++++---------
 plugins/cachekey/cachekey.h             |  3 +-
 plugins/cachekey/configs.cc             | 11 ++++
 plugins/cachekey/configs.h              |  6 +++
 plugins/cachekey/plugin.cc              |  2 +-
 6 files changed, 102 insertions(+), 31 deletions(-)

diff --git a/doc/admin-guide/plugins/cachekey.en.rst 
b/doc/admin-guide/plugins/cachekey.en.rst
index 5342d8b..51f4ef1 100644
--- a/doc/admin-guide/plugins/cachekey.en.rst
+++ b/doc/admin-guide/plugins/cachekey.en.rst
@@ -70,20 +70,29 @@ Cache key structure and related plugin parameters
 
 ::
 
-  Optional components      | 
┌─────────────────┬──────────────────┬──────────────────────┐
+  Optional components      | ┌─────────────────┬────────────── 
───┬──────────────────────┐
   (included in this order) | │ --static-prefix | --capture-prefix │ 
--capture-prefix-uri │
                            | 
├─────────────────┴──────────────────┴──────────────────────┤
-  Default values if no     | │ /host/port                                      
          |
+  Default values if no     | │ /host/port or scheme://host:port (see the table 
below)    |
   optional components      | 
└───────────────────────────────────────────────────────────┘
   configured               |
 
+  ┌────────────────────┬─────────────────────────┬──────────────────────┐
+  │ --canonical-prefix |  default value if no    │ input used for       │
+  │                    |  prefix parameters used │ --capture-prefix     │
+  ├────────────────────┴─────────────────────────┴──────────────────────┤
+  │ fasle              | /host/port              | host:port            |
+  ├────────────────────┴─────────────────────────┴──────────────────────┤
+  │ true               | scheme://host:port      | scheme://host:port   |
+  └──────────────────────────────────────────────┴──────────────────────┘
+
+
 * ``--static-prefix=<value>`` (default: empty string) - if specified and not 
an empty string the ``<value>`` will be added to the cache key.
-* ``--capture-prefix=<capture_definition>`` (default: empty string) - if 
specified and not empty then strings are captured from ``host:port`` based on 
the ``<capture_definition>`` and are added to the cache key.
+* ``--capture-prefix=<capture_definition>`` (default: empty string) - if 
specified and not empty then strings are captured based on the value of 
``--canonical-prefix`` parameter (see the table above) and 
``<capture_definition>`` and are added to the cache key.
 * ``--capture-prefix-uri=<capture_definition>`` (default: empty string) - if 
specified and not empty then strings are captured from the entire URI based on 
the ``<capture_definition>`` and are added to the cache key.
 * If any of the "Prefix" related plugin parameters are used together in the 
plugin configuration they are added to the cache key in the order shown in the 
diagram.
-* ``--remove-prefix=<true|false|yes|no|0|1`` (default: false) - if specified 
the prefix elements (host, port) are not processed nor appended to the 
cachekey. All prefix related plugin parameters are ignored if this parameter is 
``true``, ``yes`` or ``1``.
-
-
+* ``--remove-prefix=true|false|yes|no|0|1`` (default: false) - if specified 
the prefix elements (host, port) are not processed nor appended to the 
cachekey. All prefix related plugin parameters are ignored if this parameter is 
``true``, ``yes`` or ``1``.
+* ``--canonical-prefix=true|false|yes|no|0|1`` (default: false) - impacts the 
input of regex operation when ``--capture-prefix`` is used and the default 
value if no prefix parameters are used (see the table above).
 
 "User-Agent" section
 ^^^^^^^^^^^^^^^^^^^^
diff --git a/plugins/cachekey/cachekey.cc b/plugins/cachekey/cachekey.cc
index 9cf4454..95640e1 100644
--- a/plugins/cachekey/cachekey.cc
+++ b/plugins/cachekey/cachekey.cc
@@ -188,6 +188,51 @@ getUri(TSMBuffer buf, TSMLoc url)
   return uri;
 }
 
+static String
+getCanonicalUrl(TSMBuffer buf, TSMLoc url, bool canonicalPrefix, bool 
provideDefaultKey)
+{
+  String canonicalUrl;
+
+  String scheme;
+  int schemeLen;
+  const char *schemePtr = TSUrlSchemeGet(buf, url, &schemeLen);
+  if (nullptr != schemePtr && 0 != schemeLen) {
+    scheme.assign(schemePtr, schemeLen);
+  } else {
+    CacheKeyError("failed to get scheme");
+    return canonicalUrl;
+  }
+
+  String host;
+  int hostLen;
+  const char *hostPtr = TSUrlHostGet(buf, url, &hostLen);
+  if (nullptr != hostPtr && 0 != hostLen) {
+    host.assign(hostPtr, hostLen);
+  } else {
+    CacheKeyError("failed to get host");
+    return canonicalUrl;
+  }
+
+  String port;
+  int portInt = TSUrlPortGet(buf, url);
+  ::append(port, portInt);
+
+  if (canonicalPrefix) {
+    /* return the same for both regex input or default key, results in 
'scheme://host:port' */
+    
canonicalUrl.assign(scheme).append("://").append(host).append(":").append(port);
+  } else {
+    if (provideDefaultKey) {
+      /* return the key default - results in '/host/port' */
+      canonicalUrl.assign("/").append(host).append("/").append(port);
+    } else {
+      /* return regex input string - results in 'host:port' (use-case kept for 
compatibility reasons) */
+      canonicalUrl.assign(host).append(":").append(port);
+    }
+  }
+
+  return canonicalUrl;
+}
+
 /**
  * @brief Constructor setting up the cache key prefix, initializing request 
info.
  * @param txn transaction handle.
@@ -289,6 +334,16 @@ CacheKey::append(const String &s)
   ::appendEncoded(_key, s.data(), s.size());
 }
 
+void
+CacheKey::append(const String &s, bool useSeparator)
+{
+  if (useSeparator) {
+    append(s);
+  } else {
+    _key.append(s);
+  }
+}
+
 /**
  * @brief Append null-terminated C-style string to the key.
  * @param s null-terminated C-style string.
@@ -319,42 +374,31 @@ CacheKey::append(const char *s, unsigned n)
  * @param prefix if not empty string will append the static prefix to the 
cache key.
  * @param prefixCapture if not empty will append regex capture/replacement 
from the host:port.
  * @param prefixCaptureUri if not empty will append regex capture/replacement 
from the whole URI.
+ * @param canonicalPrefix false - use 'host:port' as starting point of all 
transformations, true - use 'scheme://host:port'
  * @note if both prefix and pattern are not empty prefix will be added first, 
followed by the results from pattern.
  */
 void
-CacheKey::appendPrefix(const String &prefix, Pattern &prefixCapture, Pattern 
&prefixCaptureUri)
+CacheKey::appendPrefix(const String &prefix, Pattern &prefixCapture, Pattern 
&prefixCaptureUri, bool canonicalPrefix)
 {
-  // "true" would mean that the plugin config meant to override the default 
prefix (host:port).
+  // "true" would mean that the plugin config meant to override the default 
prefix, "false" means use default.
   bool customPrefix = false;
-  String host;
-  int port = 0;
+
+  /* For all the following operations if a canonical prefix is required then 
appned to the key with no separator
+   * to leave the door open for potential valid host name formed in the final 
resulting cache key. */
 
   if (!prefix.empty()) {
     customPrefix = true;
-    append(prefix);
+    append(prefix, /* useSeparator */ !canonicalPrefix);
     CacheKeyDebug("added static prefix, key: '%s'", _key.c_str());
   }
 
-  int hostLen;
-  const char *hostPtr = TSUrlHostGet(_buf, _url, &hostLen);
-  if (nullptr != hostPtr && 0 != hostLen) {
-    host.assign(hostPtr, hostLen);
-  } else {
-    CacheKeyError("failed to get host");
-  }
-  port = TSUrlPortGet(_buf, _url);
-
   if (!prefixCapture.empty()) {
     customPrefix = true;
 
-    String hostAndPort;
-    hostAndPort.append(host).append(":");
-    ::append(hostAndPort, port);
-
     StringVector captures;
-    if (prefixCapture.process(hostAndPort, captures)) {
+    if (prefixCapture.process(getCanonicalUrl(_buf, _url, canonicalPrefix, /* 
provideDefaultKey */ false), captures)) {
       for (auto &capture : captures) {
-        append(capture);
+        append(capture, /* useSeparator */ !canonicalPrefix);
       }
       CacheKeyDebug("added host:port capture prefix, key: '%s'", _key.c_str());
     }
@@ -368,7 +412,7 @@ CacheKey::appendPrefix(const String &prefix, Pattern 
&prefixCapture, Pattern &pr
       StringVector captures;
       if (prefixCaptureUri.process(uri, captures)) {
         for (auto &capture : captures) {
-          append(capture);
+          append(capture, /* useSeparator */ !canonicalPrefix);
         }
         CacheKeyDebug("added URI capture prefix, key: '%s'", _key.c_str());
       }
@@ -376,8 +420,8 @@ CacheKey::appendPrefix(const String &prefix, Pattern 
&prefixCapture, Pattern &pr
   }
 
   if (!customPrefix) {
-    append(host);
-    append(port);
+    /* nothing was customized => default prefix */
+    append(getCanonicalUrl(_buf, _url, canonicalPrefix, /* provideDefaultKey 
*/ true), /* useSeparator */ false);
     CacheKeyDebug("added default prefix, key: '%s'", _key.c_str());
   }
 }
diff --git a/plugins/cachekey/cachekey.h b/plugins/cachekey/cachekey.h
index 7ea058c..0922ed1 100644
--- a/plugins/cachekey/cachekey.h
+++ b/plugins/cachekey/cachekey.h
@@ -55,9 +55,10 @@ public:
 
   void append(unsigned number);
   void append(const String &);
+  void append(const String &s, bool useSeparator);
   void append(const char *s);
   void append(const char *n, unsigned s);
-  void appendPrefix(const String &prefix, Pattern &prefixCapture, Pattern 
&prefixCaptureUri);
+  void appendPrefix(const String &prefix, Pattern &prefixCapture, Pattern 
&prefixCaptureUri, bool canonicalPrefix);
   void appendPath(Pattern &pathCapture, Pattern &pathCaptureUri);
   void appendHeaders(const ConfigHeaders &config);
   void appendQuery(const ConfigQuery &config);
diff --git a/plugins/cachekey/configs.cc b/plugins/cachekey/configs.cc
index 2320db1..a56565c 100644
--- a/plugins/cachekey/configs.cc
+++ b/plugins/cachekey/configs.cc
@@ -397,6 +397,8 @@ Configs::init(int argc, const char *argv[], bool 
perRemapConfig)
     {const_cast<char *>("separator"), optional_argument, nullptr, 's'},
     {const_cast<char *>("uri-type"), optional_argument, nullptr, 't'},
     {const_cast<char *>("capture-header"), optional_argument, nullptr, 'u'},
+    {const_cast<char *>("canonical-prefix"), optional_argument, nullptr, 'v'},
+    /* reserve 'z' for 'config' files */
     {nullptr, 0, nullptr, 0},
   };
 
@@ -504,6 +506,9 @@ Configs::init(int argc, const char *argv[], bool 
perRemapConfig)
     case 'u': /* capture-header */
       _headers.addCapture(optarg);
       break;
+    case 'v': /* canonical-prefix */
+      _canonicalPrefix = isTrue(optarg);
+      break;
     }
   }
 
@@ -535,6 +540,12 @@ Configs::pathToBeRemoved()
   return _pathToBeRemoved;
 }
 
+bool
+Configs::canonicalPrefix()
+{
+  return _canonicalPrefix;
+}
+
 void
 Configs::setSeparator(const char *arg)
 {
diff --git a/plugins/cachekey/configs.h b/plugins/cachekey/configs.h
index 947b219..5ff41f0 100644
--- a/plugins/cachekey/configs.h
+++ b/plugins/cachekey/configs.h
@@ -163,6 +163,11 @@ public:
   bool pathToBeRemoved();
 
   /**
+   * @brief keep URI scheme and authority elements.
+   */
+  bool canonicalPrefix();
+
+  /**
    * @brief set the cache key elements separator string.
    */
   void setSeparator(const char *arg);
@@ -205,6 +210,7 @@ private:
 
   bool _prefixToBeRemoved  = false; /**< @brief instructs the prefix (i.e. 
host:port) not to added to the cache key */
   bool _pathToBeRemoved    = false; /**< @brief instructs the path not to 
added to the cache key */
+  bool _canonicalPrefix    = false; /**< @brief keep the URI scheme and 
authority element used as input to transforming into key */
   String _separator        = "/";   /**< @brief a separator used to separate 
the cache key elements extracted from the URI */
   CacheKeyUriType _uriType = REMAP; /**< @brief shows which URI the cache key 
will be based on */
 };
diff --git a/plugins/cachekey/plugin.cc b/plugins/cachekey/plugin.cc
index 43bad79..afb9503 100644
--- a/plugins/cachekey/plugin.cc
+++ b/plugins/cachekey/plugin.cc
@@ -43,7 +43,7 @@ setCacheKey(TSHttpTxn txn, Configs *config, 
TSRemapRequestInfo *rri = nullptr)
 
   /* Append custom prefix or the host:port */
   if (!config->prefixToBeRemoved()) {
-    cachekey.appendPrefix(config->_prefix, config->_prefixCapture, 
config->_prefixCaptureUri);
+    cachekey.appendPrefix(config->_prefix, config->_prefixCapture, 
config->_prefixCaptureUri, config->canonicalPrefix());
   }
   /* Classify User-Agent and append the class name to the cache key if 
matched. */
   cachekey.appendUaClass(config->_classifier);

Reply via email to