MINOR: arg: add an argument type for identifier

The ARGT_ID argument type may now be used to set a custom resolve
function in order to help resolve the argument string value. If the
custom resolve function is not set, the behavior is the same as of
type ARGT_STR.
This commit is contained in:
Dragan Dosen 2024-10-17 10:59:01 +02:00 committed by Willy Tarreau
parent 40ab88899c
commit f33e9079a9
3 changed files with 23 additions and 0 deletions

View File

@ -46,6 +46,7 @@ enum {
ARGT_STOP = 0, /* end of the arg list */ ARGT_STOP = 0, /* end of the arg list */
ARGT_SINT, /* signed 64 bit integer. */ ARGT_SINT, /* signed 64 bit integer. */
ARGT_STR, /* string */ ARGT_STR, /* string */
ARGT_ID, /* identifier */
ARGT_IPV4, /* an IPv4 address */ ARGT_IPV4, /* an IPv4 address */
ARGT_MSK4, /* an IPv4 address mask (integer or dotted), stored as ARGT_IPV4 */ ARGT_MSK4, /* an IPv4 address mask (integer or dotted), stored as ARGT_IPV4 */
ARGT_IPV6, /* an IPv6 address */ ARGT_IPV6, /* an IPv6 address */
@ -124,6 +125,12 @@ struct arg {
unsigned char unresolved; /* argument contains a string in <str> that must be resolved and freed */ unsigned char unresolved; /* argument contains a string in <str> that must be resolved and freed */
unsigned char type_flags; /* type-specific extra flags (eg: case sensitivity for regex), ARGF_* */ unsigned char type_flags; /* type-specific extra flags (eg: case sensitivity for regex), ARGF_* */
union arg_data data; /* argument data */ union arg_data data; /* argument data */
int (*resolve_ptr)(struct arg *arg, char **err); /* ptr to custom resolve function that can be used
* for the arg of type ARGT_ID; the err must always
* be compatible with free() (i.e. either null or
* the result of a malloc/strdup/memprintf call)
*/
}; };
/* arg lists are used to store information about arguments that could not be /* arg lists are used to store information about arguments that could not be

View File

@ -24,6 +24,7 @@ const char *arg_type_names[ARGT_NBTYPES] = {
[ARGT_STOP] = "end of arguments", [ARGT_STOP] = "end of arguments",
[ARGT_SINT] = "integer", [ARGT_SINT] = "integer",
[ARGT_STR] = "string", [ARGT_STR] = "string",
[ARGT_ID] = "identifier",
[ARGT_IPV4] = "IPv4 address", [ARGT_IPV4] = "IPv4 address",
[ARGT_MSK4] = "IPv4 mask", [ARGT_MSK4] = "IPv4 mask",
[ARGT_IPV6] = "IPv6 address", [ARGT_IPV6] = "IPv6 address",
@ -237,6 +238,7 @@ int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp,
arg->type = ARGT_SINT; arg->type = ARGT_SINT;
break; break;
case ARGT_ID:
case ARGT_FE: case ARGT_FE:
case ARGT_BE: case ARGT_BE:
case ARGT_TAB: case ARGT_TAB:

View File

@ -1444,6 +1444,20 @@ int smp_resolve_args(struct proxy *p, char **err)
pname = p->id; pname = p->id;
switch (arg->type) { switch (arg->type) {
case ARGT_ID:
err2 = NULL;
if (arg->resolve_ptr && !arg->resolve_ptr(arg, &err2)) {
memprintf(err, "%sparsing [%s:%d]: error in identifier '%s' in arg %d of %s%s%s%s '%s' %s proxy '%s' : %s.\n",
*err ? *err : "", cur->file, cur->line,
arg->data.str.area,
cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id, err2);
ha_free(&err2);
cfgerr++;
continue;
}
break;
case ARGT_SRV: case ARGT_SRV:
if (!arg->data.str.data) { if (!arg->data.str.data) {
memprintf(err, "%sparsing [%s:%d]: missing server name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n", memprintf(err, "%sparsing [%s:%d]: missing server name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",