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

bneradt 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 762d87c9a7 Remap ACL changes for 10 (#11033)
762d87c9a7 is described below

commit 762d87c9a70c1dc2238def9f04fe84e9eab172af
Author: Brian Neradt <[email protected]>
AuthorDate: Sat Feb 10 20:48:07 2024 -0600

    Remap ACL changes for 10 (#11033)
    
    This continues in the vein of #9631 by implementing the following ACL 
changes for ATS 10 which makes remap.config ACLs behave more similarly to 
ip_allow.yaml:
    
    * Fix @action=allow to deny transactions that are not in the allow list. 
Transactions with non-allowed methods simply didn't match the rule before, so 
they were not denied. This seems like a bug to me.
    * Change in-line ACL rules to match before activated named ACL rules.
    * If an ACL matches and is run, implicitly stop processing ip_allow.yaml 
rules.
---
 doc/admin-guide/files/remap.config.en.rst          |  15 +-
 include/proxy/http/HttpTransact.h                  |   2 +-
 include/proxy/http/remap/AclFiltering.h            |  23 +-
 include/proxy/http/remap/UrlMapping.h              |   2 +-
 src/proxy/http/HttpSM.cc                           |   4 +-
 src/proxy/http/HttpTransact.cc                     |   6 +-
 src/proxy/http/remap/AclFiltering.cc               |  17 +-
 src/proxy/http/remap/RemapConfig.cc                |  68 +++--
 src/proxy/http/remap/UrlRewrite.cc                 |  86 +++---
 tests/gold_tests/ip_allow/ip_category.test.py      |   6 +-
 .../https_categories_external_remap.replay.yaml    |  13 +-
 tests/gold_tests/remap/remap_acl.test.py           | 298 +++++++++++++++++++++
 .../remap_acl_all_allowed.replay.yaml}             |  50 +++-
 .../remap_acl_all_denied.replay.yaml}              |  46 +++-
 .../remap_acl_get_allowed.replay.yaml}             |  48 +++-
 .../remap_acl_get_post_allowed.replay.yaml}        |  50 +++-
 .../remap_acl_get_post_denied.replay.yaml}         |  48 +++-
 17 files changed, 662 insertions(+), 120 deletions(-)

diff --git a/doc/admin-guide/files/remap.config.en.rst 
b/doc/admin-guide/files/remap.config.en.rst
index b1c7d0e1db..7988220b30 100644
--- a/doc/admin-guide/files/remap.config.en.rst
+++ b/doc/admin-guide/files/remap.config.en.rst
@@ -435,17 +435,18 @@ You may configure Nexthop or Parent hierarchical caching 
rules by remap using th
 **@strategy** tag.  See :doc:`../configuration/hierarchical-caching.en` and 
:doc:`strategies.yaml.en`
 for configuration details and examples.
 
-Acl Filters
+ACL Filters
 ===========
 
-Acl filters can be created to control access of specific remap lines. The 
markup
+ACL filters can be created to control access of specific remap lines. The 
markup
 is very similar to that of :file:`ip_allow.yaml`, with slight changes to
 accommodate remap markup.
 
 **Note:** As of ATS v10.x, these filters are applied just as 
:file:`ip_allow.yaml`,
-this means once a filter matches the request, the action for that rule takes 
effect.
+meaning once a filter matches the request, the action for that rule takes 
effect.
 In previous versions, all filters for a remap rule were evaluated, and the 
``deny``
-action took priority.
+action took priority. Also, if an ACL filter matches, then 
:file:`ip_allow.yaml` rules
+will not not apply to the request because the matched rule is the ACL filter.
 
 Examples
 --------
@@ -464,11 +465,14 @@ Examples
 
     map http://foo.example.com/  http://foo.example.com/ @action=allow 
@src_ip_category=ACME_INTERNAL @method=post @method=get @method=head
 
-Note that these Acl filters will return a 403 response if the resource is 
restricted.
+Note that these ACL filters will return a 403 response if the resource is 
restricted.
 
 The difference between ``@src_ip`` and ``@in_ip`` is that the ``@src_ip`` is 
the client
 ip and the ``in_ip`` is the ip address the client is connecting to (the 
incoming address).
 ``@src_ip_category`` functions like ``ip_category`` described in 
:file:`ip_allow.yaml`.
+If no IP address is specified for ``@src_ip``, ``@src_ip_category``, or
+``@in_ip``, the filter will implicitly apply to all incoming IP addresses. This
+can be explicitly stated with ``@src_ip=all``.
 
 Named Filters
 =============
@@ -486,6 +490,7 @@ is helpful for remapping internal requests without allowing 
access
 to external users. By default both internal and external requests
 are allowed.
 
+In-line ACL filters take priority over named active ACL filters.
 
 Examples
 --------
diff --git a/include/proxy/http/HttpTransact.h 
b/include/proxy/http/HttpTransact.h
index d4029eabb8..290fdf70d6 100644
--- a/include/proxy/http/HttpTransact.h
+++ b/include/proxy/http/HttpTransact.h
@@ -682,7 +682,7 @@ public:
     bool is_upgrade_request           = false;
     bool is_websocket                 = false;
     bool did_upgrade_succeed          = false;
-    bool client_connection_enabled    = true;
+    bool client_connection_allowed    = true;
     bool acl_filtering_performed      = false;
     bool api_cleanup_cache_read       = false;
     bool api_server_response_no_store = false;
diff --git a/include/proxy/http/remap/AclFiltering.h 
b/include/proxy/http/remap/AclFiltering.h
index a19287b107..a0c4a26c7f 100644
--- a/include/proxy/http/remap/AclFiltering.h
+++ b/include/proxy/http/remap/AclFiltering.h
@@ -40,22 +40,27 @@ static int const ACL_FILTER_MAX_IN_IP  = 8;
 static int const ACL_FILTER_MAX_ARGV   = 512;
 
 struct src_ip_info_t {
-  IpAddr start; ///< Minimum value in range.
-  IpAddr end;   ///< Maximum value in range.
-  bool invert;  ///< Should we "invert" the meaning of this IP range ("not in 
range")
+  IpAddr start;             ///< Minimum value in range.
+  IpAddr end;               ///< Maximum value in range.
+  bool invert;              ///< Should we "invert" the meaning of this IP 
range ("not in range")
+  bool match_all_addresses; ///< This rule should match all IP addresses.
 
   void
   reset()
   {
     start.invalidate();
     end.invalidate();
-    invert = false;
+    invert              = false;
+    match_all_addresses = false;
   }
 
   /// @return @c true if @a ip is inside @a this range.
   bool
   contains(IpEndpoint const &ip) const
   {
+    if (match_all_addresses) {
+      return true;
+    }
     IpAddr addr{ip};
     return addr.cmp(start) >= 0 && addr.cmp(end) <= 0;
   }
@@ -95,11 +100,11 @@ public:
   acl_filter_rule *next = nullptr;
   char *filter_name     = nullptr; // optional filter name
   unsigned int allow_flag : 1,     // action allow deny
-    src_ip_valid          : 1,     // src_ip range valid
-    src_ip_category_valid : 1,     // src_ip range valid
-    in_ip_valid           : 1,
-    active_queue_flag     : 1, // filter is in active state (used by .useflt 
directive)
-    internal              : 1; // filter internal HTTP requests
+    src_ip_valid          : 1,     // src_ip (client's src IP) range is 
specified and valid
+    src_ip_category_valid : 1,     // src_ip_category (client's src IP 
category) is specified and valid
+    in_ip_valid           : 1,     // in_ip (client's dest IP) range is 
specified and valid
+    active_queue_flag     : 1,     // filter is in active state (used by 
.useflt directive)
+    internal              : 1;     // filter internal HTTP requests
 
   // we need arguments as string array for directive processing
   int argc = 0;                    // argument counter (only for filter defs)
diff --git a/include/proxy/http/remap/UrlMapping.h 
b/include/proxy/http/remap/UrlMapping.h
index 511e949f42..2779ac9563 100644
--- a/include/proxy/http/remap/UrlMapping.h
+++ b/include/proxy/http/remap/UrlMapping.h
@@ -116,7 +116,7 @@ public:
   referer_info *referer_list         = nullptr;
   redirect_tag_str *redir_chunk_list = nullptr;
   bool ip_allow_check_enabled_p      = false;
-  acl_filter_rule *filter            = nullptr; // acl filtering (list of 
rules)
+  acl_filter_rule *filter            = nullptr; // acl filtering (linked list 
of rules)
   LINK(url_mapping, link);                      // For use with the main Queue 
linked list holding all the mapping
   std::shared_ptr<NextHopSelectionStrategy> strategy = nullptr;
   std::string remapKey;
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index 4b2268930c..ede21bfde4 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -4302,7 +4302,7 @@ HttpSM::check_sni_host()
         swoc::bwprint(error_bw_buffer, "No SNI for TLS request: connecting to 
{} for host='{}', returning a 403",
                       t_state.client_info.dst_addr, 
std::string_view{host_name, static_cast<size_t>(host_len)});
         Log::error("%s", error_bw_buffer.c_str());
-        this->t_state.client_connection_enabled = false;
+        this->t_state.client_connection_allowed = false;
       }
     } else if (strncasecmp(host_name, sni_value, host_len) != 0) { // Name 
mismatch
       Warning("SNI/hostname mismatch sni=%s host=%.*s action=%s", sni_value, 
host_len, host_name, action_value);
@@ -4311,7 +4311,7 @@ HttpSM::check_sni_host()
         swoc::bwprint(error_bw_buffer, "SNI/hostname mismatch: connecting to 
{} for host='{}' sni='{}', returning a 403",
                       t_state.client_info.dst_addr, 
std::string_view{host_name, static_cast<size_t>(host_len)}, sni_value);
         Log::error("%s", error_bw_buffer.c_str());
-        this->t_state.client_connection_enabled = false;
+        this->t_state.client_connection_allowed = false;
       }
     } else {
       SMDbg(dbg_ctl_ssl_sni, "SNI/hostname successfully match sni=%s 
host=%.*s", sni_value, host_len, host_name);
diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc
index e04a3df077..cf9447f825 100644
--- a/src/proxy/http/HttpTransact.cc
+++ b/src/proxy/http/HttpTransact.cc
@@ -1105,7 +1105,7 @@ HttpTransact::EndRemapRequest(State *s)
   /////////////////////////////////////////////////////////////////////////
   // We must close this connection if client_connection_enabled == false //
   /////////////////////////////////////////////////////////////////////////
-  if (!s->client_connection_enabled) {
+  if (!s->client_connection_allowed) {
     build_error_response(s, HTTP_STATUS_FORBIDDEN, "Access Denied", 
"access#denied");
     s->reverse_proxy = false;
     goto done;
@@ -6487,7 +6487,7 @@ void
 HttpTransact::process_quick_http_filter(State *s, int method)
 {
   // connection already disabled by previous ACL filtering, don't modify it.
-  if (!s->client_connection_enabled) {
+  if (!s->client_connection_allowed) {
     return;
   }
 
@@ -6523,7 +6523,7 @@ HttpTransact::process_quick_http_filter(State *s, int 
method)
         TxnDbg(dbg_ctl_ip_allow, "Line %d denial for '%.*s' from %s", 
acl.source_line(), method_str_len, method_str,
                ats_ip_ntop(&s->client_info.src_addr.sa, ipb, sizeof(ipb)));
       }
-      s->client_connection_enabled = false;
+      s->client_connection_allowed = false;
     }
   }
 }
diff --git a/src/proxy/http/remap/AclFiltering.cc 
b/src/proxy/http/remap/AclFiltering.cc
index 259972768c..106690cdf4 100644
--- a/src/proxy/http/remap/AclFiltering.cc
+++ b/src/proxy/http/remap/AclFiltering.cc
@@ -55,6 +55,7 @@ acl_filter_rule::reset()
   for (i = (src_ip_cnt = 0); i < ACL_FILTER_MAX_SRC_IP; i++) {
     src_ip_array[i].reset();
   }
+  src_ip_category_valid = 0;
   for (i = (src_ip_category_cnt = 0); i < ACL_FILTER_MAX_SRC_IP; i++) {
     src_ip_category_array[i].reset();
   }
@@ -66,7 +67,7 @@ acl_filter_rule::reset()
   internal    = 0;
 }
 
-acl_filter_rule::acl_filter_rule() : allow_flag(1), src_ip_valid(0), 
active_queue_flag(0), internal(0)
+acl_filter_rule::acl_filter_rule() : allow_flag(1), src_ip_valid(0), 
src_ip_category_valid(0), active_queue_flag(0), internal(0)
 {
   standard_method_lookup.resize(HTTP_WKSIDX_METHODS_CNT);
   ink_zero(argv);
@@ -108,9 +109,11 @@ acl_filter_rule::print()
 {
   int i;
   
printf("-----------------------------------------------------------------------------------------\n");
-  printf("Filter \"%s\" status: allow_flag=%s, src_ip_valid=%s, 
in_ip_valid=%s, internal=%s, active_queue_flag=%d\n",
+  printf("Filter \"%s\" status: allow_flag=%s, src_ip_valid=%s, 
src_ip_category_valid=%s, in_ip_valid=%s, internal=%s, "
+         "active_queue_flag=%d\n",
          filter_name ? filter_name : "<NONAME>", allow_flag ? "true" : 
"false", src_ip_valid ? "true" : "false",
-         in_ip_valid ? "true" : "false", internal ? "true" : "false", 
static_cast<int>(active_queue_flag));
+         src_ip_category_valid ? "true" : "false", in_ip_valid ? "true" : 
"false", internal ? "true" : "false",
+         static_cast<int>(active_queue_flag));
   printf("standard methods=");
   for (i = 0; i < HTTP_WKSIDX_METHODS_CNT; i++) {
     if (standard_method_lookup[i]) {
@@ -126,18 +129,20 @@ acl_filter_rule::print()
   printf("src_ip_cnt=%d\n", src_ip_cnt);
   for (i = 0; i < src_ip_cnt; i++) {
     ip_text_buffer b1, b2;
-    printf("%s - %s, ", src_ip_array[i].start.toString(b1, sizeof(b1)), 
src_ip_array[i].end.toString(b2, sizeof(b2)));
+    printf("%s - %s/invert=%s, ", src_ip_array[i].start.toString(b1, 
sizeof(b1)), src_ip_array[i].end.toString(b2, sizeof(b2)),
+           src_ip_array[i].invert ? "true" : "false");
   }
   printf("\n");
   printf("src_ip_category_cnt=%d\n", src_ip_category_cnt);
   for (i = 0; i < src_ip_category_cnt; i++) {
-    printf("%s, ", src_ip_category_array[i].category.c_str());
+    printf("%s/invert=%s, ", src_ip_category_array[i].category.c_str(), 
src_ip_category_array[i].invert ? "true" : "false");
   }
   printf("\n");
   printf("in_ip_cnt=%d\n", in_ip_cnt);
   for (i = 0; i < in_ip_cnt; i++) {
     ip_text_buffer b1, b2;
-    printf("%s - %s, ", in_ip_array[i].start.toString(b1, sizeof(b1)), 
in_ip_array[i].end.toString(b2, sizeof(b2)));
+    printf("%s - %s/invert=%s, ", in_ip_array[i].start.toString(b1, 
sizeof(b1)), in_ip_array[i].end.toString(b2, sizeof(b2)),
+           in_ip_array[i].invert ? "true" : "false");
   }
   printf("\n");
   for (i = 0; i < argc; i++) {
diff --git a/src/proxy/http/remap/RemapConfig.cc 
b/src/proxy/http/remap/RemapConfig.cc
index 2736802a14..2bbc630060 100644
--- a/src/proxy/http/remap/RemapConfig.cc
+++ b/src/proxy/http/remap/RemapConfig.cc
@@ -21,6 +21,7 @@
  *  limitations under the License.
  */
 
+#include "proxy/http/remap/AclFiltering.h"
 #include "swoc/swoc_file.h"
 
 #include "proxy/http/remap/RemapConfig.h"
@@ -111,24 +112,31 @@ process_filter_opt(url_mapping *mp, const 
BUILD_TABLE_INFO *bti, char *errStrBuf
     Debug("url_rewrite", "[process_filter_opt] Invalid argument(s)");
     return (const char *)"[process_filter_opt] Invalid argument(s)";
   }
-  for (rp = bti->rules_list; rp; rp = rp->next) {
-    if (rp->active_queue_flag) {
-      Debug("url_rewrite", "[process_filter_opt] Add active main filter \"%s\" 
(argc=%d)",
-            rp->filter_name ? rp->filter_name : "<nullptr>", rp->argc);
-      for (rpp = &mp->filter; *rpp; rpp = &((*rpp)->next)) {
-        ;
-      }
-      if ((errStr = remap_validate_filter_args(rpp, (const char **)rp->argv, 
rp->argc, errStrBuf, errStrBufSize)) != nullptr) {
-        break;
-      }
-    }
-  }
+  // ACLs are processed in this order:
+  // 1. A remap.config ACL line for an individual remap rule.
+  // 2. All named ACLs in remap.config.
+  // 3. Rules as specified in ip_allow.yaml.
   if (!errStr && (bti->remap_optflg & REMAP_OPTFLG_ALL_FILTERS) != 0) {
     Debug("url_rewrite", "[process_filter_opt] Add per remap filter");
     for (rpp = &mp->filter; *rpp; rpp = &((*rpp)->next)) {
       ;
     }
     errStr = remap_validate_filter_args(rpp, (const char **)bti->argv, 
bti->argc, errStrBuf, errStrBufSize);
+    for (rp = bti->rules_list; rp; rp = rp->next) {
+      for (rpp = &mp->filter; *rpp; rpp = &((*rpp)->next)) {
+        ;
+      }
+      if (rp->active_queue_flag) {
+        Debug("url_rewrite", "[process_filter_opt] Add active main filter 
\"%s\" (argc=%d)",
+              rp->filter_name ? rp->filter_name : "<nullptr>", rp->argc);
+        for (rpp = &mp->filter; *rpp; rpp = &((*rpp)->next)) {
+          ;
+        }
+        if ((errStr = remap_validate_filter_args(rpp, (const char **)rp->argv, 
rp->argc, errStrBuf, errStrBufSize)) != nullptr) {
+          break;
+        }
+      }
+    }
   }
   // Set the ip allow flag for this rule to the current ip allow flag state
   mp->ip_allow_check_enabled_p = bti->ip_allow_check_enabled_p;
@@ -449,6 +457,7 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, const 
char **argv, int arg
     Debug("url_rewrite", "[validate_filter_args] new acl_filter_rule class was 
created during remap rule processing");
   }
 
+  bool ip_is_listed = false;
   for (i = 0; i < argc; i++) {
     unsigned long ul;
     bool hasarg;
@@ -508,7 +517,10 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, 
const char **argv, int arg
       if (ul & REMAP_OPTFLG_INVERT) {
         ipi->invert = true;
       }
-      if (ats_ip_range_parse(argptr, ipi->start, ipi->end) != 0) {
+      std::string_view arg{argptr};
+      if (arg == "all") {
+        ipi->match_all_addresses = true;
+      } else if (ats_ip_range_parse(arg, ipi->start, ipi->end) != 0) {
         Debug("url_rewrite", "[validate_filter_args] Unable to parse IP value 
in %s", argv[i]);
         snprintf(errStrBuf, errStrBufSize, "Unable to parse IP value in %s", 
argv[i]);
         errStrBuf[errStrBufSize - 1] = 0;
@@ -528,6 +540,7 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, const 
char **argv, int arg
       if (ipi) {
         rule->src_ip_cnt++;
         rule->src_ip_valid = 1;
+        ip_is_listed       = true;
       }
     }
 
@@ -543,6 +556,7 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, const 
char **argv, int arg
         return (const char *)errStrBuf;
       }
       src_ip_category_info_t *ipi = 
&rule->src_ip_category_array[rule->src_ip_category_cnt];
+      ipi->category.assign(argptr);
       if (ul & REMAP_OPTFLG_INVERT) {
         ipi->invert = true;
       }
@@ -556,10 +570,11 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, 
const char **argv, int arg
       if (ipi) {
         rule->src_ip_category_cnt++;
         rule->src_ip_category_valid = 1;
+        ip_is_listed                = true;
       }
     }
 
-    if (ul & REMAP_OPTFLG_IN_IP) { /* "dest_ip=" option */
+    if (ul & REMAP_OPTFLG_IN_IP) { /* "in_ip=" option */
       if (rule->in_ip_cnt >= ACL_FILTER_MAX_IN_IP) {
         Debug("url_rewrite", "[validate_filter_args] Too many \"in_ip=\" 
filters");
         snprintf(errStrBuf, errStrBufSize, "Defined more than %d \"in_ip=\" 
filters!", ACL_FILTER_MAX_IN_IP);
@@ -575,7 +590,10 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, 
const char **argv, int arg
         ipi->invert = true;
       }
       // important! use copy of argument
-      if (ats_ip_range_parse(argptr, ipi->start, ipi->end) != 0) {
+      std::string_view arg{argptr};
+      if (arg == "all") {
+        ipi->match_all_addresses = true;
+      } else if (ats_ip_range_parse(arg, ipi->start, ipi->end) != 0) {
         Debug("url_rewrite", "[validate_filter_args] Unable to parse IP value 
in %s", argv[i]);
         snprintf(errStrBuf, errStrBufSize, "Unable to parse IP value in %s", 
argv[i]);
         errStrBuf[errStrBufSize - 1] = 0;
@@ -595,6 +613,7 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, const 
char **argv, int arg
       if (ipi) {
         rule->in_ip_cnt++;
         rule->in_ip_valid = 1;
+        ip_is_listed      = true;
       }
     }
 
@@ -620,6 +639,15 @@ remap_validate_filter_args(acl_filter_rule **rule_pp, 
const char **argv, int arg
     }
   }
 
+  if (!ip_is_listed) {
+    // If no IP addresses are listed, treat that like `@src_ip=all`.
+    ink_release_assert(rule->src_ip_valid == 0 && rule->src_ip_cnt == 0);
+    src_ip_info_t *ipi       = &rule->src_ip_array[rule->src_ip_cnt];
+    ipi->match_all_addresses = true;
+    rule->src_ip_cnt++;
+    rule->src_ip_valid = 1;
+  }
+
   if (is_debug_tag_set("url_rewrite")) {
     rule->print();
   }
@@ -675,7 +703,7 @@ remap_check_option(const char **argv, int argc, unsigned 
long findmode, int *_re
           *argptr = &argv[i][8];
         }
         ret_flags |= (REMAP_OPTFLG_SRC_IP | REMAP_OPTFLG_INVERT);
-      } else if (!strncasecmp(argv[i], "src_ip_category=~", 8)) {
+      } else if (!strncasecmp(argv[i], "src_ip_category=~", 17)) {
         if ((findmode & REMAP_OPTFLG_SRC_IP_CATEGORY) != 0) {
           idx = i;
         }
@@ -691,6 +719,14 @@ remap_check_option(const char **argv, int argc, unsigned 
long findmode, int *_re
           *argptr = &argv[i][7];
         }
         ret_flags |= REMAP_OPTFLG_SRC_IP;
+      } else if (!strncasecmp(argv[i], "src_ip_category=", 16)) {
+        if ((findmode & REMAP_OPTFLG_SRC_IP_CATEGORY) != 0) {
+          idx = i;
+        }
+        if (argptr) {
+          *argptr = &argv[i][16];
+        }
+        ret_flags |= REMAP_OPTFLG_SRC_IP_CATEGORY;
       } else if (!strncasecmp(argv[i], "in_ip=~", 7)) {
         if ((findmode & REMAP_OPTFLG_IN_IP) != 0) {
           idx = i;
diff --git a/src/proxy/http/remap/UrlRewrite.cc 
b/src/proxy/http/remap/UrlRewrite.cc
index 925b1b0e21..1f8176e97c 100644
--- a/src/proxy/http/remap/UrlRewrite.cc
+++ b/src/proxy/http/remap/UrlRewrite.cc
@@ -399,7 +399,7 @@ UrlRewrite::ReverseMap(HTTPHdr *response_header)
 void
 UrlRewrite::PerformACLFiltering(HttpTransact::State *s, url_mapping *map)
 {
-  if (unlikely(!s || s->acl_filtering_performed || 
!s->client_connection_enabled)) {
+  if (unlikely(!s || s->acl_filtering_performed || 
!s->client_connection_allowed)) {
     return;
   }
 
@@ -411,60 +411,70 @@ UrlRewrite::PerformACLFiltering(HttpTransact::State *s, 
url_mapping *map)
 
     ink_release_assert(ats_is_ip(&s->client_info.src_addr));
 
-    s->client_connection_enabled = true; // Default is that we allow things 
unless some filter matches
+    s->client_connection_allowed = true; // Default is that we allow things 
unless some filter matches
 
-    for (acl_filter_rule *rp = map->filter; rp; rp = rp->next) {
-      bool match = true;
+    int rule_index = 0;
+    for (acl_filter_rule *rp = map->filter; rp; rp = rp->next, ++rule_index) {
+      bool method_matches = true;
 
       if (rp->method_restriction_enabled) {
         if (method_wksidx >= 0 && method_wksidx < HTTP_WKSIDX_METHODS_CNT) {
-          match = rp->standard_method_lookup[method_wksidx];
+          method_matches = rp->standard_method_lookup[method_wksidx];
         } else if (!rp->nonstandard_methods.empty()) {
-          match = false;
+          method_matches = false;
         } else {
           int method_str_len;
           const char *method_str = 
s->hdr_info.client_request.method_get(&method_str_len);
-          match                  = 
rp->nonstandard_methods.count(std::string(method_str, method_str_len));
+          method_matches         = 
rp->nonstandard_methods.count(std::string(method_str, method_str_len));
         }
+      } else {
+        // No method specified, therefore all match.
+        method_matches = true;
       }
 
-      if (match && rp->src_ip_valid) {
-        match = false;
-        for (int j = 0; j < rp->src_ip_cnt && !match; j++) {
+      bool ip_matches = true;
+      // Is there a @src_ip specified? If so, check it.
+      if (rp->src_ip_valid) {
+        bool src_ip_matches = false;
+        for (int j = 0; j < rp->src_ip_cnt && !src_ip_matches; j++) {
           bool in_range = 
rp->src_ip_array[j].contains(s->client_info.src_addr);
           if (rp->src_ip_array[j].invert) {
             if (!in_range) {
-              match = true;
+              src_ip_matches = true;
             }
           } else {
             if (in_range) {
-              match = true;
+              src_ip_matches = true;
             }
           }
         }
+        Debug("url_rewrite", "Checked the specified src_ip, result: %s", 
src_ip_matches ? "true" : "false");
+        ip_matches &= src_ip_matches;
       }
 
-      if (match && rp->src_ip_category_valid) {
-        Debug("url_rewrite", "match was true and we have specified an 
src_ip_category field");
-        match = false;
-        for (int j = 0; j < rp->src_ip_category_cnt && !match; j++) {
+      // Is there a @src_ip_category specified? If so, check it.
+      if (ip_matches && rp->src_ip_category_valid) {
+        bool category_ip_matches = false;
+        for (int j = 0; j < rp->src_ip_category_cnt && !category_ip_matches; 
j++) {
           bool in_category = 
rp->src_ip_category_array[j].contains(s->client_info.src_addr);
           if (rp->src_ip_category_array[j].invert) {
             if (!in_category) {
-              match = true;
+              category_ip_matches = true;
             }
           } else {
             if (in_category) {
-              match = true;
+              category_ip_matches = true;
             }
           }
         }
+        Debug("url_rewrite", "Checked the specified src_ip_category, result: 
%s", category_ip_matches ? "true" : "false");
+        ip_matches &= category_ip_matches;
       }
 
-      if (match && rp->in_ip_valid) {
-        Debug("url_rewrite", "match was true and we have specified an in_ip 
field");
-        match = false;
-        for (int j = 0; j < rp->in_ip_cnt && !match; j++) {
+      // Is there an @in_ip specified? If so, check it.
+      if (ip_matches && rp->in_ip_valid) {
+        bool in_ip_matches = false;
+        for (int j = 0; j < rp->in_ip_cnt && !in_ip_matches; j++) {
           IpEndpoint incoming_addr;
           
incoming_addr.assign(s->state_machine->get_ua_txn()->get_netvc()->get_local_addr());
           if (is_debug_tag_set("url_rewrite")) {
@@ -477,28 +487,40 @@ UrlRewrite::PerformACLFiltering(HttpTransact::State *s, 
url_mapping *map)
           bool in_range = rp->in_ip_array[j].contains(incoming_addr);
           if (rp->in_ip_array[j].invert) {
             if (!in_range) {
-              match = true;
+              in_ip_matches = true;
             }
           } else {
             if (in_range) {
-              match = true;
+              in_ip_matches = true;
             }
           }
         }
+        Debug("url_rewrite", "Checked the specified in_ip, result: %s", 
in_ip_matches ? "true" : "false");
+        ip_matches &= in_ip_matches;
       }
 
       if (rp->internal) {
-        match = 
s->state_machine->get_ua_txn()->get_netvc()->get_is_internal_request();
-        Debug("url_rewrite", "%s an internal request", match ? "matched" : 
"didn't match");
+        ip_matches = 
s->state_machine->get_ua_txn()->get_netvc()->get_is_internal_request();
+        Debug("url_rewrite", "%s an internal request", ip_matches ? "matched" 
: "didn't match");
       }
 
-      if (match) {
-        // We have a match, stop evaluating filters
-        Debug("url_rewrite", "matched ACL filter rule, %s request", 
rp->allow_flag ? "allowing" : "denying");
-        s->client_connection_enabled = rp->allow_flag;
+      Debug("url_rewrite", "%d: ACL filter %s rule matches by ip: %s, by 
method: %s", rule_index,
+            (rp->allow_flag ? "allow" : "deny"), (ip_matches ? "true" : 
"false"), (method_matches ? "true" : "false"));
+
+      if (ip_matches) {
+        // The rule matches. Handle the method according to the rule.
+        if (method_matches) {
+          // Did they specify allowing the listed methods, or denying them?
+          Debug("url_rewrite", "matched ACL filter rule, %s request", 
rp->allow_flag ? "allowing" : "denying");
+          s->client_connection_allowed = rp->allow_flag;
+        } else {
+          Debug("url_rewrite", "ACL rule matched on IP but not on method, 
action: %s, %s the request",
+                (rp->allow_flag ? "allow" : "deny"), (rp->allow_flag ? 
"denying" : "allowing"));
+          s->client_connection_allowed = !rp->allow_flag;
+        }
+        // Since we have a matching ACL, no need to process ip_allow.yaml 
rules.
+        map->ip_allow_check_enabled_p = false;
         break;
-      } else {
-        Debug("url_rewrite", "did NOT match ACL filter rule, %s request", 
rp->allow_flag ? "denying" : "allowing");
       }
     }
   } /* end of for(rp = map->filter;rp;rp = rp->next) */
diff --git a/tests/gold_tests/ip_allow/ip_category.test.py 
b/tests/gold_tests/ip_allow/ip_category.test.py
index e5044ecc62..9c04df20d2 100644
--- a/tests/gold_tests/ip_allow/ip_category.test.py
+++ b/tests/gold_tests/ip_allow/ip_category.test.py
@@ -316,11 +316,11 @@ test_ip_allow_optional_methods = Test_ip_category(
     acl_configuration='',
     expected_responses=None)
 
-# Deny GET as well via remap.config ACL.
+# Deny GET via remap.config ACL.
 test_ip_allow_optional_methods = Test_ip_category(
-    "IP Category: INTERNAL",
+    "IP Category: EXTERNAL",
     replay_file='replays/https_categories_external_remap.replay.yaml',
     ip_allow_config=IP_ALLOW_CONTENT,
     ip_category_config=localhost_is_external,
     acl_configuration='@action=deny @src_ip_category=ACME_REMAP_EXTERNAL 
@method=GET',
-    expected_responses=[403, 403, 403])
+    expected_responses=[403, 200, 200])
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
index 16ca64ddf7..2ead15ebb7 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ 
b/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
@@ -14,8 +14,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# The replay file executes various HTTP requests to verify that GET
+# is denied while all other requests are allowed.
 
 meta:
   version: "1.0"
@@ -53,7 +53,7 @@ sessions:
     proxy-response:
       status: 403
 
-  # POST rejected
+  # POST accepted
   - client-request:
       method: "POST"
       version: "1.1"
@@ -64,13 +64,12 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
     <<: *standard_response
 
     proxy-response:
-      status: 403
+      status: 200
 
-  # PUSH rejected
+  # PUSH accepted
   - client-request:
       method: "PUSH"
       version: "1.1"
@@ -89,4 +88,4 @@ sessions:
 
     # Verify that ATS rejected the PUSH.
     proxy-response:
-      status: 403
+      status: 400
diff --git a/tests/gold_tests/remap/remap_acl.test.py 
b/tests/gold_tests/remap/remap_acl.test.py
new file mode 100644
index 0000000000..b4bb1c7e85
--- /dev/null
+++ b/tests/gold_tests/remap/remap_acl.test.py
@@ -0,0 +1,298 @@
+'''
+Verify remap.config acl behavior.
+'''
+#  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.
+
+import os
+import re
+from typing import List, Tuple
+
+Test.Summary = '''
+Verify remap.config acl behavior.
+'''
+
+
+class Test_remap_acl:
+    """Configure a test to verify remap.config acl behavior."""
+
+    _ts_counter: int = 0
+    _server_counter: int = 0
+    _client_counter: int = 0
+
+    def __init__(
+            self, name: str, replay_file: str, ip_allow_content: str, 
deactivate_ip_allow: bool, acl_configuration: str,
+            named_acls: List[Tuple[str, str]], expected_responses: list[int]):
+        """Initialize the test.
+
+        :param name: The name of the test.
+        :param replay_file: The replay file to be used.
+        :param ip_allow_content: The ip_allow configuration to be used.
+        :param deactivate_ip_allow: Whether to deactivate the ip_allow filter.
+        :param acl_configuration: The ACL configuration to be used.
+        :param named_acls: The set of named ACLs to configure and use.
+        :param expect_responses: The in-order expected responses from the 
proxy.
+        """
+        self._replay_file = replay_file
+        self._ip_allow_content = ip_allow_content
+        self._deactivate_ip_allow = deactivate_ip_allow
+        self._acl_configuration = acl_configuration
+        self._named_acls = named_acls
+        self._expected_responses = expected_responses
+
+        tr = Test.AddTestRun(name)
+        self._configure_server(tr)
+        self._configure_traffic_server(tr)
+        self._configure_client(tr)
+
+    def _configure_server(self, tr: 'TestRun') -> None:
+        """Configure the server.
+
+        :param tr: The TestRun object to associate the server process with.
+        """
+        name = f"server-{Test_remap_acl._server_counter}"
+        server = tr.AddVerifierServerProcess(name, self._replay_file)
+        Test_remap_acl._server_counter += 1
+        self._server = server
+
+    def _configure_traffic_server(self, tr: 'TestRun') -> None:
+        """Configure Traffic Server.
+
+        :param tr: The TestRun object to associate the Traffic Server process 
with.
+        """
+
+        name = f"ts-{Test_remap_acl._ts_counter}"
+        ts = tr.MakeATSProcess(name, enable_cache=False, enable_tls=True)
+        Test_remap_acl._ts_counter += 1
+        self._ts = ts
+
+        ts.addDefaultSSLFiles()
+        ts.Disk.ssl_multicert_config.AddLine('dest_ip=* 
ssl_cert_name=server.pem ssl_key_name=server.key')
+        ts.Disk.records_config.update(
+            {
+                'proxy.config.diags.debug.enabled': 1,
+                'proxy.config.diags.debug.tags': 'http|url|remap|ip_allow',
+                'proxy.config.http.push_method_enabled': 1,
+                'proxy.config.ssl.server.cert.path': ts.Variables.SSLDir,
+                'proxy.config.quic.no_activity_timeout_in': 0,
+                'proxy.config.ssl.server.private_key.path': 
ts.Variables.SSLDir,
+                'proxy.config.ssl.client.verify.server.policy': 'PERMISSIVE',
+                'proxy.config.http.connect_ports': 
self._server.Variables.http_port,
+            })
+
+        remap_config_lines = []
+        if self._deactivate_ip_allow:
+            remap_config_lines.append('.deactivatefilter ip_allow')
+
+        # First, define the name ACLs (filters).
+        for name, definition in self._named_acls:
+            remap_config_lines.append(f'.definefilter {name} {definition}')
+        # Now activate them.
+        for name, _ in self._named_acls:
+            remap_config_lines.append(f'.activatefilter {name}')
+
+        remap_config_lines.append(f'map / 
http://127.0.0.1:{self._server.Variables.http_port} {self._acl_configuration}')
+        ts.Disk.remap_config.AddLines(remap_config_lines)
+        ts.Disk.ip_allow_yaml.AddLines(self._ip_allow_content.split("\n"))
+
+    def _configure_client(self, tr: 'TestRun') -> None:
+        """Run the test.
+
+        :param tr: The TestRun object to associate the client process with.
+        """
+
+        name = f"client-{Test_remap_acl._client_counter}"
+        p = tr.AddVerifierClientProcess(name, self._replay_file, 
https_ports=[self._ts.Variables.ssl_port])
+        Test_remap_acl._client_counter += 1
+        p.StartBefore(self._server)
+        p.StartBefore(self._ts)
+
+        codes = [str(code) for code in self._expected_responses]
+        p.Streams.stdout += Testers.ContainsExpression(
+            '.*'.join(codes), "Verifying the expected order of responses", 
reflags=re.DOTALL | re.MULTILINE)
+
+
+IP_ALLOW_CONTENT = f'''
+ip_categories:
+  - name: ACME_LOCAL
+    ip_addrs: 127.0.0.1
+  - name: ACME_EXTERNAL
+    ip_addrs: 5.6.7.8
+
+ip_allow:
+  - apply: in
+    ip_addrs: 0/0
+    action: allow
+    methods:
+      - GET
+'''
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify non-allowed methods are blocked.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify if no ACLs match, ip_allow.yaml is used.",
+    replay_file='remap_acl_get_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=1.2.3.4 @method=GET @method=POST',
+    named_acls=[],
+    expected_responses=[200, 403, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify @src_ip=all works.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=all @method=GET @method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify @src_ip_category works.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip_category=ACME_LOCAL @method=GET 
@method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify no @src_ip implies all IP addresses.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @method=GET @method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify denied methods are blocked.",
+    replay_file='remap_acl_get_post_denied.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=deny @src_ip=127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[],
+    expected_responses=[403, 403, 200, 200, 400])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify a default deny filter rule works.",
+    replay_file='remap_acl_all_denied.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=1.2.3.4 @method=GET @method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[403, 403, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify inverting @src_ip works.",
+    replay_file='remap_acl_all_denied.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=~127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[403, 403, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify inverting @src_ip works with the rule matching.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=~3.4.5.6 @method=GET 
@method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify inverting @src_ip_category works.",
+    replay_file='remap_acl_all_denied.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip_category=~ACME_LOCAL @method=GET 
@method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[403, 403, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify inverting @src_ip_category works with the rule matching.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip_category=~ACME_EXTERNAL 
@method=GET @method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify @src_ip and @src_ip_category AND together.",
+    replay_file='remap_acl_all_denied.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    # The rule will not match because, while @src_ip matches, @src_ip_category 
does not.
+    acl_configuration='@action=allow @src_ip=127.0.0.1 
@src_ip_category=ACME_EXTERNAL @method=GET @method=POST',
+    # Therefore, this named deny filter will block.
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[403, 403, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify defined in-line ACLS are evaluated before named ones.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[('deny', '@action=deny')],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify remap.config line overrides ip_allow rule.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @src_ip=127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify we can deactivate the ip_allow filter.",
+    replay_file='remap_acl_all_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=True,
+    # This won't match, so nothing will match since ip_allow.yaml is off.
+    acl_configuration='@action=allow @src_ip=1.2.3.4 @method=GET @method=POST',
+    named_acls=[],
+    # Nothing will block the request since ip_allow.yaml is off.
+    expected_responses=[200, 200, 200, 200, 400])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify in_ip matches on IP as expected.",
+    replay_file='remap_acl_get_post_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @in_ip=127.0.0.1 @method=GET 
@method=POST',
+    named_acls=[],
+    expected_responses=[200, 200, 403, 403, 403])
+
+test_ip_allow_optional_methods = Test_remap_acl(
+    "Verify in_ip rules do not match on other IPs.",
+    replay_file='remap_acl_get_allowed.replay.yaml',
+    ip_allow_content=IP_ALLOW_CONTENT,
+    deactivate_ip_allow=False,
+    acl_configuration='@action=allow @in_ip=3.4.5.6 @method=GET @method=POST',
+    named_acls=[],
+    expected_responses=[200, 403, 403, 403, 403])
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/remap/remap_acl_all_allowed.replay.yaml
similarity index 69%
copy from 
tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
copy to tests/gold_tests/remap/remap_acl_all_allowed.replay.yaml
index 16ca64ddf7..52d9517d91 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ b/tests/gold_tests/remap/remap_acl_all_allowed.replay.yaml
@@ -14,8 +14,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# This expects a remap.config to allow all requests.
 
 meta:
   version: "1.0"
@@ -49,11 +48,9 @@ sessions:
 
     <<: *standard_response
 
-    # Even GET is now blocked via remap ACL.
     proxy-response:
-      status: 403
+      status: 200
 
-  # POST rejected
   - client-request:
       method: "POST"
       version: "1.1"
@@ -64,13 +61,47 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
     <<: *standard_response
 
     proxy-response:
-      status: 403
+      status: 200
+
+  - client-request:
+      method: "PUT"
+      version: "1.1"
+      url: /test/ip_allow/test_put
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, put ]
+        - [ X-Request, put ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: 
bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    # Not received.
+    <<: *standard_response
+
+    proxy-response:
+      status: 200
+
+  - client-request:
+      method: "DELETE"
+      version: "1.1"
+      url: /test/ip_allow/test_delete
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, delete ]
+        - [ X-Request, delete ]
+        - [ Content-Length, 0 ]
+
+    <<: *standard_response
+
+    proxy-response:
+      status: 200
 
-  # PUSH rejected
   - client-request:
       method: "PUSH"
       version: "1.1"
@@ -87,6 +118,5 @@ sessions:
 
     <<: *standard_response
 
-    # Verify that ATS rejected the PUSH.
     proxy-response:
-      status: 403
+      status: 400
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/remap/remap_acl_all_denied.replay.yaml
similarity index 69%
copy from 
tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
copy to tests/gold_tests/remap/remap_acl_all_denied.replay.yaml
index 16ca64ddf7..d15782b046 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ b/tests/gold_tests/remap/remap_acl_all_denied.replay.yaml
@@ -14,8 +14,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# This expects a remap.config that denies all request methods.
 
 meta:
   version: "1.0"
@@ -47,13 +46,12 @@ sessions:
         - [ uuid, get ]
         - [ X-Request, get ]
 
+    # Not received.
     <<: *standard_response
 
-    # Even GET is now blocked via remap ACL.
     proxy-response:
       status: 403
 
-  # POST rejected
   - client-request:
       method: "POST"
       version: "1.1"
@@ -64,7 +62,44 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
+    # Not received.
+    <<: *standard_response
+
+    proxy-response:
+      status: 403
+
+  - client-request:
+      method: "PUT"
+      version: "1.1"
+      url: /test/ip_allow/test_put
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, put ]
+        - [ X-Request, put ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: 
bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    # Not received.
+    <<: *standard_response
+
+    proxy-response:
+      status: 403
+
+  # DELETE rejected
+  - client-request:
+      method: "DELETE"
+      version: "1.1"
+      url: /test/ip_allow/test_delete
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, delete ]
+        - [ X-Request, delete ]
+        - [ Content-Length, 0 ]
+
     <<: *standard_response
 
     proxy-response:
@@ -87,6 +122,5 @@ sessions:
 
     <<: *standard_response
 
-    # Verify that ATS rejected the PUSH.
     proxy-response:
       status: 403
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/remap/remap_acl_get_allowed.replay.yaml
similarity index 68%
copy from 
tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
copy to tests/gold_tests/remap/remap_acl_get_allowed.replay.yaml
index 16ca64ddf7..3e20822fda 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ b/tests/gold_tests/remap/remap_acl_get_allowed.replay.yaml
@@ -14,8 +14,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# This expects a remap.config that allows GET, but denies all other
+# methods.
 
 meta:
   version: "1.0"
@@ -49,9 +49,8 @@ sessions:
 
     <<: *standard_response
 
-    # Even GET is now blocked via remap ACL.
     proxy-response:
-      status: 403
+      status: 200
 
   # POST rejected
   - client-request:
@@ -64,12 +63,51 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
     <<: *standard_response
 
     proxy-response:
       status: 403
 
+  # PUT rejected
+  - client-request:
+      method: "PUT"
+      version: "1.1"
+      url: /test/ip_allow/test_put
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, put ]
+        - [ X-Request, put ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: 
bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    # Not received.
+    <<: *standard_response
+
+    # Verify that ATS rejected the PUSH.
+    proxy-response:
+      status: 403
+
+  # DELETE rejected
+  - client-request:
+      method: "DELETE"
+      version: "1.1"
+      url: /test/ip_allow/test_delete
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, delete ]
+        - [ X-Request, delete ]
+        - [ Content-Length, 0 ]
+
+    <<: *standard_response
+
+    # Verify that ATS rejects the DELETE.
+    proxy-response:
+      status: 403
+
   # PUSH rejected
   - client-request:
       method: "PUSH"
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/remap/remap_acl_get_post_allowed.replay.yaml
similarity index 67%
copy from 
tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
copy to tests/gold_tests/remap/remap_acl_get_post_allowed.replay.yaml
index 16ca64ddf7..cf08a22a8a 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ b/tests/gold_tests/remap/remap_acl_get_post_allowed.replay.yaml
@@ -14,8 +14,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# This expects a remap.config that allows GET and POST, but denies all other
+# methods.
 
 meta:
   version: "1.0"
@@ -49,11 +49,10 @@ sessions:
 
     <<: *standard_response
 
-    # Even GET is now blocked via remap ACL.
     proxy-response:
-      status: 403
+      status: 200
 
-  # POST rejected
+  # POST also is in the allow list.
   - client-request:
       method: "POST"
       version: "1.1"
@@ -64,9 +63,48 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
     <<: *standard_response
 
+    proxy-response:
+      status: 200
+
+  # PUT rejected
+  - client-request:
+      method: "PUT"
+      version: "1.1"
+      url: /test/ip_allow/test_put
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, put ]
+        - [ X-Request, put ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: 
bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    # Not received.
+    <<: *standard_response
+
+    # Verify that ATS rejected the PUSH.
+    proxy-response:
+      status: 403
+
+  # DELETE rejected
+  - client-request:
+      method: "DELETE"
+      version: "1.1"
+      url: /test/ip_allow/test_delete
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, delete ]
+        - [ X-Request, delete ]
+        - [ Content-Length, 0 ]
+
+    <<: *standard_response
+
+    # Verify that ATS rejects the DELETE.
     proxy-response:
       status: 403
 
diff --git 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml 
b/tests/gold_tests/remap/remap_acl_get_post_denied.replay.yaml
similarity index 67%
copy from 
tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
copy to tests/gold_tests/remap/remap_acl_get_post_denied.replay.yaml
index 16ca64ddf7..2a82445648 100644
--- 
a/tests/gold_tests/ip_allow/replays/https_categories_external_remap.replay.yaml
+++ b/tests/gold_tests/remap/remap_acl_get_post_denied.replay.yaml
@@ -14,8 +14,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# The replay file executes various HTTP requests to verify the ip_allow policy
-# applies by default to all methods.
+# This expects a remap.config that denies GET and POST, but allows all other
+# methods.
 
 meta:
   version: "1.0"
@@ -49,11 +49,9 @@ sessions:
 
     <<: *standard_response
 
-    # Even GET is now blocked via remap ACL.
     proxy-response:
       status: 403
 
-  # POST rejected
   - client-request:
       method: "POST"
       version: "1.1"
@@ -64,13 +62,47 @@ sessions:
         - [ uuid, post ]
         - [ X-Request, post ]
 
-    # Shouldn't be used.
     <<: *standard_response
 
     proxy-response:
       status: 403
 
-  # PUSH rejected
+  # All other methods are allowed.
+  - client-request:
+      method: "PUT"
+      version: "1.1"
+      url: /test/ip_allow/test_put
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, put ]
+        - [ X-Request, put ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: 
bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    <<: *standard_response
+
+    proxy-response:
+      status: 200
+
+  - client-request:
+      method: "DELETE"
+      version: "1.1"
+      url: /test/ip_allow/test_delete
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, delete ]
+        - [ X-Request, delete ]
+        - [ Content-Length, 0 ]
+
+    <<: *standard_response
+
+    proxy-response:
+      status: 200
+
   - client-request:
       method: "PUSH"
       version: "1.1"
@@ -87,6 +119,6 @@ sessions:
 
     <<: *standard_response
 
-    # Verify that ATS rejected the PUSH.
+    # ATS will allow the PUSH, but issue a 400 saying that it can't cache it.
     proxy-response:
-      status: 403
+      status: 400

Reply via email to