[TS-1981] Adding arbitrary methods to url remap, and fix the same problem in IpAllow
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/0094d4b1 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/0094d4b1 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/0094d4b1 Branch: refs/heads/master Commit: 0094d4b11091bba7496b19445c380ccb2443cda0 Parents: 923269b Author: Brian Geffon <[email protected]> Authored: Fri May 30 13:42:17 2014 -0700 Committer: Brian Geffon <[email protected]> Committed: Fri May 30 13:42:17 2014 -0700 ---------------------------------------------------------------------- proxy/IPAllow.cc | 42 ++++++++++++++------- proxy/IPAllow.h | 69 ++++++++++++++++++++++------------- proxy/http/HttpClientSession.cc | 2 +- proxy/http/HttpClientSession.h | 5 ++- proxy/http/HttpSessionAccept.cc | 8 ++-- proxy/http/HttpTransact.cc | 23 +++++++++--- proxy/http/remap/AclFiltering.cc | 29 ++++++++++----- proxy/http/remap/AclFiltering.h | 16 +++++--- proxy/http/remap/RemapConfig.cc | 49 ++++--------------------- proxy/http/remap/UrlRewrite.cc | 31 ++++++++++------ 10 files changed, 154 insertions(+), 120 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/IPAllow.cc ---------------------------------------------------------------------- diff --git a/proxy/IPAllow.cc b/proxy/IPAllow.cc index de2a72f..bd8d81b 100644 --- a/proxy/IPAllow.cc +++ b/proxy/IPAllow.cc @@ -44,10 +44,7 @@ enum AclOp { ACL_OP_DENY, ///< Deny access. }; -// Mask for all methods. -// This can't be computed properly at process start, so it's delayed -// until the instance is initialized. -uint32_t IpAllow::ALL_METHOD_MASK; +const AclRecord IpAllow::ALL_METHOD_ACL(AclRecord::ALL_METHOD_MASK); int IpAllow::configid = 0; @@ -138,8 +135,8 @@ IpAllow::Print() { s << " - " << ats_ip_ntop(spot->max(), text, sizeof text); } s << " method="; - uint32_t mask = ALL_METHOD_MASK & ar->_method_mask; - if (ALL_METHOD_MASK == mask) { + uint32_t mask = AclRecord::ALL_METHOD_MASK & ar->_method_mask; + if (AclRecord::ALL_METHOD_MASK == mask) { s << "ALL"; } else if (0 == mask) { s << "NONE"; @@ -155,6 +152,18 @@ IpAllow::Print() { } } } + if (!ar->_nonstandard_methods.empty()) { + s << " nonstandard method="; + bool leader = false; // need leading vbar? + for (AclRecord::MethodSet::iterator iter = ar->_nonstandard_methods.begin(), + end = ar->_nonstandard_methods.end(); iter != end; ++iter) { + if (leader) { + s << '|'; + } + s << *iter; + leader = true; + } + } } Debug("ip-allow", "%s", s.str().c_str()); } @@ -216,6 +225,8 @@ IpAllow::BuildTable() // Search for "action=ip_allow method=PURGE method=GET ..." or "action=ip_deny method=PURGE method=GET ...". char *label, *val; uint32_t acl_method_mask = 0; + AclRecord::MethodSet nonstandard_methods; + bool deny_nonstandard_methods = false; AclOp op = ACL_OP_DENY; // "shut up", I explained to the compiler. bool op_found = false, method_found = false; for (int i = 0; i < MATCHER_MAX_TOKENS; i++) { @@ -248,30 +259,35 @@ IpAllow::BuildTable() method_found = false; // in case someone does method=GET|ALL break; } else { - int method_idx = hdrtoken_tokenize(method_name, strlen(method_name)); + int method_name_len = strlen(method_name); + int method_idx = hdrtoken_tokenize(method_name, method_name_len); if (method_idx < HTTP_WKSIDX_CONNECT || method_idx >= HTTP_WKSIDX_CONNECT + HTTP_WKSIDX_METHODS_CNT) { - Warning("Method name '%s' on line %d is not valid. Ignoring.", method_name, line_num); + nonstandard_methods.insert(method_name); + Debug("ip-allow", "Found nonstandard method [%s] on line %d", method_name, line_num); } else { // valid method. - method_found = true; - acl_method_mask |= MethodIdxToMask(method_idx); + acl_method_mask |= AclRecord::MethodIdxToMask(method_idx); } + method_found = true; } } } } // If method not specified, default to ALL if (!method_found) { - method_found = true, acl_method_mask = ALL_METHOD_MASK; + method_found = true; + acl_method_mask = AclRecord::ALL_METHOD_MASK; + nonstandard_methods.clear(); } // When deny, use bitwise complement. (Make the rule 'allow for all // methods except those specified') if (op == ACL_OP_DENY) { - acl_method_mask = ALL_METHOD_MASK & ~acl_method_mask; + acl_method_mask = AclRecord::ALL_METHOD_MASK & ~acl_method_mask; + deny_nonstandard_methods = true; } } if (method_found) { - _acls.push_back(AclRecord(acl_method_mask, line_num)); + _acls.push_back(AclRecord(acl_method_mask, line_num, nonstandard_methods, deny_nonstandard_methods)); // Color with index because at this point the address // is volatile. _map.fill( http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/IPAllow.h ---------------------------------------------------------------------- diff --git a/proxy/IPAllow.h b/proxy/IPAllow.h index 2c2d232..695d351 100644 --- a/proxy/IPAllow.h +++ b/proxy/IPAllow.h @@ -37,6 +37,9 @@ #include "ts/Vec.h" #include "ProxyConfig.h" +#include <string> +#include <set> + // forward declare in name only so it can be a friend. struct IpAllowUpdate; @@ -51,14 +54,41 @@ static uint64_t const IP_ALLOW_TIMEOUT = HRTIME_HOUR; It has the methods permitted and the source line. */ struct AclRecord { - int _method_mask; + uint32_t _method_mask; int _src_line; + typedef std::set<std::string> MethodSet; + MethodSet _nonstandard_methods; + bool _deny_nonstandard_methods; + static const uint32_t ALL_METHOD_MASK = ~0; // Mask for all methods. /// Default constructor. /// Present only to make Vec<> happy, do not use. - AclRecord() : _method_mask(0), _src_line(0) { } + AclRecord() : _method_mask(0), _src_line(0), _deny_nonstandard_methods(false) { } + + AclRecord(uint32_t method_mask) : _method_mask(method_mask), _src_line(0), + _deny_nonstandard_methods(false) { } + + AclRecord(uint32_t method_mask, int ln, const MethodSet &nonstandard_methods, bool deny_nonstandard_methods) + : _method_mask(method_mask), _src_line(ln), _nonstandard_methods(nonstandard_methods), + _deny_nonstandard_methods(deny_nonstandard_methods) { } + + static uint32_t MethodIdxToMask(int wksidx) { return 1 << (wksidx - HTTP_WKSIDX_CONNECT); } - AclRecord(uint32_t method_mask, int ln) : _method_mask(method_mask), _src_line(ln) { } + bool isEmpty() const { + return (_method_mask == 0) && _nonstandard_methods.empty(); + } + + bool isMethodAllowed(int method_wksidx) const { + return _method_mask & MethodIdxToMask(method_wksidx); + } + + bool isNonstandardMethodAllowed(const std::string &method_str) const { + if (_method_mask == ALL_METHOD_MASK) { + return true; + } + bool method_in_set = _nonstandard_methods.count(method_str); + return _deny_nonstandard_methods ? !method_in_set : method_in_set; + } }; /** Singleton class for access controls. @@ -74,8 +104,8 @@ public: IpAllow(const char *config_var, const char *name, const char *action_val); ~IpAllow(); void Print(); - uint32_t match(IpEndpoint const* ip) const; - uint32_t match(sockaddr const* ip) const; + AclRecord *match(IpEndpoint const* ip) const; + AclRecord *match(sockaddr const* ip) const; static void startup(); static void reconfigure(); @@ -83,18 +113,16 @@ public: static IpAllow * acquire(); static void release(IpAllow * params); - static bool CheckMask(uint32_t, int); /// @return A mask that permits all methods. - static uint32_t AllMethodMask() { - return ALL_METHOD_MASK; + static const AclRecord *AllMethodAcl() { + return &ALL_METHOD_ACL; } typedef ConfigProcessor::scoped_config<IpAllow, IpAllow> scoped_config; private: - static uint32_t MethodIdxToMask(int); - static uint32_t ALL_METHOD_MASK; static int configid; + static const AclRecord ALL_METHOD_ACL; int BuildTable(); @@ -105,29 +133,18 @@ private: Vec<AclRecord> _acls; }; -inline uint32_t IpAllow::MethodIdxToMask(int idx) { return 1 << (idx - HTTP_WKSIDX_CONNECT); } - -inline uint32_t +inline AclRecord * IpAllow::match(IpEndpoint const* ip) const { return this->match(&ip->sa); } -inline uint32_t +inline AclRecord * IpAllow::match(sockaddr const* ip) const { - uint32_t zret = 0; - void* raw; + void *raw; if (_map.contains(ip, &raw)) { - AclRecord* acl = static_cast<AclRecord*>(raw); - if (acl) { - zret = acl->_method_mask; - } + return static_cast<AclRecord*>(raw); } - return zret; -} - -inline bool -IpAllow::CheckMask(uint32_t mask, int method_idx) { - return ((mask & MethodIdxToMask(method_idx)) != 0); + return NULL; } #endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/HttpClientSession.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc index 1239113..9952cf1 100644 --- a/proxy/http/HttpClientSession.cc +++ b/proxy/http/HttpClientSession.cc @@ -68,7 +68,7 @@ HttpClientSession::HttpClientSession() cur_hooks(0), backdoor_connect(false), hooks_set(0), outbound_port(0), f_outbound_transparent(false), - host_res_style(HOST_RES_IPV4), acl_method_mask(0), + host_res_style(HOST_RES_IPV4), acl_record(NULL), m_active(false), debug_on(false) { memset(user_args, 0, sizeof(user_args)); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/HttpClientSession.h ---------------------------------------------------------------------- diff --git a/proxy/http/HttpClientSession.h b/proxy/http/HttpClientSession.h index 8daf04f..cb4c5ba 100644 --- a/proxy/http/HttpClientSession.h +++ b/proxy/http/HttpClientSession.h @@ -37,6 +37,7 @@ #include "InkAPIInternal.h" #include "HTTP.h" #include "HttpConfig.h" +#include "IPAllow.h" extern ink_mutex debug_cs_list_mutex; @@ -152,8 +153,8 @@ public: bool f_transparent_passthrough; /// DNS resolution preferences. HostResStyle host_res_style; - /// acl method mask - cache IpAllow::match() call - uint32_t acl_method_mask; + /// acl record - cache IpAllow::match() call + const AclRecord *acl_record; // for DI. An active connection is one that a request has // been successfully parsed (PARSE_DONE) and it remains to http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/HttpSessionAccept.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpSessionAccept.cc b/proxy/http/HttpSessionAccept.cc index e485764..942a215 100644 --- a/proxy/http/HttpSessionAccept.cc +++ b/proxy/http/HttpSessionAccept.cc @@ -31,15 +31,15 @@ void HttpSessionAccept::accept(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader) { sockaddr const* client_ip = netvc->get_remote_addr(); - uint32_t acl_method_mask = 0; + const AclRecord *acl_record = NULL; ip_port_text_buffer ipb; IpAllow::scoped_config ipallow; // The backdoor port is now only bound to "localhost", so no // reason to check for if it's incoming from "localhost" or not. if (backdoor) { - acl_method_mask = IpAllow::AllMethodMask(); - } else if (ipallow && ((acl_method_mask = ipallow->match(client_ip)) == 0)) { + acl_record = IpAllow::AllMethodAcl(); + } else if (ipallow && (((acl_record = ipallow->match(client_ip)) == NULL) || (acl_record->isEmpty()))) { //////////////////////////////////////////////////// // if client address forbidden, close immediately // //////////////////////////////////////////////////// @@ -64,7 +64,7 @@ HttpSessionAccept::accept(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferRea new_session->outbound_ip6 = outbound_ip6; new_session->outbound_port = outbound_port; new_session->host_res_style = ats_host_res_from(client_ip->sa_family, host_res_preference); - new_session->acl_method_mask = acl_method_mask; + new_session->acl_record = acl_record; new_session->new_connection(netvc, backdoor, iobuf, reader); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/HttpTransact.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 9efb233..7d028f8 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -6497,12 +6497,25 @@ HttpTransact::process_quick_http_filter(State* s, int method) return; } - if (s->state_machine->ua_session && (!IpAllow::CheckMask(s->state_machine->ua_session->acl_method_mask, method))) { - if (is_debug_tag_set("ip-allow")) { - ip_text_buffer ipb; - Debug("ip-allow", "Quick filter denial on %s:%s with mask %x", ats_ip_ntop(&s->client_info.addr.sa, ipb, sizeof(ipb)), hdrtoken_index_to_wks(method), s->state_machine->ua_session->acl_method_mask); + if (s->state_machine->ua_session) { + const AclRecord *acl_record = s->state_machine->ua_session->acl_record; + bool deny_request = (acl_record == NULL); + if (acl_record && (acl_record->_method_mask != AclRecord::ALL_METHOD_MASK)) { + if (method != -1) { + deny_request = !acl_record->isMethodAllowed(method); + } else { + int method_str_len; + const char *method_str = s->hdr_info.client_request.method_get(&method_str_len); + deny_request = !acl_record->isNonstandardMethodAllowed(std::string(method_str, method_str_len)); + } + } + if (deny_request) { + if (is_debug_tag_set("ip-allow")) { + ip_text_buffer ipb; + Debug("ip-allow", "Quick filter denial on %s:%s with mask %x", ats_ip_ntop(&s->client_info.addr.sa, ipb, sizeof(ipb)), hdrtoken_index_to_wks(method), acl_record->_method_mask); + } + s->client_connection_enabled = false; } - s->client_connection_enabled = false; } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/remap/AclFiltering.cc ---------------------------------------------------------------------- diff --git a/proxy/http/remap/AclFiltering.cc b/proxy/http/remap/AclFiltering.cc index 105eeff..79d6954 100644 --- a/proxy/http/remap/AclFiltering.cc +++ b/proxy/http/remap/AclFiltering.cc @@ -24,6 +24,7 @@ #include "AclFiltering.h" #include "Main.h" #include "Error.h" +#include "HTTP.h" // =============================================================================== // acl_filter_rule @@ -36,11 +37,11 @@ acl_filter_rule::reset(void) for (i = (argc = 0); i < ACL_FILTER_MAX_ARGV; i++) { argv[i] = (char *)ats_free_null(argv[i]); } - for (i = (method_cnt = 0); i < ACL_FILTER_MAX_METHODS; i++) { - method_array[i] = 0; - method_idx[i] = 0; + method_restriction_enabled = false; + for (i = 0; i < HTTP_WKSIDX_METHODS_CNT; i++) { + standard_method_lookup[i] = false; } - method_valid = 0; + nonstandard_methods.clear(); for (i = (src_ip_cnt = 0); i < ACL_FILTER_MAX_SRC_IP; i++) { src_ip_array[i].reset(); } @@ -48,8 +49,9 @@ acl_filter_rule::reset(void) } acl_filter_rule::acl_filter_rule():next(NULL), filter_name_size(0), filter_name(NULL), allow_flag(1), -method_valid(0), src_ip_valid(0), active_queue_flag(0), argc(0) +src_ip_valid(0), active_queue_flag(0), argc(0) { + standard_method_lookup.resize(HTTP_WKSIDX_METHODS_CNT); ink_zero(argv); reset(); } @@ -91,12 +93,19 @@ acl_filter_rule::print(void) { int i; printf("-----------------------------------------------------------------------------------------\n"); - printf("Filter \"%s\" status: allow_flag=%d, method_valid=%d, src_ip_valid=%d, active_queue_flag=%d\n", - filter_name ? filter_name : "<NONAME>", (int) allow_flag, (int) method_valid, + printf("Filter \"%s\" status: allow_flag=%d, src_ip_valid=%d, active_queue_flag=%d\n", + filter_name ? filter_name : "<NONAME>", (int) allow_flag, (int) src_ip_valid, (int) active_queue_flag); - printf("method_cnt=%d %s", method_cnt, method_cnt > 0 ? ": " : ""); - for (i = 0; i < method_cnt; i++) - printf("0x%X ", method_array[i]); + printf("standard methods="); + for (i = 0; i < HTTP_WKSIDX_METHODS_CNT; i++) { + if (standard_method_lookup[i]) { + printf("0x%x ", HTTP_WKSIDX_CONNECT + i); + } + } + printf("nonstandard methods="); + for (MethodMap::iterator iter = nonstandard_methods.begin(), end = nonstandard_methods.end(); iter != end; ++iter) { + printf("%s ", iter->c_str()); + } printf("\n"); printf("src_ip_cnt=%d\n", src_ip_cnt); for (i = 0; i < src_ip_cnt; i++) { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/remap/AclFiltering.h ---------------------------------------------------------------------- diff --git a/proxy/http/remap/AclFiltering.h b/proxy/http/remap/AclFiltering.h index 4dd684a..a8d187a 100644 --- a/proxy/http/remap/AclFiltering.h +++ b/proxy/http/remap/AclFiltering.h @@ -27,10 +27,13 @@ #include "Main.h" //#include "YAddr.h" +#include <string> +#include <set> +#include <vector> + // =============================================================================== // ACL like filtering defs (per one remap rule) -static int const ACL_FILTER_MAX_METHODS = 16; static int const ACL_FILTER_MAX_SRC_IP = 128; static int const ACL_FILTER_MAX_ARGV = 512; @@ -64,7 +67,6 @@ public: int filter_name_size; // size of optional filter name char *filter_name; // optional filter name unsigned int allow_flag:1, // action allow deny - method_valid:1, // method valid for verification src_ip_valid:1, // src_ip range valid active_queue_flag:1; // filter is in active state (used by .useflt directive) @@ -72,10 +74,12 @@ public: int argc; // argument counter (only for filter defs) char *argv[ACL_FILTER_MAX_ARGV]; // argument strings (only for filter defs) - // method - int method_cnt; // how many valid methods we have - int method_array[ACL_FILTER_MAX_METHODS]; // any HTTP method (actually only WKSIDX from HTTP.cc) - int method_idx[ACL_FILTER_MAX_METHODS]; // HTTP method index (actually method flag) + // methods + bool method_restriction_enabled; + std::vector<bool> standard_method_lookup; + + typedef std::set<std::string> MethodMap; + MethodMap nonstandard_methods; // src_ip int src_ip_cnt; // how many valid src_ip rules we have http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/remap/RemapConfig.cc ---------------------------------------------------------------------- diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc index 0961da6..70fdbb7 100644 --- a/proxy/http/remap/RemapConfig.cc +++ b/proxy/http/remap/RemapConfig.cc @@ -390,18 +390,9 @@ remap_validate_filter_args(acl_filter_rule ** rule_pp, const char ** argv, int a } if (ul & REMAP_OPTFLG_METHOD) { /* "method=" option */ - if (rule->method_cnt >= ACL_FILTER_MAX_METHODS) { - Debug("url_rewrite", "[validate_filter_args] Too many \"method=\" filters"); - snprintf(errStrBuf, errStrBufSize, "Defined more than %d \"method=\" filters!", ACL_FILTER_MAX_METHODS); - errStrBuf[errStrBufSize - 1] = 0; - if (new_rule_flg) { - delete rule; - *rule_pp = NULL; - } - return (const char *) errStrBuf; - } // Please remember that the order of hash idx creation is very important and it is defined // in HTTP.cc file + m = -1; if (!strcasecmp(argptr, "CONNECT")) m = HTTP_WKSIDX_CONNECT; else if (!strcasecmp(argptr, "DELETE")) @@ -424,38 +415,14 @@ remap_validate_filter_args(acl_filter_rule ** rule_pp, const char ** argv, int a m = HTTP_WKSIDX_TRACE; else if (!strcasecmp(argptr, "PUSH")) m = HTTP_WKSIDX_PUSH; - else { - Debug("url_rewrite", "[validate_filter_args] Unknown method value %s", argptr); - snprintf(errStrBuf, errStrBufSize, "Unknown method \"%s\"", argptr); - errStrBuf[errStrBufSize - 1] = 0; - if (new_rule_flg) { - delete rule; - *rule_pp = NULL; - } - return (const char *) errStrBuf; - } - for (j = 0; j < rule->method_cnt; j++) { - if (rule->method_array[j] == m) { - m = 0; - break; /* we already have it in the list */ - } - } - if ((j = m) != 0) { - j = j - HTTP_WKSIDX_CONNECT; // get method index - if (j<0 || j>= ACL_FILTER_MAX_METHODS) { - Debug("url_rewrite", "[validate_filter_args] Incorrect method index! Method sequence in HTTP.cc is broken"); - snprintf(errStrBuf, errStrBufSize, "Incorrect method index %d", j); - errStrBuf[errStrBufSize - 1] = 0; - if (new_rule_flg) { - delete rule; - *rule_pp = NULL; - } - return (const char *) errStrBuf; - } - rule->method_idx[j] = m; - rule->method_array[rule->method_cnt++] = m; - rule->method_valid = 1; + if (m != -1) { + m = m - HTTP_WKSIDX_CONNECT; // get method index + rule->standard_method_lookup[m] = true; + } else { + Debug("url_rewrite", "[validate_filter_args] Using nonstandard method [%s]", argptr); + rule->nonstandard_methods.insert(argptr); } + rule->method_restriction_enabled = true; } else if (ul & REMAP_OPTFLG_SRC_IP) { /* "src_ip=" option */ if (rule->src_ip_cnt >= ACL_FILTER_MAX_SRC_IP) { Debug("url_rewrite", "[validate_filter_args] Too many \"src_ip=\" filters"); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0094d4b1/proxy/http/remap/UrlRewrite.cc ---------------------------------------------------------------------- diff --git a/proxy/http/remap/UrlRewrite.cc b/proxy/http/remap/UrlRewrite.cc index ab61b3b..549add6 100644 --- a/proxy/http/remap/UrlRewrite.cc +++ b/proxy/http/remap/UrlRewrite.cc @@ -425,18 +425,21 @@ UrlRewrite::PerformACLFiltering(HttpTransact::State *s, url_mapping *map) s->acl_filtering_performed = true; // small protection against reverse mapping if (map->filter) { - int i, res, method; - i = (method = s->hdr_info.client_request.method_get_wksidx()) - HTTP_WKSIDX_CONNECT; + int res; + int method = s->hdr_info.client_request.method_get_wksidx(); + int method_wksidx = (method != -1) ? (method - HTTP_WKSIDX_CONNECT) : -1; bool client_enabled_flag = true; ink_release_assert(ats_is_ip(&s->client_info.addr)); - for (acl_filter_rule * rp = map->filter; rp && client_enabled_flag; rp = rp->next) { // stop as soon as a filter denies + for (acl_filter_rule * rp = map->filter; rp; rp = rp->next) { bool match = true; - if (rp->method_valid) { - if (likely(i >= 0 && i < ACL_FILTER_MAX_METHODS)) { - match = rp->method_idx[i] == method; + if (rp->method_restriction_enabled) { + if (method_wksidx != -1) { + match = rp->standard_method_lookup[method_wksidx]; } - else { - match = false; + else if (!rp->nonstandard_methods.empty()) { + 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)); } } if (match && rp->src_ip_valid) { @@ -452,14 +455,18 @@ UrlRewrite::PerformACLFiltering(HttpTransact::State *s, url_mapping *map) } } } - if (match) { + if (match && client_enabled_flag) { //make sure that a previous filter did not DENY Debug("url_rewrite", "matched ACL filter rule, %s request", rp->allow_flag ? "allowing" : "denying"); client_enabled_flag = rp->allow_flag ? true : false; } else { - Debug("url_rewrite", "did NOT match ACL filter rule, %s request", rp->allow_flag ? "denying" : "allowing"); - client_enabled_flag = rp->allow_flag ? false : true; + if (!client_enabled_flag) { + Debug("url_rewrite", "Previous ACL filter rule denied request, continuing to deny it"); + } else { + Debug("url_rewrite", "did NOT match ACL filter rule, %s request", rp->allow_flag ? "denying" : "allowing"); + client_enabled_flag = rp->allow_flag ? false : true; + } } - + } /* end of for(rp = map->filter;rp;rp = rp->next) */ s->client_connection_enabled = client_enabled_flag; }
