mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: checks: add rbinary expect match type
The rbinary match works similarly to the rstring match type, however the received data is rewritten as hex-string before the match operation is done. This allows using regexes on binary content even with the POSIX regex engine. [Cf: I slightly updated the patch. mem2hex function was removed and dump_binary is used instead.]
This commit is contained in:
parent
21f3695126
commit
efab6c61d9
@ -9865,8 +9865,8 @@ tcp-check expect [min-recv <int>] [!] <match> <pattern>
|
||||
the evaluation result is always conclusive.
|
||||
|
||||
<match> is a keyword indicating how to look for a specific pattern in the
|
||||
response. The keyword may be one of "string", "rstring" or
|
||||
binary.
|
||||
response. The keyword may be one of "string", "rstring", "binary" or
|
||||
"rbinary".
|
||||
The keyword may be preceded by an exclamation mark ("!") to negate
|
||||
the match. Spaces are allowed between the exclamation mark and the
|
||||
keyword. See below for more details on the supported keywords.
|
||||
@ -9904,6 +9904,15 @@ tcp-check expect [min-recv <int>] [!] <match> <pattern>
|
||||
this exact hexadecimal string.
|
||||
Purpose is to match data on binary protocols.
|
||||
|
||||
rbinary <regex> : test a regular expression on the response buffer, like
|
||||
"rstring". However, the response buffer is transformed
|
||||
into its hexadecimal form, including NUL-bytes. This
|
||||
allows using all regex engines to match any binary
|
||||
content. The hexadecimal transformation takes twice the
|
||||
size of the original response. As such, the expected
|
||||
pattern should work on at-most half the response buffer
|
||||
size.
|
||||
|
||||
It is important to note that the responses will be limited to a certain size
|
||||
defined by the global "tune.chksize" option, which defaults to 16384 bytes.
|
||||
Thus, too large responses may not contain the mandatory pattern when using
|
||||
|
@ -215,6 +215,7 @@ enum tcpcheck_expect_type {
|
||||
TCPCHK_EXPECT_UNDEF = 0, /* Match is not used. */
|
||||
TCPCHK_EXPECT_STRING, /* Matches a string. */
|
||||
TCPCHK_EXPECT_REGEX, /* Matches a regular pattern. */
|
||||
TCPCHK_EXPECT_REGEX_BINARY, /* Matches a regular pattern on a hex-encoded text. */
|
||||
TCPCHK_EXPECT_BINARY, /* Matches a binary sequence. */
|
||||
};
|
||||
|
||||
|
@ -3282,7 +3282,8 @@ stats_error_parsing:
|
||||
expect->string = strdup(args[cur_arg + 1]);
|
||||
expect->length = strlen(expect->string);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstring") == 0) {
|
||||
else if (strcmp(ptr_arg, "rstring") == 0 ||
|
||||
strcmp(ptr_arg, "rbinary") == 0) {
|
||||
if (!*(args[cur_arg + 1])) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg);
|
||||
@ -3290,8 +3291,7 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
|
||||
expect->type = TCPCHK_EXPECT_REGEX;
|
||||
|
||||
expect->type = ((strcmp(ptr_arg, "rbinary") == 0) ? TCPCHK_EXPECT_REGEX_BINARY : TCPCHK_EXPECT_REGEX);
|
||||
error = NULL;
|
||||
if (!(expect->regex = regex_comp(args[cur_arg + 1], 1, 1, &error))) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' : regular expression '%s': %s.\n",
|
||||
@ -3302,7 +3302,7 @@ stats_error_parsing:
|
||||
}
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
|
||||
ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', 'rbinary', found '%s'.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
|
19
src/checks.c
19
src/checks.c
@ -652,6 +652,9 @@ static void chk_report_conn_err(struct check *check, int errno_bck, int expired)
|
||||
case TCPCHK_EXPECT_REGEX:
|
||||
chunk_appendf(chk, " (expect regex)");
|
||||
break;
|
||||
case TCPCHK_EXPECT_REGEX_BINARY:
|
||||
chunk_appendf(chk, " (expect binary regex)");
|
||||
break;
|
||||
case TCPCHK_EXPECT_UNDEF:
|
||||
chunk_appendf(chk, " (undefined expect!)");
|
||||
break;
|
||||
@ -2775,7 +2778,6 @@ static char * tcpcheck_get_step_comment(struct check *check, int stepid)
|
||||
*/
|
||||
static int tcpcheck_main(struct check *check)
|
||||
{
|
||||
char *comment;
|
||||
struct tcpcheck_rule *next;
|
||||
int done = 0, ret = 0, step = 0;
|
||||
struct conn_stream *cs = check->cs;
|
||||
@ -2784,6 +2786,7 @@ static int tcpcheck_main(struct check *check)
|
||||
struct proxy *proxy = check->proxy;
|
||||
struct task *t = check->task;
|
||||
struct list *head = check->tcpcheck_rules;
|
||||
char *comment;
|
||||
int retcode = 0;
|
||||
|
||||
/* here, we know that the check is complete or that it failed */
|
||||
@ -3064,8 +3067,7 @@ static int tcpcheck_main(struct check *check)
|
||||
check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (&check->current_step->list != head &&
|
||||
check->current_step->action == TCPCHK_ACT_COMMENT)
|
||||
while (&check->current_step->list != head && check->current_step->action == TCPCHK_ACT_COMMENT)
|
||||
check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
|
||||
|
||||
if (&check->current_step->list == head)
|
||||
@ -3189,6 +3191,12 @@ static int tcpcheck_main(struct check *check)
|
||||
case TCPCHK_EXPECT_REGEX:
|
||||
match = regex_exec2(expect->regex, b_head(&check->bi), MIN(b_data(&check->bi), b_size(&check->bi)-1));
|
||||
break;
|
||||
|
||||
case TCPCHK_EXPECT_REGEX_BINARY:
|
||||
chunk_reset(&trash);
|
||||
dump_binary(&trash, b_head(&check->bi), b_data(&check->bi));
|
||||
match = regex_exec2(expect->regex, b_head(&trash), MIN(b_data(&trash), b_size(&trash)-1));
|
||||
break;
|
||||
case TCPCHK_EXPECT_UNDEF:
|
||||
/* Should never happen. */
|
||||
retcode = -1;
|
||||
@ -3239,6 +3247,10 @@ static int tcpcheck_main(struct check *check)
|
||||
chunk_printf(&trash, "TCPCHK %s (regex) at step %d",
|
||||
diag, step);
|
||||
break;
|
||||
case TCPCHK_EXPECT_REGEX_BINARY:
|
||||
chunk_printf(&trash, "TCPCHK %s (binary regex) at step %d",
|
||||
diag, step);
|
||||
break;
|
||||
case TCPCHK_EXPECT_UNDEF:
|
||||
/* Should never happen. */
|
||||
retcode = -1;
|
||||
@ -3356,6 +3368,7 @@ void email_alert_free(struct email_alert *alert)
|
||||
free(rule->expect.string);
|
||||
break;
|
||||
case TCPCHK_EXPECT_REGEX:
|
||||
case TCPCHK_EXPECT_REGEX_BINARY:
|
||||
regex_free(rule->expect.regex);
|
||||
break;
|
||||
case TCPCHK_EXPECT_UNDEF:
|
||||
|
Loading…
x
Reference in New Issue
Block a user