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.
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index eb175a1..7b33eb0 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -2547,178 +2547,6 @@
 			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]);
diff --git a/src/checks.c b/src/checks.c
index 240201b..ad72e08 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -5096,6 +5096,175 @@
 	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 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 },
 }};