]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: acl: support using sample fetches directly in ACLs
authorWilly Tarreau <w@1wt.eu>
Sun, 31 Mar 2013 21:14:46 +0000 (23:14 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 3 Apr 2013 00:13:02 +0000 (02:13 +0200)
Now it becomes possible to directly use sample fetches as the ACL fetch
methods. In this case, the matching method is mandatory. This allows to
form more ACL combinations from existing fetches and will limit the need
for new ACLs when everything is available to form them from sample fetches
and matches.

doc/configuration.txt
src/acl.c

index da287f37f88266b25c7b8dda94a7c36ac6861fcd..0b14d0ef0a6bcf534698f592ff229296b2d074a3 100644 (file)
@@ -8288,6 +8288,14 @@ following situations :
 7.5. Available matching criteria
 --------------------------------
 
+A number of predefined criteria may be used to form ACL expressions. The ones
+that are ACL-specific are detailed here. In addition to these ones, all sample
+fetch methods described in section 7.8 may be used. However, with these last
+ones, no default pattern matching method is defined, so it is mandatory to pass
+"-m" followed by a method. When a same keyword exists in both forms, the ACL
+compatible form prevails.
+
+
 7.5.1. Matching at Layer 4 and below
 ------------------------------------
 
index 50772733f3be7f3395b20a83817b17c39b3c94d5..4a53072024e16e79f2b310bf332e2d988290e1ab 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -1037,11 +1037,24 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
        struct acl_pattern *pattern;
        int opaque, patflags;
        const char *arg;
+       struct sample_fetch *smp = NULL;
 
+       /* First, we lookd for an ACL keyword. And if we don't find one, then
+        * we look for a sample fetch keyword.
+        */
        aclkw = find_acl_kw(args[0]);
        if (!aclkw || !aclkw->parse) {
-               memprintf(err, "unknown ACL keyword '%s'", *args);
-               goto out_return;
+               const char *kwend;
+
+               kwend = strchr(args[0], '(');
+               if (!kwend)
+                       kwend = args[0] + strlen(args[0]);
+               smp = find_sample_fetch(args[0], kwend - args[0]);
+
+               if (!smp) {
+                       memprintf(err, "unknown ACL or sample keyword '%s'", *args);
+                       goto out_return;
+               }
        }
 
        expr = (struct acl_expr *)calloc(1, sizeof(*expr));
@@ -1050,13 +1063,13 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
                goto out_return;
        }
 
-       expr->kw = aclkw->kw;
+       expr->kw = aclkw ? aclkw->kw : smp->kw;
        LIST_INIT(&expr->patterns);
        expr->pattern_tree = EB_ROOT_UNIQUE;
-       expr->parse = aclkw->parse;
-       expr->match = aclkw->match;
+       expr->parse = aclkw ? aclkw->parse : NULL;
+       expr->match = aclkw ? aclkw->match : NULL;
        expr->args = empty_arg_list;
-       expr->smp = aclkw->smp;
+       expr->smp = aclkw ? aclkw->smp : smp;
 
        arg = strchr(args[0], '(');
        if (expr->smp->arg_mask) {
@@ -1146,6 +1159,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
                if ((*args)[1] == 'i')
                        patflags |= ACL_PAT_F_IGNORE_CASE;
                else if ((*args)[1] == 'f') {
+                       if (!expr->parse) {
+                               memprintf(err, "matching method must be specified first (using '-m') when using a sample fetch ('%s')", expr->kw);
+                               goto out_free_expr;
+                       }
+
                        if (!acl_read_patterns_from_file(expr, args[1], patflags | ACL_PAT_F_FROM_FILE, err))
                                goto out_free_expr;
                        args++;
@@ -1198,6 +1216,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
                args++;
        }
 
+       if (!expr->parse) {
+               memprintf(err, "matching method must be specified first (using '-m') when using a sample fetch ('%s')", expr->kw);
+               goto out_free_expr;
+       }
+
        /* now parse all patterns */
        opaque = 0;
        while (**args) {