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

mlibbey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 03652e4928 prefetch: admit --fetch-query requests only when the key is 
present (#13370)
03652e4928 is described below

commit 03652e4928a0c18cc7256e1dfaed7e7001abf5db
Author: Miles Libbey <[email protected]>
AuthorDate: Sat Jul 18 16:45:30 2026 -0700

    prefetch: admit --fetch-query requests only when the key is present (#13370)
    
    With --fetch-query configured, the front-end/first-pass gate set
    handleFetch=true whenever the query key was *configured*, not when the
    request carried it. So every request whose path matched no
    fetch-path-pattern was admitted anyway, ran the pattern replace, failed,
    and logged ERROR "failed to process the pattern" -- while scheduling no
    prefetch at all (BgFetch runs only on the success path).
    
    Admit only when the request's query actually contains the key, matched
    as a "<key>=" parameter rather than a substring (which could hit another
    parameter's name or value). The same parameter test is now used by the
    hasValidQuery branch selector and the query-branch loop as well.
---
 plugins/prefetch/plugin.cc | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/plugins/prefetch/plugin.cc b/plugins/prefetch/plugin.cc
index b935e7928d..a472bea0d5 100644
--- a/plugins/prefetch/plugin.cc
+++ b/plugins/prefetch/plugin.cc
@@ -348,6 +348,31 @@ getPristineUrlQuery(TSHttpTxn txnp)
   return pristineQuery;
 }
 
+/**
+ * @brief Whether a single query parameter is the configured "<key>=..." 
parameter.
+ */
+static bool
+isQueryKeyParam(const String &param, const String &key)
+{
+  return param.size() > key.size() && param.compare(0, key.size(), key) == 0 
&& param[key.size()] == '=';
+}
+
+/**
+ * @brief Whether the query string contains the configured "<key>=..." 
parameter.
+ */
+static bool
+hasQueryKeyParam(const String &query, const String &key)
+{
+  std::istringstream qs(query);
+  String             param;
+  while (getline(qs, param, '&')) {
+    if (isQueryKeyParam(param, key)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 static constexpr StringView CmcdHeader{"Cmcd-Request"};
 static constexpr StringView CmcdNorFieldPrefix{"nor="};
 static constexpr StringView CmcdNrrFieldPrefix{"nrr="};
@@ -590,9 +615,9 @@ contHandleFetch(const TSCont contp, TSEvent event, void 
*edata)
       const String currentQuery  = getPristineUrlQuery(txnp);
       bool         hasValidQuery = false;
 
-      // If there is a --fetch-query defined in the config, and that string is 
found in the querystring, assume it is
-      // valid, and prefer the --fetch-query over the --fetch-path-pattern(s).
-      if (!config.getQueryKeyName().empty() && 
currentQuery.find(config.getQueryKeyName()) != String::npos) {
+      // If there is a --fetch-query defined in the config, and that parameter 
is present in the querystring, assume it
+      // is valid, and prefer the --fetch-query over the 
--fetch-path-pattern(s).
+      if (!config.getQueryKeyName().empty() && hasQueryKeyParam(currentQuery, 
config.getQueryKeyName())) {
         PrefetchDebug("Setting hasValidQuery to true");
         hasValidQuery = true;
       }
@@ -663,7 +688,7 @@ contHandleFetch(const TSCont contp, TSEvent event, void 
*edata)
           String             param;
 
           while (getline(cStringStream, param, '&')) {
-            if (param.find(config.getQueryKeyName()) != 0) {
+            if (!isQueryKeyParam(param, config.getQueryKeyName())) {
               continue;
             }
             if (config.getFetchCount() < done++) {
@@ -851,8 +876,8 @@ TSRemapDoRemap(void *instance, TSHttpTxn txnp, 
TSRemapRequestInfo *rri)
             PrefetchDebug("failed to get path to (pre)match");
           }
 
-          String queryKey = config.getQueryKeyName();
-          if (!queryKey.empty()) {
+          const String &queryKey = config.getQueryKeyName();
+          if (!handleFetch && !queryKey.empty() && 
hasQueryKeyParam(getPristineUrlQuery(txnp), queryKey)) {
             PrefetchDebug("handling for query-key: %s", queryKey.c_str());
             handleFetch = true;
           }

Reply via email to