From dc6cf224dde9dc2de9d693bff968a478c216ad7f Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Mon, 12 Jan 2026 14:47:51 +0100 Subject: [PATCH] MINOR: proxy: refactor mode parsing Define a new utility function str_to_proxy_mode() which is able to convert a string into the corresponding proxy mode if possible. This new function is used for the parsing of "mode" configuration proxy keyword. This patch will be reused for dynamic backend implementation, in order to parse a similar "mode" argument via a CLI handler. --- include/haproxy/proxy.h | 1 + src/cfgparse-listen.c | 19 +++++++++++++------ src/proxy.c | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 089ab9e22..57dbbd9ff 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -59,6 +59,7 @@ void deinit_proxy(struct proxy *p); void free_proxy(struct proxy *p); const char *proxy_cap_str(int cap); const char *proxy_mode_str(int mode); +enum pr_mode str_to_proxy_mode(const char *mode); const char *proxy_find_best_option(const char *word, const char **extra); uint proxy_get_next_id(uint from); void proxy_store_name(struct proxy *px); diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 68b2eba88..3c27a638e 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -633,23 +633,30 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } else if (strcmp(args[0], "mode") == 0) { /* sets the proxy mode */ + enum pr_mode mode; if (alertif_too_many_args(1, file, linenum, args, &err_code)) goto out; - if (strcmp(args[1], "http") == 0) curproxy->mode = PR_MODE_HTTP; - else if (strcmp(args[1], "tcp") == 0) curproxy->mode = PR_MODE_TCP; - else if (strcmp(args[1], "log") == 0 && (curproxy->cap & PR_CAP_BE)) curproxy->mode = PR_MODE_SYSLOG; - else if (strcmp(args[1], "spop") == 0 && (curproxy->cap & PR_CAP_BE)) curproxy->mode = PR_MODE_SPOP; - else if (strcmp(args[1], "health") == 0) { + if (unlikely(strcmp(args[1], "health") == 0)) { ha_alert("parsing [%s:%d] : 'mode health' doesn't exist anymore. Please use 'http-request return status 200' instead.\n", file, linenum); err_code |= ERR_ALERT | ERR_FATAL; goto out; } - else { + + mode = str_to_proxy_mode(args[1]); + if (!mode) { ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]); err_code |= ERR_ALERT | ERR_FATAL; goto out; } + else if ((mode == PR_MODE_SYSLOG || mode == PR_MODE_SPOP) && + !(curproxy->cap & PR_CAP_BE)) { + ha_alert("parsing [%s:%d] : mode %s is only applicable on proxies with backend capability.\n", file, linenum, proxy_mode_str(mode)); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + curproxy->mode = mode; } else if (strcmp(args[0], "id") == 0) { struct proxy *conflict; diff --git a/src/proxy.c b/src/proxy.c index fc65f3c06..207f85a98 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -501,6 +501,21 @@ const char *proxy_mode_str(int mode) { return "unknown"; } +/* Convert string into proxy mode type. PR_MODES is returned for unknown values. */ +enum pr_mode str_to_proxy_mode(const char *mode) +{ + if (strcmp(mode, "http") == 0) + return PR_MODE_HTTP; + else if (strcmp(mode, "tcp") == 0) + return PR_MODE_TCP; + else if (strcmp(mode, "log") == 0) + return PR_MODE_SYSLOG; + else if (strcmp(mode, "spop") == 0) + return PR_MODE_SPOP; + + return PR_MODES; +} + /* try to find among known options the one that looks closest to by * counting transitions between letters, digits and other characters. Will * return the best matching word if found, otherwise NULL. An optional array -- 2.47.3