]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: vars: Parse optional conditions passed to the set-var actions
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 16 Dec 2021 16:14:38 +0000 (17:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 16 Dec 2021 16:31:57 +0000 (17:31 +0100)
This patch adds the parsing of the optional condition parameters that
can be passed to the set-var and set-var-fmt actions (http as well as
tcp). Those conditions will not be taken into account yet in the var_set
function so conditions passed as parameters will not have any effect.
Since actions do not benefit from the parameter preparsing that
converters have, parsing conditions needed to be done by hand.

include/haproxy/action-t.h
src/vars.c

index 45d2bd144b2b7a067f99bf97bbccba7107a422f6..4c919e841c015aa6da7995bffae041a4bab2c666 100644 (file)
@@ -170,6 +170,7 @@ struct act_rule {
                        struct sample_expr *expr;
                        uint64_t name_hash;
                        enum vars_scope scope;
+                       uint conditions;            /* Bitfield of the conditions passed to this set-var call */
                } vars;
                struct {
                        int sc;
index 6fb39ccf6862c96a0e3599140e88005495003c91..1ab81197e1a45e0b214773ec699571edad62aa48 100644 (file)
@@ -840,8 +840,8 @@ static int conv_check_var(struct arg *args, struct sample_conv *conv,
 /* This function is a common parser for using variables. It understands
  * the format:
  *
- *   set-var-fmt(<variable-name>) <format-string>
- *   set-var(<variable-name>) <expression>
+ *   set-var-fmt(<variable-name>[,<cond> ...]) <format-string>
+ *   set-var(<variable-name>[,<cond> ...]) <expression>
  *   unset-var(<variable-name>)
  *
  * It returns ACT_RET_PRS_ERR if fails and <err> is filled with an error
@@ -857,6 +857,9 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
        const char *kw_name;
        int flags = 0, set_var = 0; /* 0=unset-var, 1=set-var, 2=set-var-fmt */
        struct sample empty_smp = { };
+       struct ist condition = IST_NULL;
+       struct ist var = IST_NULL;
+       struct ist varname_ist = IST_NULL;
 
        if (strncmp(var_name, "set-var-fmt", 11) == 0) {
                var_name += 11;
@@ -885,6 +888,28 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
                return ACT_RET_PRS_ERR;
        }
 
+       /* Parse the optional conditions. */
+       var = ist2(var_name, var_len);
+       varname_ist = istsplit(&var, ',');
+       var_len = istlen(varname_ist);
+
+       condition = istsplit(&var, ',');
+
+       if (istlen(condition) && set_var == 0) {
+               memprintf(err, "unset-var does not expect parameters after the variable name. Only \"set-var\" and \"set-var-fmt\" manage conditions");
+               return ACT_RET_PRS_ERR;
+       }
+
+       while (istlen(condition)) {
+               struct buffer cond = {};
+
+               chunk_initlen(&cond, istptr(condition), 0, istlen(condition));
+               if (vars_parse_cond_param(&cond, &rule->arg.vars.conditions, err) == 0)
+                       return ACT_RET_PRS_ERR;
+
+               condition = istsplit(&var, ',');
+       }
+
        LIST_INIT(&rule->arg.vars.fmt);
        if (!vars_hash_name(var_name, var_len, &rule->arg.vars.scope, &rule->arg.vars.name_hash, err))
                return ACT_RET_PRS_ERR;