You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2014/05/30 23:57:52 UTC
[2/6] git commit: [TS-1981] Adding arbitrary methods to url remap,
and fix the same problem in IpAllow
[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/5.0.x
Commit: 0094d4b11091bba7496b19445c380ccb2443cda0
Parents: 923269b
Author: Brian Geffon <br...@apache.org>
Authored: Fri May 30 13:42:17 2014 -0700
Committer: Brian Geffon <br...@apache.org>
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;
}