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_USR, /* a pointer to a user list */
|
||||
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 */
|
||||
|
@ -72,10 +73,15 @@ enum {
|
|||
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 */
|
||||
struct proxy;
|
||||
struct server;
|
||||
struct userlist;
|
||||
struct my_regex;
|
||||
|
||||
union arg_data {
|
||||
unsigned int uint; /* used for uint, time, size */
|
||||
|
@ -87,6 +93,7 @@ union arg_data {
|
|||
struct server *srv;
|
||||
struct userlist *usr;
|
||||
struct map_descriptor *map;
|
||||
struct my_regex *reg;
|
||||
};
|
||||
|
||||
struct arg {
|
||||
|
|
|
@ -34,6 +34,7 @@ static const char *arg_type_names[ARGT_NBTYPES] = {
|
|||
[ARGT_SRV] = "server",
|
||||
[ARGT_USR] = "user list",
|
||||
[ARGT_MAP] = "map",
|
||||
[ARGT_REG] = "regex",
|
||||
/* 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_SRV:
|
||||
case ARGT_USR:
|
||||
case ARGT_REG:
|
||||
/* These argument types need to be stored as strings during
|
||||
* parsing then resolved later.
|
||||
*/
|
||||
|
|
|
@ -1086,6 +1086,13 @@ static void deinit_sample_arg(struct arg *p)
|
|||
p->data.str.str = NULL;
|
||||
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++;
|
||||
}
|
||||
|
||||
|
|
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 *conv_ctx, *conv_pre, *conv_pos;
|
||||
struct userlist *ul;
|
||||
struct my_regex *reg;
|
||||
struct arg *arg;
|
||||
int cfgerr = 0;
|
||||
int rflags;
|
||||
|
||||
list_for_each_entry_safe(cur, bak, &p->conf.args.list, list) {
|
||||
struct proxy *px;
|
||||
struct server *srv;
|
||||
char *pname, *sname;
|
||||
char *err;
|
||||
|
||||
arg = cur->arg;
|
||||
|
||||
|
@ -1004,7 +1007,7 @@ int smp_resolve_args(struct proxy *p)
|
|||
where = "in";
|
||||
ctx = "sample fetch keyword";
|
||||
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_LOG: where = "in log-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->data.usr = ul;
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue