MINOR: args: implement a new arg type for regex : ARGT_REG
This one will be used when a regex is expected. It is automatically resolved after the parsing and compiled into a regex. Some optional flags are supported in the type-specific flags that should be set by the optional arg checker. One is used during the regex compilation : ARGF_REG_ICASE to ignore case.
This commit is contained in:
parent
085dafac5f
commit
469477879c
|
@ -57,6 +57,7 @@ enum {
|
||||||
ARGT_SRV, /* a pointer to a server */
|
ARGT_SRV, /* a pointer to a server */
|
||||||
ARGT_USR, /* a pointer to a user list */
|
ARGT_USR, /* a pointer to a user list */
|
||||||
ARGT_MAP, /* a pointer to a map descriptor */
|
ARGT_MAP, /* a pointer to a map descriptor */
|
||||||
|
ARGT_REG, /* a pointer to a regex */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* context where arguments are used, in order to help error reporting */
|
/* context where arguments are used, in order to help error reporting */
|
||||||
|
@ -72,10 +73,15 @@ enum {
|
||||||
ARGC_CAP, /* capture rule */
|
ARGC_CAP, /* capture rule */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* flags used when compiling and executing regex */
|
||||||
|
#define ARGF_REG_ICASE 1
|
||||||
|
#define ARGF_REG_GLOB 2
|
||||||
|
|
||||||
/* some types that are externally defined */
|
/* some types that are externally defined */
|
||||||
struct proxy;
|
struct proxy;
|
||||||
struct server;
|
struct server;
|
||||||
struct userlist;
|
struct userlist;
|
||||||
|
struct my_regex;
|
||||||
|
|
||||||
union arg_data {
|
union arg_data {
|
||||||
unsigned int uint; /* used for uint, time, size */
|
unsigned int uint; /* used for uint, time, size */
|
||||||
|
@ -87,6 +93,7 @@ union arg_data {
|
||||||
struct server *srv;
|
struct server *srv;
|
||||||
struct userlist *usr;
|
struct userlist *usr;
|
||||||
struct map_descriptor *map;
|
struct map_descriptor *map;
|
||||||
|
struct my_regex *reg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arg {
|
struct arg {
|
||||||
|
|
|
@ -34,6 +34,7 @@ static const char *arg_type_names[ARGT_NBTYPES] = {
|
||||||
[ARGT_SRV] = "server",
|
[ARGT_SRV] = "server",
|
||||||
[ARGT_USR] = "user list",
|
[ARGT_USR] = "user list",
|
||||||
[ARGT_MAP] = "map",
|
[ARGT_MAP] = "map",
|
||||||
|
[ARGT_REG] = "regex",
|
||||||
/* Unassigned types must never happen. Better crash during parsing if they do. */
|
/* Unassigned types must never happen. Better crash during parsing if they do. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,6 +174,7 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||||
case ARGT_TAB:
|
case ARGT_TAB:
|
||||||
case ARGT_SRV:
|
case ARGT_SRV:
|
||||||
case ARGT_USR:
|
case ARGT_USR:
|
||||||
|
case ARGT_REG:
|
||||||
/* These argument types need to be stored as strings during
|
/* These argument types need to be stored as strings during
|
||||||
* parsing then resolved later.
|
* parsing then resolved later.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1086,6 +1086,13 @@ static void deinit_sample_arg(struct arg *p)
|
||||||
p->data.str.str = NULL;
|
p->data.str.str = NULL;
|
||||||
p->unresolved = 0;
|
p->unresolved = 0;
|
||||||
}
|
}
|
||||||
|
else if (p->type == ARGT_REG) {
|
||||||
|
if (p->data.reg) {
|
||||||
|
regex_free(p->data.reg);
|
||||||
|
free(p->data.reg);
|
||||||
|
p->data.reg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
src/sample.c
44
src/sample.c
|
@ -983,13 +983,16 @@ int smp_resolve_args(struct proxy *p)
|
||||||
const char *ctx, *where;
|
const char *ctx, *where;
|
||||||
const char *conv_ctx, *conv_pre, *conv_pos;
|
const char *conv_ctx, *conv_pre, *conv_pos;
|
||||||
struct userlist *ul;
|
struct userlist *ul;
|
||||||
|
struct my_regex *reg;
|
||||||
struct arg *arg;
|
struct arg *arg;
|
||||||
int cfgerr = 0;
|
int cfgerr = 0;
|
||||||
|
int rflags;
|
||||||
|
|
||||||
list_for_each_entry_safe(cur, bak, &p->conf.args.list, list) {
|
list_for_each_entry_safe(cur, bak, &p->conf.args.list, list) {
|
||||||
struct proxy *px;
|
struct proxy *px;
|
||||||
struct server *srv;
|
struct server *srv;
|
||||||
char *pname, *sname;
|
char *pname, *sname;
|
||||||
|
char *err;
|
||||||
|
|
||||||
arg = cur->arg;
|
arg = cur->arg;
|
||||||
|
|
||||||
|
@ -1004,7 +1007,7 @@ int smp_resolve_args(struct proxy *p)
|
||||||
where = "in";
|
where = "in";
|
||||||
ctx = "sample fetch keyword";
|
ctx = "sample fetch keyword";
|
||||||
switch (cur->ctx) {
|
switch (cur->ctx) {
|
||||||
case ARGC_STK:where = "in stick rule in"; break;
|
case ARGC_STK: where = "in stick rule in"; break;
|
||||||
case ARGC_TRK: where = "in tracking rule in"; break;
|
case ARGC_TRK: where = "in tracking rule in"; break;
|
||||||
case ARGC_LOG: where = "in log-format string in"; break;
|
case ARGC_LOG: where = "in log-format string in"; break;
|
||||||
case ARGC_HRQ: where = "in http-request header format string in"; break;
|
case ARGC_HRQ: where = "in http-request header format string in"; break;
|
||||||
|
@ -1175,6 +1178,45 @@ int smp_resolve_args(struct proxy *p)
|
||||||
arg->unresolved = 0;
|
arg->unresolved = 0;
|
||||||
arg->data.usr = ul;
|
arg->data.usr = ul;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARGT_REG:
|
||||||
|
if (!arg->data.str.len) {
|
||||||
|
Alert("parsing [%s:%d] : missing regex in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
|
||||||
|
cur->file, cur->line,
|
||||||
|
cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = calloc(1, sizeof(*reg));
|
||||||
|
if (!reg) {
|
||||||
|
Alert("parsing [%s:%d] : not enough memory to build regex in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
|
||||||
|
cur->file, cur->line,
|
||||||
|
cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rflags = 0;
|
||||||
|
rflags |= (arg->type_flags & ARGF_REG_ICASE) ? REG_ICASE : 0;
|
||||||
|
err = NULL;
|
||||||
|
|
||||||
|
if (!regex_comp(arg->data.str.str, reg, rflags, 1 /* capture substr */, &err)) {
|
||||||
|
Alert("parsing [%s:%d] : error in regex '%s' in arg %d of %s%s%s%s '%s' %s proxy '%s' : %s.\n",
|
||||||
|
cur->file, cur->line,
|
||||||
|
arg->data.str.str,
|
||||||
|
cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id, err);
|
||||||
|
cfgerr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(arg->data.str.str);
|
||||||
|
arg->data.str.str = NULL;
|
||||||
|
arg->unresolved = 0;
|
||||||
|
arg->data.reg = reg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_DEL(&cur->list);
|
LIST_DEL(&cur->list);
|
||||||
|
|
Loading…
Reference in New Issue