diff --git a/doc/configuration.txt b/doc/configuration.txt index 6d8226a82..939f7c489 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1795,7 +1795,7 @@ log-tag Sometimes it can be useful to differentiate between multiple processes running on the same host. See also the per-proxy "log-tag" directive. -lua-load +lua-load [ [ [ ... ] ] ] This global directive loads and executes a Lua file in the shared context that is visible to all threads. Any variable set in such a context is visible from any thread. This is the easiest and recommended way to load Lua programs @@ -1804,7 +1804,14 @@ lua-load way will always see 0 in the "core.thread" variable. This directive can be used multiple times. -lua-load-per-thread + args are avalaible in the lua file using the code below in the body of the + file. Do not forget that Lua arrays start at index 1. A "local" variable + declared in a file is avalaible in the entire file and not avalaible on + other files. + + local args = table.pack(...) + +lua-load-per-thread [ [ [ ... ] ] ] This global directive loads and executes a Lua file into each started thread. Any global variable has a thread-local visibility so that each thread could see a different value. As such it is strongly recommended not to use global @@ -1821,6 +1828,8 @@ lua-load-per-thread case it will be equivalent to lua-load). This directive can be used multiple times. + See lua-load for usage of args. + lua-prepend-path [] Prepends the given string followed by a semicolon to Lua's package. variable. diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index 515d8853b..847ab521e 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -116,6 +116,38 @@ On other terminal, you can test with telnet: #:~ telnet 127.0.0.1 10001 hello world +Usage of load parameters +------------------------ + +HAProxy lua-load(-per-thread) directives allow a list of paramaters after +the lua file name. These parameters are accessible through an array of args +using this code `local args = table.pack(...)` in the body of loaded file. + +Below, a new version of the hello world using load parameters + +HAProxy configuration file (`hello_world.conf`): + +:: + + global + lua-load hello_world.lua "this is not an hello world" + + listen proxy + bind 127.0.0.1:10001 + tcp-request inspect-delay 1s + tcp-request content use-service lua.hello_world + +HAProxy Lua file (`hello_world.lua`): + +.. code-block:: lua + + local args = table.pack(...) + + core.register_service("hello_world", "tcp", function(applet) + applet:send(args[1] .. "\n") + end) + + Core class ========== diff --git a/src/hlua.c b/src/hlua.c index d3a73d50e..2fd710d3a 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -145,7 +145,7 @@ static struct list referenced_functions = LIST_HEAD_INIT(referenced_functions); static int hlua_state_id; /* This is a NULL-terminated list of lua file which are referenced to load per thread */ -static char **per_thread_load = NULL; +static char ***per_thread_load = NULL; lua_State *hlua_init_state(int thread_id); @@ -11236,20 +11236,27 @@ static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx, * We are in the configuration parsing process of HAProxy, this abort() is * tolerated. */ -static int hlua_load_state(char *filename, lua_State *L, char **err) +static int hlua_load_state(char **args, lua_State *L, char **err) { int error; + int nargs; /* Just load and compile the file. */ - error = luaL_loadfile(L, filename); + error = luaL_loadfile(L, args[0]); if (error) { - memprintf(err, "error in Lua file '%s': %s", filename, lua_tostring(L, -1)); + memprintf(err, "error in Lua file '%s': %s", args[0], lua_tostring(L, -1)); lua_pop(L, 1); return -1; } + /* Push args in the Lua stack, except the first one which is the filename */ + for (nargs = 1; *(args[nargs]) != 0; nargs++) { + lua_pushstring(L, args[nargs]); + } + nargs--; + /* If no syntax error where detected, execute the code. */ - error = lua_pcall(L, 0, LUA_MULTRET, 0); + error = lua_pcall(L, nargs, LUA_MULTRET, 0); switch (error) { case LUA_OK: break; @@ -11291,7 +11298,7 @@ static int hlua_load(char **args, int section_type, struct proxy *curpx, /* loading for global state */ hlua_state_id = 0; ha_set_thread(NULL); - return hlua_load_state(args[1], hlua_states[0], err); + return hlua_load_state(&args[1], hlua_states[0], err); } static int hlua_load_per_thread(char **args, int section_type, struct proxy *curpx, @@ -11299,6 +11306,7 @@ static int hlua_load_per_thread(char **args, int section_type, struct proxy *cur char **err) { int len; + int i; if (*(args[1]) == 0) { memprintf(err, "'%s' expects a file as parameter.", args[0]); @@ -11323,19 +11331,32 @@ static int hlua_load_per_thread(char **args, int section_type, struct proxy *cur memprintf(err, "out of memory error"); return -1; } - - per_thread_load[len] = strdup(args[1]); per_thread_load[len + 1] = NULL; + /* count args excepting the first, allocate array and copy args */ + for (i = 0; *(args[i + 1]) != 0; i++); + per_thread_load[len] = calloc(i + 1, sizeof(per_thread_load[len])); if (per_thread_load[len] == NULL) { memprintf(err, "out of memory error"); return -1; } + for (i = 1; *(args[i]) != 0; i++) { + per_thread_load[len][i - 1] = strdup(args[i]); + if (per_thread_load[len][i - 1] == NULL) { + memprintf(err, "out of memory error"); + return -1; + } + } + per_thread_load[len][i - 1] = strdup(""); + if (per_thread_load[len][i - 1] == NULL) { + memprintf(err, "out of memory error"); + return -1; + } /* loading for thread 1 only */ hlua_state_id = 1; ha_set_thread(NULL); - return hlua_load_state(args[1], hlua_states[1], err); + return hlua_load_state(per_thread_load[len], hlua_states[1], err); } /* Prepend the given followed by a semicolon to the `package.` variable