mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-25 06:02:08 +00:00
MINOR: vars: make vars_get_by_* support an optional default value
In preparation for support default values when fetching variables, we need to update the internal API to pass an extra argument to functions vars_get_by_{name,desc} to provide an optional default value. This patch does this and always passes NULL in this argument. var_to_smp() was extended to fall back to this value when available.
This commit is contained in:
parent
be7e00d134
commit
e352b9dac7
@ -34,11 +34,11 @@ void var_accounting_diff(struct vars *vars, struct session *sess, struct stream
|
||||
unsigned int var_clear(struct var *var);
|
||||
void vars_prune(struct vars *vars, struct session *sess, struct stream *strm);
|
||||
void vars_prune_per_sess(struct vars *vars);
|
||||
int vars_get_by_name(const char *name, size_t len, struct sample *smp);
|
||||
int vars_get_by_name(const char *name, size_t len, struct sample *smp, const struct buffer *def);
|
||||
int vars_set_by_name_ifexist(const char *name, size_t len, struct sample *smp);
|
||||
int vars_set_by_name(const char *name, size_t len, struct sample *smp);
|
||||
int vars_unset_by_name_ifexist(const char *name, size_t len, struct sample *smp);
|
||||
int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp);
|
||||
int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp, const struct buffer *def);
|
||||
int vars_check_arg(struct arg *arg, char **err);
|
||||
|
||||
#endif
|
||||
|
@ -4382,7 +4382,7 @@ __LJMP static int hlua_applet_tcp_get_var(lua_State *L)
|
||||
s = luactx->htxn.s;
|
||||
|
||||
smp_set_owner(&smp, s->be, s->sess, s, 0);
|
||||
if (!vars_get_by_name(name, len, &smp)) {
|
||||
if (!vars_get_by_name(name, len, &smp, NULL)) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
@ -4869,7 +4869,7 @@ __LJMP static int hlua_applet_http_get_var(lua_State *L)
|
||||
s = luactx->htxn.s;
|
||||
|
||||
smp_set_owner(&smp, s->be, s->sess, s, 0);
|
||||
if (!vars_get_by_name(name, len, &smp)) {
|
||||
if (!vars_get_by_name(name, len, &smp, NULL)) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
@ -6966,7 +6966,7 @@ __LJMP static int hlua_get_var(lua_State *L)
|
||||
name = MAY_LJMP(luaL_checklstring(L, 2, &len));
|
||||
|
||||
smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
|
||||
if (!vars_get_by_name(name, len, &smp)) {
|
||||
if (!vars_get_by_name(name, len, &smp, NULL)) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
10
src/sample.c
10
src/sample.c
@ -1747,7 +1747,7 @@ static inline int sample_conv_var2smp_str(const struct arg *arg, struct sample *
|
||||
smp->flags = SMP_F_CONST;
|
||||
return 1;
|
||||
case ARGT_VAR:
|
||||
if (!vars_get_by_desc(&arg->data.var, smp))
|
||||
if (!vars_get_by_desc(&arg->data.var, smp, NULL))
|
||||
return 0;
|
||||
if (!sample_casts[smp->data.type][SMP_T_STR])
|
||||
return 0;
|
||||
@ -2990,7 +2990,7 @@ static inline int sample_conv_var2smp(const struct arg *arg, struct sample *smp)
|
||||
smp->data.u.sint = arg->data.sint;
|
||||
return 1;
|
||||
case ARGT_VAR:
|
||||
if (!vars_get_by_desc(&arg->data.var, smp))
|
||||
if (!vars_get_by_desc(&arg->data.var, smp, NULL))
|
||||
return 0;
|
||||
if (!sample_casts[smp->data.type][SMP_T_SINT])
|
||||
return 0;
|
||||
@ -3317,7 +3317,7 @@ static int sample_conv_concat(const struct arg *arg_p, struct sample *smp, void
|
||||
* into a string.
|
||||
*/
|
||||
smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
|
||||
if (arg_p[1].type == ARGT_VAR && vars_get_by_desc(&arg_p[1].data.var, &tmp) &&
|
||||
if (arg_p[1].type == ARGT_VAR && vars_get_by_desc(&arg_p[1].data.var, &tmp, NULL) &&
|
||||
(sample_casts[tmp.data.type][SMP_T_STR] == c_none ||
|
||||
sample_casts[tmp.data.type][SMP_T_STR](&tmp))) {
|
||||
|
||||
@ -3377,7 +3377,7 @@ static int sample_conv_strcmp(const struct arg *arg_p, struct sample *smp, void
|
||||
smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
|
||||
if (arg_p[0].type != ARGT_VAR)
|
||||
return 0;
|
||||
if (!vars_get_by_desc(&arg_p[0].data.var, &tmp))
|
||||
if (!vars_get_by_desc(&arg_p[0].data.var, &tmp, NULL))
|
||||
return 0;
|
||||
if (!sample_casts[tmp.data.type][SMP_T_STR](&tmp))
|
||||
return 0;
|
||||
@ -3415,7 +3415,7 @@ static int sample_conv_secure_memcmp(const struct arg *arg_p, struct sample *smp
|
||||
smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
|
||||
if (arg_p[0].type != ARGT_VAR)
|
||||
return 0;
|
||||
if (!vars_get_by_desc(&arg_p[0].data.var, &tmp))
|
||||
if (!vars_get_by_desc(&arg_p[0].data.var, &tmp, NULL))
|
||||
return 0;
|
||||
if (!sample_casts[tmp.data.type][SMP_T_BIN](&tmp))
|
||||
return 0;
|
||||
|
43
src/vars.c
43
src/vars.c
@ -340,7 +340,7 @@ static int smp_fetch_var(const struct arg *args, struct sample *smp, const char
|
||||
{
|
||||
const struct var_desc *var_desc = &args[0].data.var;
|
||||
|
||||
return vars_get_by_desc(var_desc, smp);
|
||||
return vars_get_by_desc(var_desc, smp, NULL);
|
||||
}
|
||||
|
||||
/* This function search in the <head> a variable with the same
|
||||
@ -574,10 +574,11 @@ int vars_unset_by_name_ifexist(const char *name, size_t len, struct sample *smp)
|
||||
* release the variables lock ASAP (so a pre-allocated chunk is obtained
|
||||
* via get_trash_shunk()). The variables' lock is used for reads.
|
||||
*
|
||||
* The function returns 0 if the variable was not found, otherwise 1
|
||||
* with the sample filled.
|
||||
* The function returns 0 if the variable was not found and no default
|
||||
* value was provided in <def>, otherwise 1 with the sample filled.
|
||||
* Default values are always returned as strings.
|
||||
*/
|
||||
static int var_to_smp(struct vars *vars, const char *name, struct sample *smp)
|
||||
static int var_to_smp(struct vars *vars, const char *name, struct sample *smp, const struct buffer *def)
|
||||
{
|
||||
struct var *var;
|
||||
|
||||
@ -585,12 +586,19 @@ static int var_to_smp(struct vars *vars, const char *name, struct sample *smp)
|
||||
HA_RWLOCK_RDLOCK(VARS_LOCK, &vars->rwlock);
|
||||
var = var_get(vars, name);
|
||||
if (!var) {
|
||||
HA_RWLOCK_RDUNLOCK(VARS_LOCK, &vars->rwlock);
|
||||
return 0;
|
||||
if (!def) {
|
||||
HA_RWLOCK_RDUNLOCK(VARS_LOCK, &vars->rwlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* not found but we have a default value */
|
||||
smp->data.type = SMP_T_STR;
|
||||
smp->data.u.str = *def;
|
||||
}
|
||||
else
|
||||
smp->data = var->data;
|
||||
|
||||
/* Copy sample. */
|
||||
smp->data = var->data;
|
||||
smp_dup(smp);
|
||||
|
||||
HA_RWLOCK_RDUNLOCK(VARS_LOCK, &vars->rwlock);
|
||||
@ -603,9 +611,13 @@ static int var_to_smp(struct vars *vars, const char *name, struct sample *smp)
|
||||
* and it therefore uses a pre-allocated trash chunk as returned by
|
||||
* get_trash_chunk().
|
||||
*
|
||||
* If the variable is not valid in this scope, 0 is always returned.
|
||||
* If the variable is valid but not found, either the default value
|
||||
* <def> is returned if not NULL, or zero is returned.
|
||||
*
|
||||
* Returns 1 if the sample is filled, otherwise it returns 0.
|
||||
*/
|
||||
int vars_get_by_name(const char *name, size_t len, struct sample *smp)
|
||||
int vars_get_by_name(const char *name, size_t len, struct sample *smp, const struct buffer *def)
|
||||
{
|
||||
struct vars *vars;
|
||||
enum vars_scope scope;
|
||||
@ -620,7 +632,8 @@ int vars_get_by_name(const char *name, size_t len, struct sample *smp)
|
||||
if (!vars || vars->scope != scope)
|
||||
return 0;
|
||||
|
||||
return var_to_smp(vars, name, smp);
|
||||
|
||||
return var_to_smp(vars, name, smp, def);
|
||||
}
|
||||
|
||||
/* This function fills a sample with the content of the variable described
|
||||
@ -630,9 +643,13 @@ int vars_get_by_name(const char *name, size_t len, struct sample *smp)
|
||||
* and it therefore uses a pre-allocated trash chunk as returned by
|
||||
* get_trash_chunk().
|
||||
*
|
||||
* If the variable is not valid in this scope, 0 is always returned.
|
||||
* If the variable is valid but not found, either the default value
|
||||
* <def> is returned if not NULL, or zero is returned.
|
||||
*
|
||||
* Returns 1 if the sample is filled, otherwise it returns 0.
|
||||
*/
|
||||
int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp)
|
||||
int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp, const struct buffer *def)
|
||||
{
|
||||
struct vars *vars;
|
||||
|
||||
@ -643,7 +660,7 @@ int vars_get_by_desc(const struct var_desc *var_desc, struct sample *smp)
|
||||
if (!vars || vars->scope != var_desc->scope)
|
||||
return 0;
|
||||
|
||||
return var_to_smp(vars, var_desc->name, smp);
|
||||
return var_to_smp(vars, var_desc->name, smp, def);
|
||||
}
|
||||
|
||||
/* Always returns ACT_RET_CONT even if an error occurs. */
|
||||
@ -739,7 +756,7 @@ static void release_store_rule(struct act_rule *rule)
|
||||
/* This two function checks the variable name and replace the
|
||||
* configuration string name by the global string name. its
|
||||
* the same string, but the global pointer can be easy to
|
||||
* compare.
|
||||
* compare. They return non-zero on success, zero on failure.
|
||||
*
|
||||
* The first function checks a sample-fetch and the second
|
||||
* checks a converter.
|
||||
@ -989,7 +1006,7 @@ static int vars_parse_cli_get_var(char **args, char *payload, struct appctx *app
|
||||
if (!vars || vars->scope != SCOPE_PROC)
|
||||
return 0;
|
||||
|
||||
if (!vars_get_by_name(args[2], strlen(args[2]), &smp))
|
||||
if (!vars_get_by_name(args[2], strlen(args[2]), &smp, NULL))
|
||||
return cli_err(appctx, "Variable not found.\n");
|
||||
|
||||
/* the sample returned by vars_get_by_name() is allocated into a trash
|
||||
|
Loading…
Reference in New Issue
Block a user