url_sig add 'ignore_expiry = true' option for log replay testing (#7231)

diff --git a/doc/admin-guide/plugins/url_sig.en.rst b/doc/admin-guide/plugins/url_sig.en.rst
index ad108fd..1e5d65e 100644
--- a/doc/admin-guide/plugins/url_sig.en.rst
+++ b/doc/admin-guide/plugins/url_sig.en.rst
@@ -384,3 +384,20 @@
     { [data not shown]
     * Connection #0 to host localhost left intact
 
+
+Replay test support
+===================
+
+To assist in log replay an option is available in the config file which
+will ignore the expiration date.  This allows all url_sig tests to
+pass the expiration date.
+
+The config file option to enable this is::
+
+    ignore_expiry = true
+
+Once updated, touch `remap.config` then issue a
+:option:`traffic_ctl config reload` to make the settings active.
+
+Do NOT deploy this to production as it will disable valid checks
+on signed urls!
diff --git a/plugins/experimental/url_sig/url_sig.c b/plugins/experimental/url_sig/url_sig.c
index 249a011..d08f9da 100644
--- a/plugins/experimental/url_sig/url_sig.c
+++ b/plugins/experimental/url_sig/url_sig.c
@@ -60,6 +60,7 @@
   pcre_extra *regex_extra;
   int pristine_url_flag;
   char *sig_anchor;
+  bool ignore_expiry;
 };
 
 static void
@@ -217,6 +218,11 @@
         cfg->regex_extra = pcre_study(
           cfg->regex, options, &errptr); // We do not need to check the error here because we can still run without the studying?
       }
+    } else if (strncmp(line, "ignore_expiry", 13) == 0) {
+      if (strncmp(value, "true", 4) == 0) {
+        cfg->ignore_expiry = true;
+        TSError("[url_sig] Plugin IGNORES sig expiration");
+      }
     } else {
       TSError("[url_sig] Error parsing line %d of file %s (%s)", line_no, config_file, line);
     }
@@ -667,17 +673,19 @@
   }
 
   // Expiration
-  cp = strstr(query, EXP_QSTRING "=");
-  if (cp != NULL) {
-    cp += strlen(EXP_QSTRING) + 1;
-    if (sscanf(cp, "%" SCNu64, &expiration) != 1 || (time_t)expiration < time(NULL)) {
-      err_log(url, "Invalid expiration, or expired");
+  if (!cfg->ignore_expiry) {
+    cp = strstr(query, EXP_QSTRING "=");
+    if (cp != NULL) {
+      cp += strlen(EXP_QSTRING) + 1;
+      if (sscanf(cp, "%" SCNu64, &expiration) != 1 || (time_t)expiration < time(NULL)) {
+        err_log(url, "Invalid expiration, or expired");
+        goto deny;
+      }
+      TSDebug(PLUGIN_NAME, "Exp: %" PRIu64, expiration);
+    } else {
+      err_log(url, "Expiration query string not found");
       goto deny;
     }
-    TSDebug(PLUGIN_NAME, "Exp: %" PRIu64, expiration);
-  } else {
-    err_log(url, "Expiration query string not found");
-    goto deny;
   }
   // Algorithm
   cp = strstr(query, ALG_QSTRING "=");