From d0fa538fe3e8e57409dfcd86731e802490390cbc Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Mon, 16 Feb 2015 20:14:51 +0100 Subject: [PATCH] MINOR: lua: txn: import existing sample-fetches in the class TXN This patch adds the browsing of all the HAProxy fetches and create associated LUA functions. The HAProxy internal fetches can be used in LUA trough the class "TXN". Note that the symbols "-", "+" and "." in the name of current sample fetch are rewrited as "_" in LUA because ".", "-" and "+" are operators. --- include/types/hlua.h | 10 +++++ src/hlua.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/include/types/hlua.h b/include/types/hlua.h index aada722d7e..1241778114 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -63,4 +63,14 @@ struct hlua_txn { void *l7; }; +/* This struct is used as a closure argument associated + * with dynamic sample-fetch created fucntions. This contains + * a pointer to the original sample_fetch struct. It is used + * to identify the function to execute with the sample fetch + * wrapper. + */ +struct hlua_sample_fetch { + struct sample_fetch *f; +}; + #endif /* _TYPES_HLUA_H */ diff --git a/src/hlua.c b/src/hlua.c index f3c329db6a..bf3ed29f14 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -11,6 +11,9 @@ #include #include +#include +#include +#include #include /* Lua uses longjmp to perform yield or throwing errors. This @@ -849,6 +852,57 @@ static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void * return 1; } +/* This function is an LUA binding. It is called with each sample-fetch. + * It uses closure argument to store the associated sample-fetch. It + * returns only one argument or throws an error. An error is throwed + * only if an error is encoutered during the argument parsing. If + * the "sample-fetch" function fails, nil is returned. + */ +__LJMP static int hlua_run_sample_fetch(lua_State *L) +{ + struct hlua_txn *s; + struct hlua_sample_fetch *f; + struct arg args[ARGM_NBARGS]; + int i; + struct sample smp; + + /* Get closure arguments. */ + f = (struct hlua_sample_fetch *)lua_touserdata(L, lua_upvalueindex(1)); + + /* Get traditionnal arguments. */ + s = MAY_LJMP(hlua_checktxn(L, 1)); + + /* Get extra arguments. */ + for (i = 0; i <= lua_gettop(L); i++) { + if (i >= ARGM_NBARGS) + break; + hlua_lua2arg(L, i + 2, &args[i]); + } + args[i].type = ARGT_STOP; + + /* Check arguments. */ + MAY_LJMP(hlua_lua2arg_check(L, 1, args, f->f->arg_mask)); + + /* Run the special args cehcker. */ + if (!f->f->val_args(args, NULL)) { + lua_pushfstring(L, "error in arguments"); + WILL_LJMP(lua_error(L)); + } + + /* Initialise the sample. */ + memset(&smp, 0, sizeof(smp)); + + /* Run the sample fetch process. */ + if (!f->f->process(s->p, s->s, s->l7, 0, args, &smp, f->f->kw, f->f->private)) { + lua_pushnil(L); + return 1; + } + + /* Convert the returned sample in lua value. */ + hlua_smp2lua(L, &smp); + return 1; +} + /* This function is used as a calback of a task. It is called by the * HAProxy task subsystem when the task is awaked. The LUA runtime can * return an E_AGAIN signal, the emmiter of this signal must set a @@ -1057,6 +1111,10 @@ int hlua_post_init() void hlua_init(void) { int i; + int idx; + struct sample_fetch *sf; + struct hlua_sample_fetch *hsf; + char *p; /* Initialise com signals pool session. */ pool2_hlua_com = create_pool("hlua_com", sizeof(struct hlua_com), MEM_F_SHARED); @@ -1128,6 +1186,37 @@ void hlua_init(void) lua_pushstring(gL.T, "__index"); lua_newtable(gL.T); + /* Browse existing fetches and create the associated + * object method. + */ + sf = NULL; + while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) { + + /* Dont register the keywork if the arguments check function are + * not safe during the runtime. + */ + if ((sf->val_args != NULL) && + (sf->val_args != val_payload_lv) && + (sf->val_args != val_hdr)) + continue; + + /* gL.Tua doesn't support '.' and '-' in the function names, replace it + * by an underscore. + */ + strncpy(trash.str, sf->kw, trash.size); + trash.str[trash.size - 1] = '\0'; + for (p = trash.str; *p; p++) + if (*p == '.' || *p == '-' || *p == '+') + *p = '_'; + + /* Register the function. */ + lua_pushstring(gL.T, trash.str); + hsf = lua_newuserdata(gL.T, sizeof(struct hlua_sample_fetch)); + hsf->f = sf; + lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1); + lua_settable(gL.T, -3); + } + /* Register Lua functions. */ hlua_class_function(gL.T, "set_priv", hlua_setpriv); hlua_class_function(gL.T, "get_priv", hlua_getpriv);