mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 00:57:02 +02:00
MINOR: cfgparse/bind: suggest correct spelling for unknown bind keywords
Just like with the server keywords, now's the turn of "bind" keywords. The difference is that 100% of the bind keywords are registered, thus we do not need the list of extra keywords. There are multiple bind line parsers today, all were updated: - peers - log - dgram-bind - cli $ printf "listen f\nbind :8000 tcut\n" | ./haproxy -c -f /dev/stdin [NOTICE] 070/101358 (25146) : haproxy version is 2.4-dev11-7b8787-26 [NOTICE] 070/101358 (25146) : path to executable is ./haproxy [ALERT] 070/101358 (25146) : parsing [/dev/stdin:2] : 'bind :8000' unknown keyword 'tcut'; did you mean 'tcp-ut' maybe ? [ALERT] 070/101358 (25146) : Error(s) found in configuration file : /dev/stdin [ALERT] 070/101358 (25146) : Fatal errors found in configuration.
This commit is contained in:
parent
49c2b45c1d
commit
433b05fa64
@ -167,6 +167,7 @@ struct bind_kw *bind_find_kw(const char *kw);
|
|||||||
|
|
||||||
/* Dumps all registered "bind" keywords to the <out> string pointer. */
|
/* Dumps all registered "bind" keywords to the <out> string pointer. */
|
||||||
void bind_dump_kws(char **out);
|
void bind_dump_kws(char **out);
|
||||||
|
const char *bind_find_best_kw(const char *word);
|
||||||
|
|
||||||
void bind_recount_thread_bits(struct bind_conf *conf);
|
void bind_recount_thread_bits(struct bind_conf *conf);
|
||||||
unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r);
|
unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r);
|
||||||
|
@ -389,9 +389,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
|
|
||||||
cur_arg = 2;
|
cur_arg = 2;
|
||||||
while (*(args[cur_arg])) {
|
while (*(args[cur_arg])) {
|
||||||
static int bind_dumped;
|
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
char *err;
|
const char *best;
|
||||||
|
|
||||||
kw = bind_find_kw(args[cur_arg]);
|
kw = bind_find_kw(args[cur_arg]);
|
||||||
if (kw) {
|
if (kw) {
|
||||||
@ -431,17 +430,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = NULL;
|
best = bind_find_best_kw(args[cur_arg]);
|
||||||
if (!bind_dumped) {
|
if (best)
|
||||||
bind_dump_kws(&err);
|
ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'; did you mean '%s' maybe ?\n",
|
||||||
indent_msg(&err, 4);
|
file, linenum, args[0], args[1], args[cur_arg], best);
|
||||||
bind_dumped = 1;
|
else
|
||||||
}
|
ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.\n",
|
||||||
|
file, linenum, args[0], args[1], args[cur_arg]);
|
||||||
ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
|
|
||||||
file, linenum, args[0], args[1], args[cur_arg],
|
|
||||||
err ? " Registered keywords :" : "", err ? err : "");
|
|
||||||
free(err);
|
|
||||||
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -609,7 +609,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
|||||||
|
|
||||||
if (strcmp(args[0], "bind") == 0 || strcmp(args[0], "default-bind") == 0) {
|
if (strcmp(args[0], "bind") == 0 || strcmp(args[0], "default-bind") == 0) {
|
||||||
int cur_arg;
|
int cur_arg;
|
||||||
static int kws_dumped;
|
|
||||||
struct bind_conf *bind_conf;
|
struct bind_conf *bind_conf;
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
|
|
||||||
@ -689,17 +688,13 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
|||||||
cur_arg += 1 + kw->skip;
|
cur_arg += 1 + kw->skip;
|
||||||
}
|
}
|
||||||
if (*args[cur_arg] != 0) {
|
if (*args[cur_arg] != 0) {
|
||||||
char *kws = NULL;
|
const char *best = bind_find_best_kw(args[cur_arg]);
|
||||||
|
if (best)
|
||||||
if (!kws_dumped) {
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n",
|
||||||
kws_dumped = 1;
|
file, linenum, args[cur_arg], cursection, best);
|
||||||
bind_dump_kws(&kws);
|
else
|
||||||
indent_msg(&kws, 4);
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.\n",
|
||||||
}
|
file, linenum, args[cur_arg], cursection);
|
||||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
|
|
||||||
file, linenum, args[cur_arg], cursection,
|
|
||||||
kws ? " Registered keywords :" : "", kws ? kws: "");
|
|
||||||
free(kws);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
36
src/cli.c
36
src/cli.c
@ -290,8 +290,8 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
|
|||||||
|
|
||||||
cur_arg = 3;
|
cur_arg = 3;
|
||||||
while (*args[cur_arg]) {
|
while (*args[cur_arg]) {
|
||||||
static int bind_dumped;
|
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
|
const char *best;
|
||||||
|
|
||||||
kw = bind_find_kw(args[cur_arg]);
|
kw = bind_find_kw(args[cur_arg]);
|
||||||
if (kw) {
|
if (kw) {
|
||||||
@ -314,15 +314,13 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bind_dumped) {
|
best = bind_find_best_kw(args[cur_arg]);
|
||||||
bind_dump_kws(err);
|
if (best)
|
||||||
indent_msg(err, 4);
|
memprintf(err, "'%s %s' : unknown keyword '%s'. Did you mean '%s' maybe ?",
|
||||||
bind_dumped = 1;
|
args[0], args[1], args[cur_arg], best);
|
||||||
}
|
else
|
||||||
|
memprintf(err, "'%s %s' : unknown keyword '%s'.",
|
||||||
memprintf(err, "'%s %s' : unknown keyword '%s'.%s%s",
|
args[0], args[1], args[cur_arg]);
|
||||||
args[0], args[1], args[cur_arg],
|
|
||||||
err && *err ? " Registered keywords :" : "", err && *err ? *err : "");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2656,8 +2654,8 @@ int mworker_cli_proxy_new_listener(char *line)
|
|||||||
cur_arg = 1;
|
cur_arg = 1;
|
||||||
|
|
||||||
while (*args[cur_arg]) {
|
while (*args[cur_arg]) {
|
||||||
static int bind_dumped;
|
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
|
const char *best;
|
||||||
|
|
||||||
kw = bind_find_kw(args[cur_arg]);
|
kw = bind_find_kw(args[cur_arg]);
|
||||||
if (kw) {
|
if (kw) {
|
||||||
@ -2680,15 +2678,13 @@ int mworker_cli_proxy_new_listener(char *line)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bind_dumped) {
|
best = bind_find_best_kw(args[cur_arg]);
|
||||||
bind_dump_kws(&err);
|
if (best)
|
||||||
indent_msg(&err, 4);
|
memprintf(&err, "'%s %s' : unknown keyword '%s'. Did you mean '%s' maybe ?",
|
||||||
bind_dumped = 1;
|
args[0], args[1], args[cur_arg], best);
|
||||||
}
|
else
|
||||||
|
memprintf(&err, "'%s %s' : unknown keyword '%s'.",
|
||||||
memprintf(&err, "'%s %s' : unknown keyword '%s'.%s%s",
|
args[0], args[1], args[cur_arg]);
|
||||||
args[0], args[1], args[cur_arg],
|
|
||||||
err ? " Registered keywords :" : "", err ? err : "");
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,6 +1261,37 @@ void bind_dump_kws(char **out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to find in srv_keyword the word that looks closest to <word> by counting
|
||||||
|
* transitions between letters, digits and other characters. Will return the
|
||||||
|
* best matching word if found, otherwise NULL.
|
||||||
|
*/
|
||||||
|
const char *bind_find_best_kw(const char *word)
|
||||||
|
{
|
||||||
|
uint8_t word_sig[1024];
|
||||||
|
uint8_t list_sig[1024];
|
||||||
|
const struct bind_kw_list *kwl;
|
||||||
|
const char *best_ptr = NULL;
|
||||||
|
int dist, best_dist = INT_MAX;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
make_word_fingerprint(word_sig, word);
|
||||||
|
list_for_each_entry(kwl, &bind_keywords.list, list) {
|
||||||
|
for (index = 0; kwl->kw[index].kw != NULL; index++) {
|
||||||
|
make_word_fingerprint(list_sig, kwl->kw[index].kw);
|
||||||
|
dist = word_fingerprint_distance(word_sig, list_sig);
|
||||||
|
if (dist < best_dist) {
|
||||||
|
best_dist = dist;
|
||||||
|
best_ptr = kwl->kw[index].kw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_dist > 2 * strlen(word) || (best_ptr && best_dist > 2 * strlen(best_ptr)))
|
||||||
|
best_ptr = NULL;
|
||||||
|
|
||||||
|
return best_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* All supported sample and ACL keywords must be declared here. */
|
/* All supported sample and ACL keywords must be declared here. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
38
src/log.c
38
src/log.c
@ -3894,7 +3894,6 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
|
|||||||
}
|
}
|
||||||
else if (strcmp(args[0], "bind") == 0) {
|
else if (strcmp(args[0], "bind") == 0) {
|
||||||
int cur_arg;
|
int cur_arg;
|
||||||
static int kws_dumped;
|
|
||||||
struct bind_conf *bind_conf;
|
struct bind_conf *bind_conf;
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
struct listener *l;
|
struct listener *l;
|
||||||
@ -3949,24 +3948,19 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
|
|||||||
cur_arg += 1 + kw->skip;
|
cur_arg += 1 + kw->skip;
|
||||||
}
|
}
|
||||||
if (*args[cur_arg] != 0) {
|
if (*args[cur_arg] != 0) {
|
||||||
char *kws = NULL;
|
const char *best = bind_find_best_kw(args[cur_arg]);
|
||||||
|
if (best)
|
||||||
if (!kws_dumped) {
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n",
|
||||||
kws_dumped = 1;
|
file, linenum, args[cur_arg], cursection, best);
|
||||||
bind_dump_kws(&kws);
|
else
|
||||||
indent_msg(&kws, 4);
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.\n",
|
||||||
}
|
file, linenum, args[cur_arg], cursection);
|
||||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
|
|
||||||
file, linenum, args[cur_arg], cursection,
|
|
||||||
kws ? " Registered keywords :" : "", kws ? kws: "");
|
|
||||||
free(kws);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(args[0], "dgram-bind") == 0) {
|
else if (strcmp(args[0], "dgram-bind") == 0) {
|
||||||
int cur_arg;
|
int cur_arg;
|
||||||
static int kws_dumped;
|
|
||||||
struct bind_conf *bind_conf;
|
struct bind_conf *bind_conf;
|
||||||
struct bind_kw *kw;
|
struct bind_kw *kw;
|
||||||
struct listener *l;
|
struct listener *l;
|
||||||
@ -4015,17 +4009,13 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
|
|||||||
cur_arg += 1 + kw->skip;
|
cur_arg += 1 + kw->skip;
|
||||||
}
|
}
|
||||||
if (*args[cur_arg] != 0) {
|
if (*args[cur_arg] != 0) {
|
||||||
char *kws = NULL;
|
const char *best = bind_find_best_kw(args[cur_arg]);
|
||||||
|
if (best)
|
||||||
if (!kws_dumped) {
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n",
|
||||||
kws_dumped = 1;
|
file, linenum, args[cur_arg], cursection, best);
|
||||||
bind_dump_kws(&kws);
|
else
|
||||||
indent_msg(&kws, 4);
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.\n",
|
||||||
}
|
file, linenum, args[cur_arg], cursection);
|
||||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
|
|
||||||
file, linenum, args[cur_arg], cursection,
|
|
||||||
kws ? " Registered keywords :" : "", kws ? kws: "");
|
|
||||||
free(kws);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user