[MEDIUM] http: add support for conditional request header addition

Now the reqadd rules also support ACLs. All req* rules are converted
now.
This commit is contained in:
Willy Tarreau 2010-01-31 14:30:44 +01:00
parent 97ec969077
commit 8abd4cd526
3 changed files with 36 additions and 2 deletions

View File

@ -3578,7 +3578,7 @@ redispatch (deprecated)
See also : "option redispatch"
reqadd <string>
reqadd <string> [{if | unless} <cond>]
Add a header at the end of the HTTP request
May be used in sections : defaults | frontend | listen | backend
no | yes | yes | yes
@ -3587,6 +3587,9 @@ reqadd <string>
must be escaped using a backslash ('\'). Please refer to section
6 about HTTP header manipulation for more information.
<cond> is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.
A new line consisting in <string> followed by a line feed will be added after
the last header of an HTTP request.
@ -3594,7 +3597,12 @@ reqadd <string>
and not to traffic generated by HAProxy, such as health-checks or error
responses.
See also: "rspadd" and section 6 about HTTP header manipulation
Example : add "X-Proto: SSL" to requests coming via port 81
acl is-ssl dst_port 81
reqadd X-Proto:\ SSL if is-ssl
See also: "rspadd", section 6 about HTTP header manipulation, and section 7
about ACLs.
reqallow <search> [{if | unless} <cond>]

View File

@ -3738,7 +3738,24 @@ 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)) {
if ((cond = build_acl_cond(file, linenum, curproxy, (const char **)args+2)) == NULL) {
Alert("parsing [%s:%d] : error detected while parsing a '%s' condition.\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
err_code |= warnif_cond_requires_resp(cond, file, linenum);
}
else if (*args[2]) {
Alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
file, linenum, args[0], args[2]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
wl = calloc(1, sizeof(*wl));
wl->cond = cond;
wl->s = strdup(args[1]);
LIST_ADDQ(&curproxy->req_add, &wl->list);
warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);

View File

@ -2851,6 +2851,15 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
/* add request headers from the rule sets in the same order */
list_for_each_entry(wl, &px->req_add, list) {
if (wl->cond) {
int ret = acl_exec_cond(wl->cond, px, s, txn, ACL_DIR_REQ);
ret = acl_pass(ret);
if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
ret = !ret;
if (!ret)
continue;
}
if (unlikely(http_header_add_tail(req, &txn->req, &txn->hdr_idx, wl->s) < 0))
goto return_bad_req;
}