BUG/MINOR: http_act: don't check capture id in backend

A wrong behavior was introduced by
e9544935e8, leading to preventing loading
any configuration where a capture slot id is used in a backend.
IE, the configuration below does not parse:

  frontend f
   bind *:80
   declare capture request len 32
   default_backend webserver

  backend webserver
   http-request capture req.hdr(Host) id 1

The point is that such type of configuration is valid and should run.

This patch enforces the check of capture slot id only if the action rule
is configured in a frontend.
The point is that at configuration parsing time, it is impossible to
check which frontend could point to this backend (furthermore if we use
dynamic backend name resolution at runtime).

The documentation has been updated to warn the user to ensure that
relevant frontends have required declaration when such rule has to be
used in a backend.
If no capture slot can be found, then the action will just not be
executed and HAProxy will process the next one in the list, as expected.

This should be backported to all supported branches (bug created as part
of a bug fix introduced into 1.7 and backported to 1.6).
This commit is contained in:
Baptiste Assmann 2020-01-16 14:34:22 +01:00 committed by Willy Tarreau
parent 2086365f51
commit 19a69b3740
2 changed files with 15 additions and 6 deletions

View File

@ -4391,9 +4391,12 @@ http-request capture <sample> [ len <length> | id <id> ]
If the keyword "id" is used instead of "len", the action tries to store the
captured string in a previously declared capture slot. This is useful to run
captures in backends. The slot id can be declared by a previous directive
"http-request capture" or with the "declare capture" keyword. If the slot
<id> doesn't exist, then HAProxy fails parsing the configuration to prevent
unexpected behavior at run time.
"http-request capture" or with the "declare capture" keyword.
When using this action in a backend, double check that the relevant
frontend(s) have the required capture slots otherwise, this rule will be
ignored at run time. This can't be detected at configuration parsing time
due to HAProxy's ability to dynamically resolve backend name at runtime.
http-request del-acl(<file-name>) <key fmt> [ { if | unless } <condition> ]
@ -5097,8 +5100,11 @@ http-response capture <sample> id <id> [ { if | unless } <condition> ]
This is useful to run captures in backends. The slot id can be declared by a
previous directive "http-response capture" or with the "declare capture"
keyword.
If the slot <id> doesn't exist, then HAProxy fails parsing the configuration
to prevent unexpected behavior at run time.
When using this action in a backend, double check that the relevant
frontend(s) have the required capture slots otherwise, this rule will be
ignored at run time. This can't be detected at configuration parsing time
due to HAProxy's ability to dynamically resolve backend name at runtime.
http-response del-acl(<file-name>) <key fmt> [ { if | unless } <condition> ]

View File

@ -494,7 +494,10 @@ static int check_http_req_capture(struct act_rule *rule, struct proxy *px, char
if (rule->action_ptr != http_action_req_capture_by_id)
return 1;
if (rule->arg.capid.idx >= px->nb_req_cap) {
/* capture slots can only be declared in frontends, so we can't check their
* existence in backends at configuration parsing step
*/
if (px->cap & PR_CAP_FE && rule->arg.capid.idx >= px->nb_req_cap) {
memprintf(err, "unable to find capture id '%d' referenced by http-request capture rule",
rule->arg.capid.idx);
return 0;