]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cfgparse: suggest correct spelling for unknown words in proxy sections
authorWilly Tarreau <w@1wt.eu>
Fri, 12 Mar 2021 08:14:19 +0000 (09:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 12 Mar 2021 13:13:21 +0000 (14:13 +0100)
Let's start by the largest keyword list, the listeners. Many keywords were
still not part of a list, so a common_kw_list array was added to list the
not enumerated ones. Now for example, typing "tmout" properly suggests
"timeout":

  $ printf "frontend f\ntmout client 10s\n" | ./haproxy -c -f /dev/stdin
  [NOTICE] 070/091355 (22545) : haproxy version is 2.4-dev11-3b728a-21
  [NOTICE] 070/091355 (22545) : path to executable is ./haproxy
  [ALERT] 070/091355 (22545) : parsing [/dev/stdin:2] : unknown keyword 'tmout' in 'frontend' section; did you mean 'timeout' maybe ?
  [ALERT] 070/091355 (22545) : Error(s) found in configuration file : /dev/stdin
  [ALERT] 070/091355 (22545) : Fatal errors found in configuration.

src/cfgparse-listen.c

index 1a39c2f7501732d681c97d66716448891d9c85f1..b60741aed036939201591b7d391333ec95c290c4 100644 (file)
 #include <haproxy/tcpcheck.h>
 #include <haproxy/uri_auth.h>
 
+/* some keywords that are still being parsed using strcmp() and are not
+ * registered anywhere. They are used as suggestions for mistyped words.
+ */
+static const char *common_kw_list[] = {
+       "listen", "frontend", "backend", "defaults", "server",
+       "default-server", "server-template", "bind", "monitor-net",
+       "monitor-uri", "mode", "id", "description", "disabled", "enabled",
+       "bind-process", "acl", "dynamic-cookie-key", "cookie", "email-alert",
+       "persist", "appsession", "load-server-state-from-file",
+       "server-state-file-name", "max-session-srv-conns", "capture",
+       "retries", "http-request", "http-response", "http-after-response",
+       "http-send-name-header", "block", "redirect", "use_backend",
+       "use-server", "force-persist", "ignore-persist", "force-persist",
+       "stick-table", "stick", "stats", "option", "default_backend",
+       "http-reuse", "monitor", "transparent", "maxconn", "backlog",
+       "fullconn", "grace", "dispatch", "balance", "hash-type",
+       "hash-balance-factor", "unique-id-format", "unique-id-header",
+       "log-format", "log-format-sd", "log-tag", "log", "source", "usesrc",
+       NULL /* must be last */
+};
 
 /* Report a warning if a rule is placed after a 'tcp-request session' rule.
  * Return 1 if the warning has been emitted, otherwise 0.
@@ -2917,6 +2937,7 @@ stats_error_parsing:
        }
        else {
                struct cfg_kw_list *kwl;
+               const char *best;
                int index;
 
                list_for_each_entry(kwl, &cfg_keywords.list, list) {
@@ -2941,7 +2962,11 @@ stats_error_parsing:
                        }
                }
 
-               ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
+               best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_LISTEN, common_kw_list);
+               if (best)
+                       ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
+               else
+                       ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
                err_code |= ERR_ALERT | ERR_FATAL;
                goto out;
        }