]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] acl: permit fetch() functions to set the result themselves
authorWilly Tarreau <w@1wt.eu>
Sun, 20 Jul 2008 08:13:37 +0000 (10:13 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 20 Jul 2008 08:17:20 +0000 (10:17 +0200)
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.

include/types/acl.h
src/acl.c

index 51acfe743edd714f98eedd68f4a74b8338b5e612..ddd59cec0e794d232a0897ab0e7413acf7314eb4 100644 (file)
@@ -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 */
index 983c0c5585b9fa396943b365699055652da6bbdc..e755990f8ec9c03cdc89a14890c06350abb4c07e 100644 (file)
--- 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