From: Willy Tarreau Date: Sun, 20 Jul 2008 08:13:37 +0000 (+0200) Subject: [MEDIUM] acl: permit fetch() functions to set the result themselves X-Git-Tag: v1.3.16-rc1~226 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a79534fce11d94c94fb3aa186f0038fc7fc410bf;p=thirdparty%2Fhaproxy.git [MEDIUM] acl: permit fetch() functions to set the result themselves For protocol analysis, it's not always convenient to have to run through a fetch then a match against dummy values. It's easier to let the fetch() function set the result itself. This obviously works only for boolean values. --- diff --git a/include/types/acl.h b/include/types/acl.h index 51acfe743e..ddd59cec0e 100644 --- a/include/types/acl.h +++ b/include/types/acl.h @@ -80,6 +80,10 @@ enum { ACL_TEST_F_VOLATILE = (1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6), ACL_TEST_F_FETCH_MORE = 1 << 7, /* if test does not match, retry with next entry (for multi-match) */ ACL_TEST_F_MAY_CHANGE = 1 << 8, /* if test does not match, retry later (eg: request size) */ + ACL_TEST_F_RES_SET = 1 << 9, /* for fetch() function to assign the result without calling match() */ + ACL_TEST_F_RES_PASS = 1 << 10,/* with SET_RESULT, sets result to PASS (defaults to FAIL) */ + ACL_TEST_F_SET_RES_PASS = (ACL_TEST_F_RES_SET|ACL_TEST_F_RES_PASS), /* sets result to PASS */ + ACL_TEST_F_SET_RES_FAIL = (ACL_TEST_F_RES_SET), /* sets result to FAIL */ }; /* ACLs can be evaluated on requests and on responses, and on partial or complete data */ diff --git a/src/acl.c b/src/acl.c index 983c0c5585..e755990f8e 100644 --- a/src/acl.c +++ b/src/acl.c @@ -974,11 +974,19 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v continue; } - /* apply all tests to this value */ - list_for_each_entry(pattern, &expr->patterns, list) { - acl_res |= expr->kw->match(&test, pattern); - if (acl_res == ACL_PAT_PASS) - break; + if (test.flags & ACL_TEST_F_RES_SET) { + if (test.flags & ACL_TEST_F_RES_PASS) + acl_res |= ACL_PAT_PASS; + else + acl_res |= ACL_PAT_FAIL; + } + else { + /* call the match() function for all tests on this value */ + list_for_each_entry(pattern, &expr->patterns, list) { + acl_res |= expr->kw->match(&test, pattern); + if (acl_res == ACL_PAT_PASS) + break; + } } /* * OK now acl_res holds the result of this expression