mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-27 07:02:11 +00:00
MINOR: proxy/checks: Register a keyword to parse http-check rules
The keyword 'http-check' is now parsed in a dedicated callback function. Thus the code to parse these rules is now located in checks.c.
This commit is contained in:
parent
430e480510
commit
51b129fd0f
@ -2547,178 +2547,6 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "http-check")) {
|
||||
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
|
||||
err_code |= ERR_WARN;
|
||||
|
||||
if (strcmp(args[1], "disable-on-404") == 0) {
|
||||
/* enable a graceful server shutdown on an HTTP 404 response */
|
||||
curproxy->options |= PR_O_DISABLE404;
|
||||
if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
}
|
||||
else if (strcmp(args[1], "send-state") == 0) {
|
||||
/* enable emission of the apparent state of a server in HTTP checks */
|
||||
curproxy->options2 |= PR_O2_CHK_SNDST;
|
||||
if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
}
|
||||
else if (strcmp(args[1], "send") == 0) {
|
||||
int cur_arg = 2;
|
||||
|
||||
free(curproxy->check_hdrs);
|
||||
free(curproxy->check_body);
|
||||
curproxy->check_hdrs = curproxy->check_body = NULL;
|
||||
curproxy->check_hdrs_len = curproxy->check_body_len = 0;
|
||||
while (*(args[cur_arg])) {
|
||||
if (strcmp(args[cur_arg], "hdr") == 0) {
|
||||
int hdr_len;
|
||||
if (!*(args[cur_arg+1]) || !*(args[cur_arg+2])) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s expects a name and a value as parameter.\n",
|
||||
file, linenum, args[0], args[1], args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cur_arg++;
|
||||
hdr_len = strlen(args[cur_arg]) + strlen(args[cur_arg+1]) + 4;
|
||||
curproxy->check_hdrs = my_realloc2(curproxy->check_hdrs, curproxy->check_hdrs_len+hdr_len+1);
|
||||
if (curproxy->check_hdrs == NULL) {
|
||||
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
snprintf(curproxy->check_hdrs + curproxy->check_hdrs_len, hdr_len+1, "%s: %s\r\n", args[cur_arg], args[cur_arg+1]);
|
||||
curproxy->check_hdrs_len += hdr_len;
|
||||
|
||||
cur_arg++;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "body") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s expects a string as parameter.\n",
|
||||
file, linenum, args[0], args[1], args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
cur_arg++;
|
||||
free(curproxy->check_body);
|
||||
curproxy->check_body = strdup(args[cur_arg]);
|
||||
curproxy->check_body_len = strlen(args[cur_arg]);
|
||||
if (curproxy->check_body == NULL) {
|
||||
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' only supports 'hdr' and 'body', found '%s'.\n",
|
||||
file, linenum, args[0], args[1], args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
}
|
||||
else if (strcmp(args[1], "expect") == 0) {
|
||||
const char *ptr_arg;
|
||||
int cur_arg;
|
||||
|
||||
if (curproxy->options2 & PR_O2_EXP_TYPE) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cur_arg = 2;
|
||||
/* consider exclamation marks, sole or at the beginning of a word */
|
||||
while (*(ptr_arg = args[cur_arg])) {
|
||||
while (*ptr_arg == '!') {
|
||||
curproxy->options2 ^= PR_O2_EXP_INV;
|
||||
ptr_arg++;
|
||||
}
|
||||
if (*ptr_arg)
|
||||
break;
|
||||
cur_arg++;
|
||||
}
|
||||
/* now ptr_arg points to the beginning of a word past any possible
|
||||
* exclamation mark, and cur_arg is the argument which holds this word.
|
||||
*/
|
||||
if (strcmp(ptr_arg, "status") == 0) {
|
||||
if (!*(args[cur_arg + 1])) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
curproxy->options2 |= PR_O2_EXP_STS;
|
||||
free(curproxy->expect_str);
|
||||
curproxy->expect_str = strdup(args[cur_arg + 1]);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "string") == 0) {
|
||||
if (!*(args[cur_arg + 1])) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
curproxy->options2 |= PR_O2_EXP_STR;
|
||||
free(curproxy->expect_str);
|
||||
curproxy->expect_str = strdup(args[cur_arg + 1]);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstatus") == 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);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
curproxy->options2 |= PR_O2_EXP_RSTS;
|
||||
free(curproxy->expect_str);
|
||||
regex_free(curproxy->expect_regex);
|
||||
curproxy->expect_str = strdup(args[cur_arg + 1]);
|
||||
error = NULL;
|
||||
if (!(curproxy->expect_regex = regex_comp(args[cur_arg + 1], 1, 1, &error))) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' : regular expression '%s': %s.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
|
||||
free(error);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstring") == 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);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
curproxy->options2 |= PR_O2_EXP_RSTR;
|
||||
free(curproxy->expect_str);
|
||||
regex_free(curproxy->expect_regex);
|
||||
curproxy->expect_str = strdup(args[cur_arg + 1]);
|
||||
error = NULL;
|
||||
if (!(curproxy->expect_regex = regex_comp(args[cur_arg + 1], 1, 1, &error))) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s %s' : regular expression '%s': %s.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
|
||||
free(error);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
|
||||
file, linenum, args[0], args[1], ptr_arg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : '%s' only supports 'disable-on-404', 'send-state', 'expect'.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "monitor")) {
|
||||
if (curproxy == &defproxy) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
|
172
src/checks.c
172
src/checks.c
@ -5096,6 +5096,175 @@ static int proxy_parse_tcpcheck(char **args, int section, struct proxy *curpx,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parses the "http-check" proxy keyword */
|
||||
static int proxy_parse_httpcheck(char **args, int section, struct proxy *curpx,
|
||||
struct proxy *defpx, const char *file, int line,
|
||||
char **errmsg)
|
||||
{
|
||||
int cur_arg, ret = 0;
|
||||
|
||||
if (warnifnotcap(curpx, PR_CAP_BE, file, line, args[0], NULL))
|
||||
ret = 1;
|
||||
|
||||
cur_arg = 1;
|
||||
if (strcmp(args[cur_arg], "disable-on-404") == 0) {
|
||||
/* enable a graceful server shutdown on an HTTP 404 response */
|
||||
curpx->options |= PR_O_DISABLE404;
|
||||
if (too_many_args(1, args, errmsg, NULL))
|
||||
goto error;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "send-state") == 0) {
|
||||
/* enable emission of the apparent state of a server in HTTP checks */
|
||||
curpx->options2 |= PR_O2_CHK_SNDST;
|
||||
if (too_many_args(1, args, errmsg, NULL))
|
||||
goto error;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "send") == 0) {
|
||||
free(curpx->check_hdrs);
|
||||
free(curpx->check_body);
|
||||
curpx->check_hdrs = curpx->check_body = NULL;
|
||||
curpx->check_hdrs_len = curpx->check_body_len = 0;
|
||||
|
||||
cur_arg++;
|
||||
while (*(args[cur_arg])) {
|
||||
if (strcmp(args[cur_arg], "hdr") == 0) {
|
||||
int hdr_len;
|
||||
if (!*(args[cur_arg+1]) || !*(args[cur_arg+2])) {
|
||||
memprintf(errmsg, "'%s %s' : %s expects a name and a value as parameter.",
|
||||
args[0], args[1], args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
cur_arg++;
|
||||
hdr_len = strlen(args[cur_arg]) + strlen(args[cur_arg+1]) + 4;
|
||||
curpx->check_hdrs = my_realloc2(curpx->check_hdrs, curpx->check_hdrs_len+hdr_len+1);
|
||||
if (curpx->check_hdrs == NULL) {
|
||||
memprintf(errmsg, "out of memory.");
|
||||
goto error;
|
||||
}
|
||||
snprintf(curpx->check_hdrs + curpx->check_hdrs_len, hdr_len+1, "%s: %s\r\n", args[cur_arg], args[cur_arg+1]);
|
||||
curpx->check_hdrs_len += hdr_len;
|
||||
|
||||
cur_arg++;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "body") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s %s' : %s expects a string as parameter.",
|
||||
args[0], args[1], args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
free(curpx->check_body);
|
||||
curpx->check_body = strdup(args[cur_arg]);
|
||||
curpx->check_body_len = strlen(args[cur_arg]);
|
||||
if (curpx->check_body == NULL) {
|
||||
memprintf(errmsg, "out of memory.");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memprintf(errmsg, "'%s %s' only supports 'hdr' and 'body', found '%s'.",
|
||||
args[0], args[1], args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "expect") == 0) {
|
||||
const char *ptr_arg;
|
||||
|
||||
if (curpx->options2 & PR_O2_EXP_TYPE) {
|
||||
memprintf(errmsg, "'%s %s' already specified.", args[0], args[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
cur_arg++;
|
||||
|
||||
/* consider exclamation marks, sole or at the beginning of a word */
|
||||
while (*(ptr_arg = args[cur_arg])) {
|
||||
while (*ptr_arg == '!') {
|
||||
curpx->options2 ^= PR_O2_EXP_INV;
|
||||
ptr_arg++;
|
||||
}
|
||||
if (*ptr_arg)
|
||||
break;
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
/* now ptr_arg points to the beginning of a word past any possible
|
||||
* exclamation mark, and cur_arg is the argument which holds this word.
|
||||
*/
|
||||
if (strcmp(ptr_arg, "status") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s %s %s' expects <string> as an argument.",
|
||||
args[0], args[1], ptr_arg);
|
||||
goto error;
|
||||
}
|
||||
curpx->options2 |= PR_O2_EXP_STS;
|
||||
free(curpx->expect_str);
|
||||
curpx->expect_str = strdup(args[cur_arg+1]);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "string") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s %s %s' expects <string> as an argument.",
|
||||
args[0], args[1], ptr_arg);
|
||||
goto error;
|
||||
}
|
||||
curpx->options2 |= PR_O2_EXP_STR;
|
||||
free(curpx->expect_str);
|
||||
curpx->expect_str = strdup(args[cur_arg+1]);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstatus") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s %s %s' expects <regex> as an argument.",
|
||||
args[0], args[1], ptr_arg);
|
||||
goto error;
|
||||
}
|
||||
curpx->options2 |= PR_O2_EXP_RSTS;
|
||||
free(curpx->expect_str);
|
||||
regex_free(curpx->expect_regex);
|
||||
curpx->expect_str = strdup(args[cur_arg+1]);
|
||||
if (!(curpx->expect_regex = regex_comp(args[cur_arg+1], 1, 1, errmsg))) {
|
||||
memprintf(errmsg, "'%s %s %s' : regular expression '%s': %s.",
|
||||
args[0], args[1], ptr_arg, args[cur_arg+1], *errmsg);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstring") == 0) {
|
||||
if (!*(args[cur_arg+1])) {
|
||||
memprintf(errmsg, "'%s %s %s' expects <regex> as an argument.",
|
||||
args[0], args[1], ptr_arg);
|
||||
goto error;
|
||||
}
|
||||
curpx->options2 |= PR_O2_EXP_RSTR;
|
||||
free(curpx->expect_str);
|
||||
regex_free(curpx->expect_regex);
|
||||
curpx->expect_str = strdup(args[cur_arg+1]);
|
||||
if (!(curpx->expect_regex = regex_comp(args[cur_arg+1], 1, 1, errmsg))) {
|
||||
memprintf(errmsg, "'%s %s %s' : regular expression '%s': %s.",
|
||||
args[0], args[1], ptr_arg, args[cur_arg + 1], *errmsg);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memprintf(errmsg, "'%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.",
|
||||
args[0], args[1], ptr_arg);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memprintf(errmsg, "'%s' only supports 'disable-on-404', 'send', 'send-state' and 'expect'. but got '%s'.",
|
||||
args[0], args[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = (*errmsg != NULL); /* Handle warning */
|
||||
return ret;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static struct tcpcheck_ruleset *tcpcheck_ruleset_lookup(const char *name)
|
||||
{
|
||||
@ -6701,7 +6870,8 @@ static int srv_parse_check_port(char **args, int *cur_arg, struct proxy *curpx,
|
||||
}
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_LISTEN, "tcp-check", proxy_parse_tcpcheck },
|
||||
{ CFG_LISTEN, "tcp-check", proxy_parse_tcpcheck },
|
||||
{ CFG_LISTEN, "http-check", proxy_parse_httpcheck },
|
||||
{ 0, NULL, NULL },
|
||||
}};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user