mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: checks: Simplify matching on HTTP headers in HTTP expect rules
Extra parameters on http-check expect rules, for the header matching method, to use log-format string or to match full header line have been removed. There is now separate matching methods to match a full header line or to match each comma-separated values. "http-check expect fhdr" must be used in the first case, and "http-check expect hdr" in the second one. In addition, to match log-format header name or value, "-lf" suffix must be added to "name" or "value" keyword. For intance: http-check expect hdr name "set-cookie" value-lf -m beg "sessid=%[var(check.cookie)]" Thanks to this changes, each parameter may only be interpreted in one way.
This commit is contained in:
parent
b50b3e6d0a
commit
b5594265d2
@ -4560,8 +4560,8 @@ http-check expect [min-recv <int>] [comment <msg>]
|
|||||||
log-format string.
|
log-format string.
|
||||||
|
|
||||||
<match> is a keyword indicating how to look for a specific pattern in the
|
<match> is a keyword indicating how to look for a specific pattern in the
|
||||||
response. The keyword may be one of "status", "rstatus",
|
response. The keyword may be one of "status", "rstatus", "hdr",
|
||||||
"string", or "rstring". The keyword may be preceded by an
|
"fhdr", "string", or "rstring". The keyword may be preceded by an
|
||||||
exclamation mark ("!") to negate the match. Spaces are allowed
|
exclamation mark ("!") to negate the match. Spaces are allowed
|
||||||
between the exclamation mark and the keyword. See below for more
|
between the exclamation mark and the keyword. See below for more
|
||||||
details on the supported keywords.
|
details on the supported keywords.
|
||||||
@ -4592,8 +4592,8 @@ http-check expect [min-recv <int>] [comment <msg>]
|
|||||||
will be considered invalid if the status code matches.
|
will be considered invalid if the status code matches.
|
||||||
This is mostly used to check for multiple codes.
|
This is mostly used to check for multiple codes.
|
||||||
|
|
||||||
header name [ -m <meth> ] <name> [log-format]
|
hdr { name | name-lf } [ -m <meth> ] <name>
|
||||||
[ value [ -m <meth> ] <value> [log-format] [full] ] :
|
[ { value | value-lf } [ -m <meth> ] <value> :
|
||||||
test the specified header pattern on the HTTP response
|
test the specified header pattern on the HTTP response
|
||||||
headers. The name pattern is mandatory but the value
|
headers. The name pattern is mandatory but the value
|
||||||
pattern is optional. If not specified, only the header
|
pattern is optional. If not specified, only the header
|
||||||
@ -4602,14 +4602,20 @@ http-check expect [min-recv <int>] [comment <msg>]
|
|||||||
matching methods are "str" (exact match), "beg" (prefix
|
matching methods are "str" (exact match), "beg" (prefix
|
||||||
match), "end" (suffix match), "sub" (substring match) or
|
match), "end" (suffix match), "sub" (substring match) or
|
||||||
"reg" (regex match). If not specified, exact matching
|
"reg" (regex match). If not specified, exact matching
|
||||||
method is used. If the "log-format" option is used, the
|
method is used. If the "name-lf" parameter is used,
|
||||||
pattern (<name> or <value>) is evaluated as a log-format
|
<name> is evaluated as a log-format string. If "value-lf"
|
||||||
string. This option cannot be used with the regex
|
parameter is used, <value> is evaluated as a log-format
|
||||||
matching method. Finally, by default, the header value is
|
string. These parameters cannot be used with the regex
|
||||||
considered as comma-separated list. Each part may be
|
matching method. Finally, the header value is considered
|
||||||
tested. The "full" option may be used to test the full
|
as comma-separated list. Note that matchings are case
|
||||||
header line. Note that matchings are case insensitive on
|
insensitive on the header names.
|
||||||
the header names.
|
|
||||||
|
fhdr { name | name-lf } [ -m <meth> ] <name>
|
||||||
|
[ { value | value-lf } [ -m <meth> ] <value> :
|
||||||
|
test the specified full header pattern on the HTTP
|
||||||
|
response headers. It does exactly the same than "hdr"
|
||||||
|
keyword, except the full header value is tested, commas
|
||||||
|
are not considered as delimiters.
|
||||||
|
|
||||||
string <string> : test the exact string match in the HTTP response body.
|
string <string> : test the exact string match in the HTTP response body.
|
||||||
A health check response will be considered valid if the
|
A health check response will be considered valid if the
|
||||||
|
@ -39,26 +39,26 @@ haproxy h1 -conf {
|
|||||||
option httpchk
|
option httpchk
|
||||||
http-check expect status 200-399
|
http-check expect status 200-399
|
||||||
|
|
||||||
http-check expect header name "x-test1"
|
http-check expect hdr name "x-test1"
|
||||||
http-check expect header name -m str "X-Test2"
|
http-check expect hdr name -m str "X-Test2"
|
||||||
http-check expect header name -m beg "X-Begin-"
|
http-check expect hdr name -m beg "X-Begin-"
|
||||||
http-check expect header name -m end "-End"
|
http-check expect hdr name -m end "-End"
|
||||||
http-check expect header name -m sub "-Sub-"
|
http-check expect hdr name -m sub "-Sub-"
|
||||||
http-check expect header name -m reg "^[a-z]+-Reg-[a-z]+[0-9]\$"
|
http-check expect hdr name -m reg "^[a-z]+-Reg-[a-z]+[0-9]\$"
|
||||||
http-check set-var(check.hdr_name) res.fhdr(x-hdr-name)
|
http-check set-var(check.hdr_name) res.fhdr(x-hdr-name)
|
||||||
http-check expect header name -m str "%[var(check.hdr_name)]" log-format
|
http-check expect hdr name-lf -m str "%[var(check.hdr_name)]"
|
||||||
http-check expect header name -m str "%[res.fhdr(x-hdr-name)]" log-format
|
http-check expect hdr name-lf -m str "%[res.fhdr(x-hdr-name)]"
|
||||||
|
|
||||||
http-check expect header name "x-test1" value "true, next value" full
|
http-check expect fhdr name "x-test1" value "true, next value"
|
||||||
http-check expect header name "x-test2" value -m str "true"
|
http-check expect hdr name "x-test2" value -m str "true"
|
||||||
http-check expect header name -m beg "x-test" value -m beg "begin-"
|
http-check expect hdr name -m beg "x-test" value -m beg "begin-"
|
||||||
http-check expect header name -m beg "x-test" value -m end "-end"
|
http-check expect hdr name -m beg "x-test" value -m end "-end"
|
||||||
http-check expect header name -m beg "x-test" value -m sub "-sub-"
|
http-check expect hdr name -m beg "x-test" value -m sub "-sub-"
|
||||||
http-check expect header name -m beg "x-test" value -m reg "^value-reg-[A-Z0-9]+\$"
|
http-check expect hdr name -m beg "x-test" value -m reg "^value-reg-[A-Z0-9]+\$"
|
||||||
http-check expect header name -m beg "x-test" value -m reg "value-reg-[A-Z0-9]+" full
|
http-check expect fhdr name -m beg "x-test" value -m reg "value-reg-[A-Z0-9]+"
|
||||||
http-check set-var(check.hdr_value) str(x-test1)
|
http-check set-var(check.hdr_value) str(x-test1)
|
||||||
http-check expect header name -m beg "x-" value -m str "%[var(check.hdr_value)]" log-format
|
http-check expect hdr name -m beg "x-" value-lf -m str "%[var(check.hdr_value)]"
|
||||||
http-check expect header name -m beg "x-" value -m str "%[res.fhdr(x-hdr-name)]" log-format full
|
http-check expect fhdr name -m beg "x-" value-lf -m str "%[res.fhdr(x-hdr-name)]"
|
||||||
|
|
||||||
server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
|
server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
|
||||||
} -start
|
} -start
|
||||||
|
77
src/checks.c
77
src/checks.c
@ -4319,7 +4319,7 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
}
|
}
|
||||||
type = TCPCHK_EXPECT_CUSTOM;
|
type = TCPCHK_EXPECT_CUSTOM;
|
||||||
}
|
}
|
||||||
else if (strcmp(args[cur_arg], "header") == 0) {
|
else if (strcmp(args[cur_arg], "hdr") == 0 || strcmp(args[cur_arg], "fhdr") == 0) {
|
||||||
int orig_arg = cur_arg;
|
int orig_arg = cur_arg;
|
||||||
|
|
||||||
if (proto != TCPCHK_RULES_HTTP_CHK)
|
if (proto != TCPCHK_RULES_HTTP_CHK)
|
||||||
@ -4330,12 +4330,20 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
}
|
}
|
||||||
type = TCPCHK_EXPECT_HTTP_HEADER;
|
type = TCPCHK_EXPECT_HTTP_HEADER;
|
||||||
|
|
||||||
|
if (strcmp(args[cur_arg], "fhdr") == 0)
|
||||||
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_FULL;
|
||||||
|
|
||||||
/* Parse the name pattern, mandatory */
|
/* Parse the name pattern, mandatory */
|
||||||
if (!*(args[cur_arg+1]) || !*(args[cur_arg+2]) || strcmp(args[cur_arg+1], "name") != 0) {
|
if (!*(args[cur_arg+1]) || !*(args[cur_arg+2]) ||
|
||||||
memprintf(errmsg, "'%s' expects at the keyword name as first argument followed by a pattern",
|
(strcmp(args[cur_arg+1], "name") != 0 && strcmp(args[cur_arg+1], "name-lf") != 0)) {
|
||||||
|
memprintf(errmsg, "'%s' expects at the name keyword as first argument followed by a pattern",
|
||||||
args[orig_arg]);
|
args[orig_arg]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(args[cur_arg+1], "name-lf") == 0)
|
||||||
|
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_FMT;
|
||||||
|
|
||||||
cur_arg += 2;
|
cur_arg += 2;
|
||||||
if (strcmp(args[cur_arg], "-m") == 0) {
|
if (strcmp(args[cur_arg], "-m") == 0) {
|
||||||
if (!*(args[cur_arg+1])) {
|
if (!*(args[cur_arg+1])) {
|
||||||
@ -4351,8 +4359,14 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_END;
|
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_END;
|
||||||
else if (strcmp(args[cur_arg+1], "sub") == 0)
|
else if (strcmp(args[cur_arg+1], "sub") == 0)
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_SUB;
|
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_SUB;
|
||||||
else if (strcmp(args[cur_arg+1], "reg") == 0)
|
else if (strcmp(args[cur_arg+1], "reg") == 0) {
|
||||||
|
if (flags & TCPCHK_EXPT_FL_HTTP_HNAME_FMT) {
|
||||||
|
memprintf(errmsg, "'%s': log-format string is not supported with a regex matching method",
|
||||||
|
args[orig_arg]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_REG;
|
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_REG;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
memprintf(errmsg, "'%s' : '%s' only supports 'str', 'beg', 'end', 'sub' or 'reg' (got '%s')",
|
memprintf(errmsg, "'%s' : '%s' only supports 'str', 'beg', 'end', 'sub' or 'reg' (got '%s')",
|
||||||
args[orig_arg], args[cur_arg], args[cur_arg+1]);
|
args[orig_arg], args[cur_arg], args[cur_arg+1]);
|
||||||
@ -4364,29 +4378,17 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_STR;
|
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_STR;
|
||||||
npat = args[cur_arg];
|
npat = args[cur_arg];
|
||||||
|
|
||||||
if (!(*args[cur_arg+1])) {
|
if (!*(args[cur_arg+1]) ||
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_NONE;
|
(strcmp(args[cur_arg+1], "value") != 0 && strcmp(args[cur_arg+1], "value-lf") != 0)) {
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(args[cur_arg+1], "log-format") == 0) {
|
|
||||||
if (flags & TCPCHK_EXPT_FL_HTTP_HNAME_REG) {
|
|
||||||
memprintf(errmsg, "'%s': '%s' cannot be used with a regex matching pattern",
|
|
||||||
args[orig_arg], args[cur_arg+1]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HNAME_FMT;
|
|
||||||
cur_arg++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*args[cur_arg+1]) || strcmp(args[cur_arg+1], "value") != 0) {
|
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_NONE;
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_NONE;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
if (strcmp(args[cur_arg+1], "value-lf") == 0)
|
||||||
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_FMT;
|
||||||
|
|
||||||
/* Parse the value pattern, optionnal */
|
/* Parse the value pattern, optionnal */
|
||||||
cur_arg += 2;
|
if (strcmp(args[cur_arg+2], "-m") == 0) {
|
||||||
if (strcmp(args[cur_arg], "-m") == 0) {
|
cur_arg += 2;
|
||||||
if (!*(args[cur_arg+1])) {
|
if (!*(args[cur_arg+1])) {
|
||||||
memprintf(errmsg, "'%s' : '%s' expects at a matching pattern ('str', 'beg', 'end', 'sub' or 'reg')",
|
memprintf(errmsg, "'%s' : '%s' expects at a matching pattern ('str', 'beg', 'end', 'sub' or 'reg')",
|
||||||
args[orig_arg], args[cur_arg]);
|
args[orig_arg], args[cur_arg]);
|
||||||
@ -4400,34 +4402,29 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_END;
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_END;
|
||||||
else if (strcmp(args[cur_arg+1], "sub") == 0)
|
else if (strcmp(args[cur_arg+1], "sub") == 0)
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_SUB;
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_SUB;
|
||||||
else if (strcmp(args[cur_arg+1], "reg") == 0)
|
else if (strcmp(args[cur_arg+1], "reg") == 0) {
|
||||||
|
if (flags & TCPCHK_EXPT_FL_HTTP_HVAL_FMT) {
|
||||||
|
memprintf(errmsg, "'%s': log-format string is not supported with a regex matching method",
|
||||||
|
args[orig_arg]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_REG;
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_REG;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
memprintf(errmsg, "'%s' : '%s' only supports 'str', 'beg', 'end', 'sub' or 'reg' (got '%s')",
|
memprintf(errmsg, "'%s' : '%s' only supports 'str', 'beg', 'end', 'sub' or 'reg' (got '%s')",
|
||||||
args[orig_arg], args[cur_arg], args[cur_arg+1]);
|
args[orig_arg], args[cur_arg], args[cur_arg+1]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
cur_arg += 2;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_STR;
|
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_STR;
|
||||||
vpat = args[cur_arg];
|
|
||||||
|
|
||||||
while (*args[cur_arg+1]) {
|
if (!*(args[cur_arg+2])) {
|
||||||
if (strcmp(args[cur_arg+1], "log-format") == 0) {
|
memprintf(errmsg, "'%s' expect a pattern with the value keyword", args[orig_arg]);
|
||||||
if (flags & TCPCHK_EXPT_FL_HTTP_HVAL_REG) {
|
goto error;
|
||||||
memprintf(errmsg, "'%s': '%s' cannot be used with a regex matching pattern",
|
|
||||||
args[orig_arg], args[cur_arg+1]);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_FMT;
|
|
||||||
}
|
|
||||||
else if (strcmp(args[cur_arg+1], "full") == 0)
|
|
||||||
flags |= TCPCHK_EXPT_FL_HTTP_HVAL_FULL;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
cur_arg++;
|
|
||||||
}
|
}
|
||||||
|
vpat = args[cur_arg+2];
|
||||||
|
cur_arg += 2;
|
||||||
}
|
}
|
||||||
else if (strcmp(args[cur_arg], "comment") == 0) {
|
else if (strcmp(args[cur_arg], "comment") == 0) {
|
||||||
if (in_pattern) {
|
if (in_pattern) {
|
||||||
@ -4574,7 +4571,7 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
if (proto == TCPCHK_RULES_HTTP_CHK) {
|
if (proto == TCPCHK_RULES_HTTP_CHK) {
|
||||||
bad_http_kw:
|
bad_http_kw:
|
||||||
memprintf(errmsg, "'only supports min-recv, [!]string', '[!]rstring', '[!]string-lf', '[!]status', "
|
memprintf(errmsg, "'only supports min-recv, [!]string', '[!]rstring', '[!]string-lf', '[!]status', "
|
||||||
"'[!]rstatus', [!]header or comment but got '%s' as argument.", args[cur_arg]);
|
"'[!]rstatus', [!]hdr, [!]fhdr or comment but got '%s' as argument.", args[cur_arg]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bad_tcp_kw:
|
bad_tcp_kw:
|
||||||
|
Loading…
Reference in New Issue
Block a user