]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: vars: properly set the argument parsing context in the expression
authorWilly Tarreau <w@1wt.eu>
Thu, 2 Sep 2021 17:46:08 +0000 (19:46 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 2 Sep 2021 18:34:30 +0000 (20:34 +0200)
When the expression called in "set-var" uses argments that require late
resolution, the context must be set. At the moment, any unknown argument
is misleadingly reported as "ACL":

    frontend f
        bind :8080
        mode http
        http-request set-var(proc.a) be_conn(foo)

   parsing [b1.cfg:4]: unable to find backend 'foo' referenced in arg 1 \
   of ACL keyword 'be_conn' in proxy 'f'.

Once the context is properly set, it now says the truth:

   parsing [b1.cfg:8]: unable to find backend 'foo' referenced in arg 1 \
   of sample fetch keyword 'be_conn' in http-request expression in proxy 'f'.

This may be backported but is not really important. If so, the preceeding
patches "BUG/MINOR: vars: improve accuracy of the rules used to check
expression validity" and "MINOR: sample: add missing ARGC_ entries" must
be backported as well.

src/vars.c

index 6fa894b9a2f1165c3e2a00f145d3afd545a0c913..156eb943cb34958b6562ed88f0c7e075b2610ba7 100644 (file)
@@ -774,35 +774,38 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
 
        kw_name = args[*arg-1];
 
-       rule->arg.vars.expr = sample_parse_expr((char **)args, arg, px->conf.args.file,
-                                               px->conf.args.line, err, &px->conf.args, NULL);
-       if (!rule->arg.vars.expr)
-               return ACT_RET_PRS_ERR;
-
        switch (rule->from) {
        case ACT_F_TCP_REQ_SES:
                flags = SMP_VAL_FE_SES_ACC;
+               px->conf.args.ctx = ARGC_TSE;
                break;
        case ACT_F_TCP_REQ_CNT:
                flags = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_REQ_CNT : SMP_VAL_BE_REQ_CNT;
+               px->conf.args.ctx = ARGC_TRQ;
                break;
        case ACT_F_TCP_RES_CNT:
                flags = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_RES_CNT : SMP_VAL_BE_RES_CNT;
+               px->conf.args.ctx = ARGC_TRS;
                break;
        case ACT_F_HTTP_REQ:
                flags = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR;
+               px->conf.args.ctx = ARGC_HRQ;
                break;
        case ACT_F_HTTP_RES:
                flags = (px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR;
+               px->conf.args.ctx =  ARGC_HRS;
                break;
        case ACT_F_TCP_CHK:
                flags = SMP_VAL_BE_CHK_RUL;
+               px->conf.args.ctx = ARGC_TCK;
                break;
        case ACT_F_CFG_PARSER:
                flags = SMP_VAL_CFG_PARSER;
+               px->conf.args.ctx = ARGC_CFG;
                break;
        case ACT_F_CLI_PARSER:
                flags = SMP_VAL_CLI_PARSER;
+               px->conf.args.ctx = ARGC_CLI;
                break;
        default:
                memprintf(err,
@@ -810,6 +813,12 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
                          rule->from);
                return ACT_RET_PRS_ERR;
        }
+
+       rule->arg.vars.expr = sample_parse_expr((char **)args, arg, px->conf.args.file,
+                                               px->conf.args.line, err, &px->conf.args, NULL);
+       if (!rule->arg.vars.expr)
+               return ACT_RET_PRS_ERR;
+
        if (!(rule->arg.vars.expr->fetch->val & flags)) {
                memprintf(err,
                          "fetch method '%s' extracts information from '%s', none of which is available here",