From f51658dac41f48f47e76be3215b2bf38e625e4b0 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 23 Apr 2014 01:21:56 +0200 Subject: [PATCH] MEDIUM: config: relax use_backend check to make the condition optional Since it became possible to use log-format expressions in use_backend, having a mandatory condition becomes annoying because configurations are full of "if TRUE". Let's relax the check to accept no condition like many other keywords (eg: redirect). --- doc/configuration.txt | 6 +++--- src/cfgparse.c | 21 ++++++++------------- src/haproxy.c | 6 ++++-- src/session.c | 12 +++++++----- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 113818fa9..37321e3b6 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -7705,8 +7705,7 @@ unique-id-header See also: "unique-id-format" -use_backend if -use_backend unless +use_backend [{if | unless} ] Switch to a specific backend if/unless an ACL-based condition is matched. May be used in sections : defaults | frontend | listen | backend no | yes | yes | no @@ -7714,7 +7713,8 @@ use_backend unless is the name of a valid backend or "listen" section, or a "log-format" string resolving to a backend name. - is a condition composed of ACLs, as described in section 7. + is a condition composed of ACLs, as described in section 7. If + it is omitted, the rule is unconditionally applied. When doing content-switching, connections arrive on a frontend and are then dispatched to various backends depending on a number of conditions. The diff --git a/src/cfgparse.c b/src/cfgparse.c index d4893a134..53b136a36 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2866,22 +2866,17 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } - if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) { - Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n", - file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } + if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) { + if ((cond = build_acl_cond(file, linenum, curproxy, (const char **)args + 2, &errmsg)) == NULL) { + Alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n", + file, linenum, errmsg); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } - if ((cond = build_acl_cond(file, linenum, curproxy, (const char **)args + 2, &errmsg)) == NULL) { - Alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n", - file, linenum, errmsg); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; + err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum); } - err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum); - rule = (struct switching_rule *)calloc(1, sizeof(*rule)); rule->cond = cond; rule->be.name = strdup(args[1]); diff --git a/src/haproxy.c b/src/haproxy.c index 67798b408..ed2ff21e3 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1085,8 +1085,10 @@ void deinit(void) list_for_each_entry_safe(rule, ruleb, &p->switching_rules, list) { LIST_DEL(&rule->list); - prune_acl_cond(rule->cond); - free(rule->cond); + if (rule->cond) { + prune_acl_cond(rule->cond); + free(rule->cond); + } free(rule); } diff --git a/src/session.c b/src/session.c index b37348967..dc72ba52f 100644 --- a/src/session.c +++ b/src/session.c @@ -1238,12 +1238,14 @@ static int process_switching_rules(struct session *s, struct channel *req, int a struct switching_rule *rule; list_for_each_entry(rule, &s->fe->switching_rules, list) { - int ret; + int ret = 1; - ret = acl_exec_cond(rule->cond, s->fe, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL); - ret = acl_pass(ret); - if (rule->cond->pol == ACL_COND_UNLESS) - ret = !ret; + if (rule->cond) { + ret = acl_exec_cond(rule->cond, s->fe, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL); + ret = acl_pass(ret); + if (rule->cond->pol == ACL_COND_UNLESS) + ret = !ret; + } if (ret) { /* If the backend name is dynamic, try to resolve the name.