diff --git a/include/haproxy/action-t.h b/include/haproxy/action-t.h index 45d2bd144..4c919e841 100644 --- a/include/haproxy/action-t.h +++ b/include/haproxy/action-t.h @@ -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; diff --git a/src/vars.c b/src/vars.c index 6fb39ccf6..1ab81197e 100644 --- a/src/vars.c +++ b/src/vars.c @@ -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() - * set-var() + * set-var-fmt([, ...]) + * set-var([, ...]) * unset-var() * * It returns ACT_RET_PRS_ERR if fails and 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;