BUG/MEDIUM: sample: Cumulate frontend and backend sample validity flags
When the sample validity flags are computed to check if a sample is used in
a valid scope, the flags depending on the proxy capabilities must be
cumulated. Historically, for a sample on the request, only the frontend
capability was used to set the sample validity flags while for a sample on
the response only the backend was used. But it is a problem for listen or
defaults proxies. For those proxies, all frontend and backend samples should
be valid. However, at many place, only frontend ones are possible.
For instance, it is impossible to set the backend name (be_name) into a
variable from a listen proxy.
This bug exists on all stable versions. Thus this patch should probably be
backported. But with some caution because the code has probably changed
serveral times. Note that nobody has ever noticed this issue. So the need to
backport this patch must be evaluated for each branch.
(cherry picked from commit 7a06ffb854281a08dae8dc2c13669a3a43da1065)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index 5b49433..8fd067a 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -1190,6 +1190,7 @@
}
else if (strcmp(args[0], "http-request") == 0) { /* request access control: allow/deny/auth */
struct act_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1213,14 +1214,18 @@
}
err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
- err_code |= warnif_cond_conflicts(rule->cond,
- (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
- file, linenum);
+
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRQ_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRQ_HDR;
+ err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum);
LIST_APPEND(&curproxy->http_req_rules, &rule->list);
}
else if (strcmp(args[0], "http-response") == 0) { /* response access control */
struct act_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1243,14 +1248,17 @@
goto out;
}
- err_code |= warnif_cond_conflicts(rule->cond,
- (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
- file, linenum);
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRS_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRS_HDR;
+ err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum);
LIST_APPEND(&curproxy->http_res_rules, &rule->list);
}
else if (strcmp(args[0], "http-after-response") == 0) {
struct act_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1273,9 +1281,11 @@
goto out;
}
- err_code |= warnif_cond_conflicts(rule->cond,
- (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
- file, linenum);
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRS_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRS_HDR;
+ err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum);
LIST_APPEND(&curproxy->http_after_res_rules, &rule->list);
}
@@ -1307,6 +1317,7 @@
}
else if (strcmp(args[0], "redirect") == 0) {
struct redirect_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1323,9 +1334,12 @@
LIST_APPEND(&curproxy->redirect_rules, &rule->list);
err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
- err_code |= warnif_cond_conflicts(rule->cond,
- (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
- file, linenum);
+
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRQ_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRQ_HDR;
+ err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum);
}
else if (strcmp(args[0], "use_backend") == 0) {
struct switching_rule *rule;
@@ -1666,6 +1680,7 @@
goto stats_error_parsing;
} else if (strcmp(args[1], "admin") == 0) {
struct stats_admin_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d]: '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
@@ -1689,9 +1704,11 @@
goto out;
}
- err_code |= warnif_cond_conflicts(cond,
- (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
- file, linenum);
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRQ_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRQ_HDR;
+ err_code |= warnif_cond_conflicts(cond, where, file, linenum);
rule = calloc(1, sizeof(*rule));
if (!rule) {
@@ -1742,6 +1759,7 @@
goto alloc_error;
} else if (strcmp(args[1], "http-request") == 0) { /* request access control: allow/deny/auth */
struct act_rule *rule;
+ int where = 0;
if (curproxy->cap & PR_CAP_DEF) {
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
@@ -1766,9 +1784,11 @@
goto out;
}
- err_code |= warnif_cond_conflicts(rule->cond,
- (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
- file, linenum);
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRQ_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRQ_HDR;
+ err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum);
LIST_APPEND(&curproxy->uri_auth->http_req_rules, &rule->list);
} else if (strcmp(args[1], "auth") == 0) {
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 2e36b3b..5423ada 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3361,15 +3361,18 @@
}
if (curproxy->conf.uniqueid_format_string) {
+ int where = 0;
+
curproxy->conf.args.ctx = ARGC_UIF;
curproxy->conf.args.file = curproxy->conf.uif_file;
curproxy->conf.args.line = curproxy->conf.uif_line;
err = NULL;
+ if (curproxy->cap & PR_CAP_FE)
+ where |= SMP_VAL_FE_HRQ_HDR;
+ if (curproxy->cap & PR_CAP_BE)
+ where |= SMP_VAL_BE_HRQ_HDR;
if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id,
- LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES,
- (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR
- : SMP_VAL_BE_HRQ_HDR,
- &err)) {
+ LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES, where, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
curproxy->conf.uif_file, curproxy->conf.uif_line, err);
free(err);
diff --git a/src/http_act.c b/src/http_act.c
index 0aa8a37..12a9a9f 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -154,6 +154,7 @@
struct act_rule *rule, char **err)
{
int cur_arg = *orig_arg;
+ int cap = 0;
switch (args[0][4]) {
case 'm' :
@@ -186,8 +187,11 @@
LIST_INIT(&rule->arg.http.fmt);
px->conf.args.ctx = ARGC_HRQ;
- if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP,
- (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, err)) {
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRQ_HDR;
+ if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
return ACT_RET_PRS_ERR;
}
@@ -576,6 +580,7 @@
struct act_rule *rule, char **err)
{
int cur_arg = *orig_arg;
+ int cap = 0;
char *error = NULL;
switch (args[0][8]) {
@@ -610,8 +615,11 @@
LIST_INIT(&rule->arg.http.fmt);
px->conf.args.ctx = ARGC_HRQ;
- if (!parse_logformat_string(args[cur_arg + 1], px, &rule->arg.http.fmt, LOG_OPT_HTTP,
- (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, err)) {
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRQ_HDR;
+ if (!parse_logformat_string(args[cur_arg + 1], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
regex_free(rule->arg.http.re);
return ACT_RET_PRS_ERR;
}
@@ -1583,7 +1591,7 @@
static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{
- int cap, cur_arg;
+ int cap = 0, cur_arg;
if (args[*orig_arg-1][0] == 'e') {
rule->action = ACT_CUSTOM;
@@ -1611,11 +1619,17 @@
if (rule->from == ACT_F_HTTP_REQ) {
px->conf.args.ctx = ARGC_HRQ;
- cap = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRQ_HDR;
}
else{
px->conf.args.ctx = ARGC_HRS;
- cap = (px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRS_HDR;
}
cur_arg++;
@@ -1693,7 +1707,7 @@
static enum act_parse_ret parse_http_replace_header(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{
- int cap, cur_arg;
+ int cap = 0, cur_arg;
if (args[*orig_arg-1][8] == 'h')
rule->action = 0; // replace-header
@@ -1720,11 +1734,17 @@
if (rule->from == ACT_F_HTTP_REQ) {
px->conf.args.ctx = ARGC_HRQ;
- cap = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRQ_HDR;
}
else{
px->conf.args.ctx = ARGC_HRS;
- cap = (px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRS_HDR;
}
cur_arg++;
@@ -2003,7 +2023,7 @@
static enum act_parse_ret parse_http_set_map(const char **args, int *orig_arg, struct proxy *px,
struct act_rule *rule, char **err)
{
- int cap, cur_arg;
+ int cap = 0, cur_arg;
if (args[*orig_arg-1][0] == 'a') // add-acl
rule->action = 0;
@@ -2040,11 +2060,17 @@
if (rule->from == ACT_F_HTTP_REQ) {
px->conf.args.ctx = ARGC_HRQ;
- cap = (px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRQ_HDR;
}
else{
px->conf.args.ctx = ARGC_HRS;
- cap = (px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_FE)
+ cap |= SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_BE)
+ cap |= SMP_VAL_BE_HRS_HDR;
}
/* key pattern */
diff --git a/src/http_htx.c b/src/http_htx.c
index bb1d5a4..37ef28a 100644
--- a/src/http_htx.c
+++ b/src/http_htx.c
@@ -1386,7 +1386,7 @@
struct stat stat;
const char *act_arg = NULL;
char *obj = NULL;
- int cur_arg, cap, objlen = 0, fd = -1;
+ int cur_arg, cap = 0, objlen = 0, fd = -1;
reply = calloc(1, sizeof(*reply));
@@ -1400,10 +1400,12 @@
if (px->conf.args.ctx == ARGC_HERR)
cap = (SMP_VAL_REQUEST | SMP_VAL_RESPONSE);
- else
- cap = ((px->conf.args.ctx == ARGC_HRQ)
- ? ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR)
- : ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR));
+ else {
+ if (px->cap & PR_CAP_FE)
+ cap |= ((px->conf.args.ctx == ARGC_HRQ) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_FE_HRS_HDR);
+ if (px->cap & PR_CAP_BE)
+ cap |= ((px->conf.args.ctx == ARGC_HRQ) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_BE_HRS_HDR);
+ }
cur_arg = *orig_arg;
while (*args[cur_arg]) {
diff --git a/src/http_rules.c b/src/http_rules.c
index 6ad1e9c..1b21133 100644
--- a/src/http_rules.c
+++ b/src/http_rules.c
@@ -422,17 +422,19 @@
}
else {
/* log-format based redirect rule */
+ int cap = 0;
/* Parse destination. Note that in the REDIRECT_TYPE_PREFIX case,
* if prefix == "/", we don't want to add anything, otherwise it
* makes it hard for the user to configure a self-redirection.
*/
curproxy->conf.args.ctx = ARGC_RDR;
+ if (curproxy->cap & PR_CAP_FE)
+ cap |= (dir ? SMP_VAL_FE_HRS_HDR : SMP_VAL_FE_HRQ_HDR);
+ if (curproxy->cap & PR_CAP_BE)
+ cap |= (dir ? SMP_VAL_BE_HRS_HDR : SMP_VAL_BE_HRQ_HDR);
if (!(type == REDIRECT_TYPE_PREFIX && destination[0] == '/' && destination[1] == '\0')) {
- if (!parse_logformat_string(destination, curproxy, &rule->rdr_fmt, LOG_OPT_HTTP,
- dir ? (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRS_HDR : SMP_VAL_BE_HRS_HDR
- : (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
- errmsg)) {
+ if (!parse_logformat_string(destination, curproxy, &rule->rdr_fmt, LOG_OPT_HTTP, cap, errmsg)) {
return NULL;
}
free(curproxy->conf.lfs_file);
diff --git a/src/vars.c b/src/vars.c
index 130e98b..bfa04c3 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -734,7 +734,7 @@
const char *var_name = args[*arg-1];
int var_len;
const char *kw_name;
- int flags, set_var = 0;
+ int flags = 0, set_var = 0;
if (strncmp(var_name, "set-var", 7) == 0) {
var_name += 7;
@@ -780,19 +780,31 @@
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;
+ if (px->cap & PR_CAP_FE)
+ flags |= SMP_VAL_FE_REQ_CNT;
+ if (px->cap & PR_CAP_BE)
+ flags |= 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;
+ if (px->cap & PR_CAP_FE)
+ flags |= SMP_VAL_FE_RES_CNT;
+ if (px->cap & PR_CAP_BE)
+ flags |= 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;
+ if (px->cap & PR_CAP_FE)
+ flags |= SMP_VAL_FE_HRQ_HDR;
+ if (px->cap & PR_CAP_BE)
+ flags |= 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;
+ if (px->cap & PR_CAP_FE)
+ flags |= SMP_VAL_FE_HRS_HDR;
+ if (px->cap & PR_CAP_BE)
+ flags |= SMP_VAL_BE_HRS_HDR;
px->conf.args.ctx = ARGC_HRS;
break;
case ACT_F_TCP_CHK: