]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: lua: create a namespace for the fetches
authorThierry FOURNIER <tfournier@exceliance.fr>
Wed, 11 Mar 2015 17:28:02 +0000 (18:28 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 11 Mar 2015 18:55:10 +0000 (19:55 +0100)
HAProxy proposes many sample fetches. It is possible that the
automatic registration of the sample fetches causes a collision
with an existing Lua function. This patch sets a namespace for
the sample fetches.

include/types/hlua.h
src/hlua.c

index a385c02bfcf495e799362421ced4b88560a169f5..77f10ac80cc7a0a1bb5e2905ad3ff8348cb5f461 100644 (file)
@@ -11,6 +11,7 @@
 
 #define CLASS_CORE     "Core"
 #define CLASS_TXN      "TXN"
+#define CLASS_FETCHES  "Fetches"
 #define CLASS_SOCKET   "Socket"
 #define CLASS_CHANNEL  "Channel"
 
index d9df99d2da0ad5a8d8b22cb8aee2ff5175785d29..5eaf2258d0f93a5a49555d2656adc007b94007c8 100644 (file)
@@ -71,6 +71,7 @@ struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
 static int class_txn_ref;
 static int class_socket_ref;
 static int class_channel_ref;
+static int class_fetches_ref;
 
 /* Global Lua execution timeout. By default Lua, execution linked
  * with session (actions, sample-fetches and converters) have a
@@ -2464,6 +2465,102 @@ __LJMP static int hlua_channel_get_out_len(lua_State *L)
        return 1;
 }
 
+/*
+ *
+ *
+ * Class Fetches
+ *
+ *
+ */
+
+/* Returns a struct hlua_session if the stack entry "ud" is
+ * a class session, otherwise it throws an error.
+ */
+__LJMP static struct hlua_txn *hlua_checkfetches(lua_State *L, int ud)
+{
+       return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_fetches_ref));
+}
+
+/* This function creates and push in the stack a fetch object according
+ * with a current TXN.
+ */
+static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn)
+{
+       struct hlua_txn *hs;
+
+       /* Check stack size. */
+       if (!lua_checkstack(L, 3))
+               return 0;
+
+       /* Create the object: obj[0] = userdata.
+        * Note that the base of the Fetches object is the
+        * transaction object.
+        */
+       lua_newtable(L);
+       hs = lua_newuserdata(L, sizeof(struct hlua_txn));
+       lua_rawseti(L, -2, 0);
+
+       hs->s = txn->s;
+       hs->p = txn->p;
+       hs->l7 = txn->l7;
+
+       /* Pop a class sesison metatable and affect it to the userdata. */
+       lua_rawgeti(L, LUA_REGISTRYINDEX, class_fetches_ref);
+       lua_setmetatable(L, -2);
+
+       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 thrown
+ * only if an error is encountered 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 + 1];
+       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_checkfetches(L, 1));
+
+       /* Get extra arguments. */
+       for (i = 0; i < lua_gettop(L) - 1; 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 checker. */
+       if (f->f->val_args && !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;
+}
 
 /*
  *
@@ -2547,6 +2644,12 @@ static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void *
        hs->p = p;
        hs->l7 = l7;
 
+       /* Create the "f" field that contains a list of fetches. */
+       lua_pushstring(L, "f");
+       if (!hlua_fetches_new(L, hs))
+               return 0;
+       lua_settable(L, -3);
+
        /* Pop a class sesison metatable and affect it to the userdata. */
        lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
        lua_setmetatable(L, -2);
@@ -2608,57 +2711,6 @@ __LJMP static int hlua_txn_close(lua_State *L)
        return 0;
 }
 
-/* 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 thrown
- * only if an error is encountered 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 + 1];
-       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) - 1; 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 checker. */
-       if (f->f->val_args && !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 an LUA binding. It creates ans returns
  * an array of HTTP headers. This function does not fails.
  */
@@ -3761,7 +3813,7 @@ void hlua_init(void)
 
        /*
         *
-        * Register class TXN
+        * Register class Fetches
         *
         */
 
@@ -3803,6 +3855,26 @@ void hlua_init(void)
                lua_settable(gL.T, -3);
        }
 
+       lua_settable(gL.T, -3);
+
+       /* Register previous table in the registry with reference and named entry. */
+       lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
+       lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_FETCHES); /* register class session. */
+       class_fetches_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
+
+       /*
+        *
+        * Register class TXN
+        *
+        */
+
+       /* Create and fill the metatable. */
+       lua_newtable(gL.T);
+
+       /* Create and fille the __index entry. */
+       lua_pushstring(gL.T, "__index");
+       lua_newtable(gL.T);
+
        /* Register Lua functions. */
        hlua_class_function(gL.T, "get_headers", hlua_session_get_headers);
        hlua_class_function(gL.T, "set_priv",    hlua_set_priv);