From bb6bc95b1eb22b7239d4d75016fda8210bd5d492 Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Thu, 16 Dec 2021 17:14:38 +0100 Subject: [PATCH] MINOR: vars: Parse optional conditions passed to the set-var actions 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 | 1 + src/vars.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) 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;