2
0

Compare commits

...

8 Commits

Author SHA1 Message Date
11df378496 [tests] lua: make sure lua logging functions don't break request handling
Change-Id: Ia43aec68b4ae7f18e8925d18665cc65e86f8e621
2025-06-01 13:44:52 +00:00
a9e4f098e2 [lua] logging: run tostring with error handling
* proper error handler
* don't raise lua error if argument couldn't be stringified (but log in
  error.log)
* use direct conversion / lua_tolstring for simple datatypes

Change-Id: Icae2639cc668f9a66c6fe3b392ecb70f92347e23
2025-06-01 13:44:52 +00:00
9a1458a3b8 [lua] add vr.error(...) (same as vr.print())
Change-Id: I2a88925ccc206db08818c8e4810b51ab2a97a49c
2025-06-01 13:44:52 +00:00
8d9c9599e9 [lua] fix broken _ENV in C (lua_getglobal) due to stack count error
Change-Id: I9be15695e78a3e6e78540c9252470ab79d5a4418
2025-06-01 13:44:52 +00:00
e51f801c00 [log] fix _VR_* logging macros (NULL-pointer (offset) deref for vr == NULL)
Change-Id: I4e42159727a423a192ed48ea4a31834b434e1941
2025-06-01 13:44:52 +00:00
7076993529 [build] search bzip2 via pkg-config first
Change-Id: Ibe02f28a91bdf3cae25663b5c223c847a5200e0b
2025-06-01 13:44:26 +00:00
ccae9e7fb5 [build]: add options for additional paths to search includes and libs in
Change-Id: I48bfd55603355357eb20668576723d217296789c
2025-06-01 13:44:22 +00:00
a0c6eb0bc7 [mod_memcached] fix comment
Change-Id: I8f3e92c5bddd731f73c8fc75b4990a8df7fa6166
2025-06-01 13:43:46 +00:00
14 changed files with 125 additions and 64 deletions

View File

@ -235,7 +235,7 @@
Methods: Methods:
* `print(...)`: print parameters via lua `tostring` method as ERROR in Virtual Request context * `error(...)` and `print(...)`: print parameters via lua `tostring` method as ERROR in Virtual Request context
* `warning(...)`: print parameters via lua `tostring` method as WARNING in Virtual Request context * `warning(...)`: print parameters via lua `tostring` method as WARNING in Virtual Request context
* `info(...)`: print parameters via lua `tostring` method as INFO in Virtual Request context * `info(...)`: print parameters via lua `tostring` method as INFO in Virtual Request context
* `debug(...)`: print parameters via lua `tostring` method as DEBUG in Virtual Request context * `debug(...)`: print parameters via lua `tostring` method as DEBUG in Virtual Request context

View File

@ -149,7 +149,7 @@ LI_API void li_lua_environment_use_globals(liLuaState *LL); /* +1 */
LI_API void li_lua_environment_restore_globals(lua_State *L); /* -1 */ LI_API void li_lua_environment_restore_globals(lua_State *L); /* -1 */
/* joinWith " " (map tostring parameter[from..to]) */ /* joinWith " " (map tostring parameter[from..to]) */
LI_API GString* li_lua_print_get_string(lua_State *L, int from, int to); LI_API GString* li_lua_print_get_string(lua_State *L, liServer *srv, liVRequest *vr, int from, int to);
/* pairs() for a GHashTable GString -> GString: /* pairs() for a GHashTable GString -> GString:
* Don't modify the hashtable while iterating: * Don't modify the hashtable while iterating:

View File

@ -54,14 +54,14 @@
#define VR_GERROR(vr, error, fmt, ...) _GERROR(vr->wrk->srv, vr->wrk, &vr->log_context, error, fmt, __VA_ARGS__) #define VR_GERROR(vr, error, fmt, ...) _GERROR(vr->wrk->srv, vr->wrk, &vr->log_context, error, fmt, __VA_ARGS__)
/* vr may be NULL; if vr is NULL, srv must NOT be NULL */ /* vr may be NULL; if vr is NULL, srv must NOT be NULL */
#define _VR_SEGFAULT(srv, vr, fmt, ...) _SEGFAULT(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_SEGFAULT(srv, vr, fmt, ...) _SEGFAULT(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_ERROR(srv, vr, fmt, ...) _ERROR(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_ERROR(srv, vr, fmt, ...) _ERROR(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_WARNING(srv, vr, fmt, ...) _WARNING(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_WARNING(srv, vr, fmt, ...) _WARNING(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_INFO(srv, vr, fmt, ...) _INFO(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_INFO(srv, vr, fmt, ...) _INFO(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_DEBUG(srv, vr, fmt, ...) _DEBUG(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_DEBUG(srv, vr, fmt, ...) _DEBUG(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_BACKEND(srv, vr, fmt, ...) _BACKEND(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, fmt, __VA_ARGS__) #define _VR_BACKEND(srv, vr, fmt, ...) _BACKEND(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, fmt, __VA_ARGS__)
#define _VR_BACKEND_LINES(srv, vr, txt, fmt, ...) _BACKEND_LINES(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, txt, fmt, __VA_ARGS__) #define _VR_BACKEND_LINES(srv, vr, txt, fmt, ...) _BACKEND_LINES(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, txt, fmt, __VA_ARGS__)
#define _VR_GERROR(srv, vr, error, fmt, ...) _GERROR(srv, NULL != vr ? vr->wrk : NULL, &vr->log_context, error, fmt, __VA_ARGS__) #define _VR_GERROR(srv, vr, error, fmt, ...) _GERROR(srv, NULL != vr ? vr->wrk : NULL, NULL != vr ? &vr->log_context : NULL, error, fmt, __VA_ARGS__)
#define SEGFAULT(srv, fmt, ...) _SEGFAULT(srv, NULL, NULL, fmt, __VA_ARGS__) #define SEGFAULT(srv, fmt, ...) _SEGFAULT(srv, NULL, NULL, fmt, __VA_ARGS__)
#define ERROR(srv, fmt, ...) _ERROR(srv, NULL, NULL, fmt, __VA_ARGS__) #define ERROR(srv, fmt, ...) _ERROR(srv, NULL, NULL, fmt, __VA_ARGS__)

View File

@ -14,6 +14,9 @@ libexec_dir = get_option('prefix') / get_option('libexecdir')
modules_dir = get_option('prefix') / get_option('libdir') / (meson.project_name() + '-' + meson.project_version()) modules_dir = get_option('prefix') / get_option('libdir') / (meson.project_name() + '-' + meson.project_version())
lua_dir = get_option('prefix') / get_option('datadir') / 'lighttpd2/lua' lua_dir = get_option('prefix') / get_option('datadir') / 'lighttpd2/lua'
search_includes = include_directories(get_option('search-inc'))
search_libs = get_option('search-lib')
compiler = meson.get_compiler('c') compiler = meson.get_compiler('c')
dep_not_found = dependency('', required: false) dep_not_found = dependency('', required: false)
@ -61,14 +64,18 @@ dep_gthread = dependency('gthread-2.0', version: '>=2.16')
dep_gmodule = dependency('gmodule-2.0', version: '>=2.16') dep_gmodule = dependency('gmodule-2.0', version: '>=2.16')
# find libev manually # find libev manually
debug('libs:', search_libs)
dep_ev = compiler.find_library( dep_ev = compiler.find_library(
'ev', 'ev',
has_headers: 'ev.h', has_headers: 'ev.h',
dirs: search_libs,
header_include_directories: search_includes,
) )
if not compiler.has_function( if not compiler.has_function(
'ev_time', 'ev_time',
prefix: '#include <ev.h>', prefix: '#include <ev.h>',
dependencies: dep_ev, dependencies: dep_ev,
include_directories: search_includes,
) )
error('Missing ev_time() in libev') error('Missing ev_time() in libev')
endif endif
@ -111,17 +118,23 @@ else
endif endif
if get_option('bzip2') if get_option('bzip2')
opt_dep_bzip2 = dependency('bzip2', required: false)
if not opt_dep_bzip2.found()
opt_dep_bzip2 = compiler.find_library( opt_dep_bzip2 = compiler.find_library(
'bz2', 'bz2',
has_headers: 'bzlib.h', has_headers: 'bzlib.h',
dirs: search_libs,
header_include_directories: search_includes,
) )
if not compiler.has_function( if not compiler.has_function(
'BZ2_bzCompressInit', 'BZ2_bzCompressInit',
prefix: '#include <bzlib.h>', prefix: '#include <bzlib.h>',
dependencies: opt_dep_bzip2, dependencies: opt_dep_bzip2,
include_directories: search_includes,
) )
error('Found libbz2, but missing BZ2_bzCompressInit()') error('Found libbz2, but missing BZ2_bzCompressInit()')
endif endif
endif
conf_data.set10('HAVE_BZIP', true) conf_data.set10('HAVE_BZIP', true)
else else
opt_dep_bzip2 = dep_not_found opt_dep_bzip2 = dep_not_found
@ -223,12 +236,15 @@ lib_crypt = compiler.find_library(
'crypt', 'crypt',
required: false, required: false,
has_headers: 'crypt.h', has_headers: 'crypt.h',
dirs: search_libs,
header_include_directories: search_includes,
) )
if lib_crypt.found() if lib_crypt.found()
if compiler.has_function( if compiler.has_function(
'crypt_r', 'crypt_r',
prefix: '#include <crypt.h>', prefix: '#include <crypt.h>',
dependencies: lib_crypt, dependencies: lib_crypt,
include_directories: search_includes,
) )
conf_data.set10('HAVE_CRYPT_H', true) conf_data.set10('HAVE_CRYPT_H', true)
conf_data.set10('HAVE_CRYPT_R', true) conf_data.set10('HAVE_CRYPT_R', true)
@ -240,7 +256,11 @@ else
endif endif
# need libm for fmod in throttle.c # need libm for fmod in throttle.c
lib_m = compiler.find_library('m') lib_m = compiler.find_library(
'm',
dirs: search_libs,
header_include_directories: search_includes,
)
# IPv6 support is mandatory by default # IPv6 support is mandatory by default
if get_option('ipv6') if get_option('ipv6')
@ -270,11 +290,14 @@ if target_machine.system() == 'freebsd'
lib_kvm = compiler.find_library( lib_kvm = compiler.find_library(
'kvm', 'kvm',
has_headers: 'kvm.h', has_headers: 'kvm.h',
dirs: search_libs,
header_include_directories: search_includes,
) )
if not compiler.has_function( if not compiler.has_function(
'kvm_open', 'kvm_open',
prefix: '#include <kvm.h>', prefix: '#include <kvm.h>',
dependencies: lib_kvm, dependencies: lib_kvm,
include_directories: search_includes,
) )
error('Found libkvm, but missing kvm_open') error('Found libkvm, but missing kvm_open')
endif endif

View File

@ -1,4 +1,4 @@
option('lua', type : 'boolean', value : true, description : 'Build with lua (5.1); extends core and other modules, and builds mod_lua') option('lua', type : 'boolean', value : true, description : 'Build with lua; extends core and other modules, and builds mod_lua')
option('ipv6', type : 'boolean', value : true, description : 'Build with IPv6 support') option('ipv6', type : 'boolean', value : true, description : 'Build with IPv6 support')
option('config-parser', type : 'boolean', value : true, description : 'Build with standard config parser') option('config-parser', type : 'boolean', value : true, description : 'Build with standard config parser')
option('unwind', type : 'boolean', value : true, description : 'Build with (lib)unwind support in asserts to print backtraces') option('unwind', type : 'boolean', value : true, description : 'Build with (lib)unwind support in asserts to print backtraces')
@ -10,3 +10,6 @@ option('deflate', type : 'boolean', value : true, description : 'Build mod_defla
option('extra-warnings', type : 'boolean', value : true, description : 'Build with extra warnings enabled') option('extra-warnings', type : 'boolean', value : true, description : 'Build with extra warnings enabled')
# option('static', type : 'boolean', value : false, description : 'Build static lighttpd with all modules included') # option('static', type : 'boolean', value : false, description : 'Build static lighttpd with all modules included')
option('profiler', type : 'boolean', value : false, description : 'Build with memory profiler') option('profiler', type : 'boolean', value : false, description : 'Build with memory profiler')
option('search-lib', type : 'array', value : [], description: 'Search libs in additional paths')
option('search-inc', type : 'array', value : [], description: 'Search includes in additional paths')

View File

@ -12,7 +12,7 @@ src_angel_shared = [
lib_shared_angel = library( lib_shared_angel = library(
'lighttpd2-sharedangel-' + meson.project_version(), 'lighttpd2-sharedangel-' + meson.project_version(),
src_angel_shared, src_angel_shared,
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: [ dependencies: [
main_deps, main_deps,
], ],
@ -23,7 +23,7 @@ lib_shared_angel = library(
bin_angel = executable( bin_angel = executable(
'lighttpd2', 'lighttpd2',
'angel_main.c', 'angel_main.c',
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: [ dependencies: [
main_deps, main_deps,
], ],

View File

@ -27,7 +27,7 @@ endif
lib_common = library( lib_common = library(
'lighttpd2-common-' + meson.project_version(), 'lighttpd2-common-' + meson.project_version(),
src_common, src_common,
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: [ dependencies: [
main_deps, main_deps,
opt_dep_unwind, opt_dep_unwind,

View File

@ -27,7 +27,7 @@ int li_lua_fixindex(lua_State *L, int ndx) {
return ndx; return ndx;
} }
static int traceback (lua_State *L) { static int traceback(lua_State *L) {
if (!lua_isstring(L, 1)) /* 'message' not a string? */ if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */ return 1; /* keep it intact */
lua_getglobal(L, "debug"); lua_getglobal(L, "debug");
@ -190,7 +190,7 @@ void li_lua_environment_restore(liLuaState *LL) /* -1 (expects previous metatabl
lua_rawgeti(L, LUA_REGISTRYINDEX, LL->li_env_ref); /* +1 */ lua_rawgeti(L, LUA_REGISTRYINDEX, LL->li_env_ref); /* +1 */
lua_pushvalue(L, -2); /* +1 */ lua_pushvalue(L, -2); /* +1 */
lua_setmetatable(L, -2); /* -1 restore prev mt for LI_ENV */ lua_setmetatable(L, -2); /* -1 restore prev mt for LI_ENV */
lua_pop(L, 1); /* -2 */ lua_pop(L, 2); /* -2 */
} }
void li_lua_environment_use_globals(liLuaState *LL) /* +1 */ { void li_lua_environment_use_globals(liLuaState *LL) /* +1 */ {
@ -205,23 +205,54 @@ void li_lua_environment_restore_globals(lua_State *L) /* -1 */ {
li_lua_set_globals(L); /* -1 */ li_lua_set_globals(L); /* -1 */
} }
GString* li_lua_print_get_string(lua_State *L, int from, int to) { /* resulting object on top of the stack might eighter be the lua string (owning the returned memory) or an error */
int i, n = lua_gettop(L); static const char *li_lua_tolstring(lua_State *L, liServer *srv, liVRequest *vr, int idx, size_t *len) { /* +1 */
int errfunc;
switch (lua_type(L, idx)) {
case LUA_TBOOLEAN:
lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
break;
case LUA_TNIL:
lua_pushlstring(L, CONST_STR_LEN("nil"));
break;
case LUA_TSTRING:
case LUA_TNUMBER:
lua_pushvalue(L, idx);
break;
default:
idx = li_lua_fixindex(L, idx);
lua_pushcfunction(L, traceback); /* +1 */
errfunc = lua_gettop(L);
lua_getglobal(L, "tostring"); /* +1 */
lua_pushvalue(L, idx); /* +1 object to convert to string */
if (lua_pcall(L, 1, 1, errfunc)) { /* -2 (func + args), +1 result */
_VR_ERROR(srv, vr, "li_lua_tolstring failed: %s", lua_tostring(L, -1));
if (len) *len = 0;
return NULL;
}
lua_remove(L, errfunc); /* -1 */
}
return lua_tolstring(L, -1, len);
}
GString* li_lua_print_get_string(lua_State *L, liServer *srv, liVRequest *vr, int from, int to) {
int i;
GString *buf = g_string_sized_new(0); GString *buf = g_string_sized_new(0);
lua_getglobal(L, "tostring");
for (i = from; i <= to; i++) { for (i = from; i <= to; i++) {
const char *s; const char *s;
size_t len; size_t len;
lua_pushvalue(L, n+1); if (NULL == (s = li_lua_tolstring(L, srv, vr, i, &len))) { /* +1 */
lua_pushvalue(L, i); s = "<failed tostring>";
if (0 != lua_pcall(L, 1, 1, 0)) goto failed; len = 17;
s = lua_tolstring(L, -1, &len); }
lua_pop(L, 1);
if (NULL == s) goto failed; if (len > 0) {
if (0 == len) continue;
if (buf->len > 0) { if (buf->len > 0) {
g_string_append_c(buf, ' '); g_string_append_c(buf, ' ');
li_g_string_append_len(buf, s, len); li_g_string_append_len(buf, s, len);
@ -229,20 +260,15 @@ GString* li_lua_print_get_string(lua_State *L, int from, int to) {
li_g_string_append_len(buf, s, len); li_g_string_append_len(buf, s, len);
} }
} }
lua_pop(L, 1); lua_pop(L, 1); /* -1 */
}
return buf; return buf;
failed:
g_string_free(buf, TRUE);
lua_pushliteral(L, "lua_print_get_string: Couldn't convert parameter to string");
lua_error(L);
return NULL; /* should be unreachable */
} }
static int li_lua_error(lua_State *L) { static int li_lua_error(lua_State *L) {
liServer *srv = lua_touserdata(L, lua_upvalueindex(1)); liServer *srv = lua_touserdata(L, lua_upvalueindex(1));
liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2)); liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2));
GString *buf = li_lua_print_get_string(L, 1, lua_gettop(L)); GString *buf = li_lua_print_get_string(L, srv, NULL, 1, lua_gettop(L));
_ERROR(srv, wrk, NULL, "(lua): %s", buf->str); _ERROR(srv, wrk, NULL, "(lua): %s", buf->str);
@ -254,7 +280,7 @@ static int li_lua_error(lua_State *L) {
static int li_lua_warning(lua_State *L) { static int li_lua_warning(lua_State *L) {
liServer *srv = lua_touserdata(L, lua_upvalueindex(1)); liServer *srv = lua_touserdata(L, lua_upvalueindex(1));
liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2)); liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2));
GString *buf = li_lua_print_get_string(L, 1, lua_gettop(L)); GString *buf = li_lua_print_get_string(L, srv, NULL, 1, lua_gettop(L));
_WARNING(srv, wrk, NULL, "(lua): %s", buf->str); _WARNING(srv, wrk, NULL, "(lua): %s", buf->str);
@ -266,7 +292,7 @@ static int li_lua_warning(lua_State *L) {
static int li_lua_info(lua_State *L) { static int li_lua_info(lua_State *L) {
liServer *srv = lua_touserdata(L, lua_upvalueindex(1)); liServer *srv = lua_touserdata(L, lua_upvalueindex(1));
liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2)); liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2));
GString *buf = li_lua_print_get_string(L, 1, lua_gettop(L)); GString *buf = li_lua_print_get_string(L, srv, NULL, 1, lua_gettop(L));
_INFO(srv, wrk, NULL, "(lua): %s", buf->str); _INFO(srv, wrk, NULL, "(lua): %s", buf->str);
@ -278,7 +304,7 @@ static int li_lua_info(lua_State *L) {
static int li_lua_debug(lua_State *L) { static int li_lua_debug(lua_State *L) {
liServer *srv = lua_touserdata(L, lua_upvalueindex(1)); liServer *srv = lua_touserdata(L, lua_upvalueindex(1));
liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2)); liWorker *wrk = lua_touserdata(L, lua_upvalueindex(2));
GString *buf = li_lua_print_get_string(L, 1, lua_gettop(L)); GString *buf = li_lua_print_get_string(L, srv, NULL, 1, lua_gettop(L));
_DEBUG(srv, wrk, NULL, "(lua): %s", buf->str); _DEBUG(srv, wrk, NULL, "(lua): %s", buf->str);

View File

@ -73,7 +73,7 @@ endif
lib_shared = library( lib_shared = library(
'lighttpd2-shared-' + meson.project_version(), 'lighttpd2-shared-' + meson.project_version(),
src_shared, src_shared,
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: [ dependencies: [
main_deps, main_deps,
opt_dep_lua, opt_dep_lua,
@ -86,7 +86,7 @@ lib_shared = library(
bin_worker = executable( bin_worker = executable(
'lighttpd2-worker', 'lighttpd2-worker',
'lighttpd_worker.c', 'lighttpd_worker.c',
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: [ dependencies: [
main_deps, main_deps,
opt_dep_lua, opt_dep_lua,

View File

@ -152,7 +152,7 @@ static int lua_vrequest_error(lua_State *L) {
GString *buf; GString *buf;
vr = li_lua_get_vrequest(L, 1); vr = li_lua_get_vrequest(L, 1);
buf = li_lua_print_get_string(L, 2, lua_gettop(L)); buf = li_lua_print_get_string(L, vr->wrk->srv, vr, 2, lua_gettop(L));
VR_ERROR(vr, "(lua): %s", buf->str); VR_ERROR(vr, "(lua): %s", buf->str);
@ -166,7 +166,7 @@ static int lua_vrequest_warning(lua_State *L) {
GString *buf; GString *buf;
vr = li_lua_get_vrequest(L, 1); vr = li_lua_get_vrequest(L, 1);
buf = li_lua_print_get_string(L, 2, lua_gettop(L)); buf = li_lua_print_get_string(L, vr->wrk->srv, vr, 2, lua_gettop(L));
VR_WARNING(vr, "(lua): %s", buf->str); VR_WARNING(vr, "(lua): %s", buf->str);
@ -180,7 +180,7 @@ static int lua_vrequest_info(lua_State *L) {
GString *buf; GString *buf;
vr = li_lua_get_vrequest(L, 1); vr = li_lua_get_vrequest(L, 1);
buf = li_lua_print_get_string(L, 2, lua_gettop(L)); buf = li_lua_print_get_string(L, vr->wrk->srv, vr, 2, lua_gettop(L));
VR_INFO(vr, "(lua): %s", buf->str); VR_INFO(vr, "(lua): %s", buf->str);
@ -194,7 +194,7 @@ static int lua_vrequest_debug(lua_State *L) {
GString *buf; GString *buf;
vr = li_lua_get_vrequest(L, 1); vr = li_lua_get_vrequest(L, 1);
buf = li_lua_print_get_string(L, 2, lua_gettop(L)); buf = li_lua_print_get_string(L, vr->wrk->srv, vr, 2, lua_gettop(L));
VR_DEBUG(vr, "(lua): %s", buf->str); VR_DEBUG(vr, "(lua): %s", buf->str);
@ -319,6 +319,7 @@ static const luaL_Reg vrequest_mt[] = {
{ "__newindex", lua_vrequest_newindex }, { "__newindex", lua_vrequest_newindex },
{ "print", lua_vrequest_error }, { "print", lua_vrequest_error },
{ "error", lua_vrequest_error },
{ "warning", lua_vrequest_warning }, { "warning", lua_vrequest_warning },
{ "info", lua_vrequest_info }, { "info", lua_vrequest_info },
{ "debug", lua_vrequest_debug }, { "debug", lua_vrequest_debug },

View File

@ -102,7 +102,7 @@ foreach name, def: modules
def['sources'], def['sources'],
dependencies: main_deps + mod_deps, dependencies: main_deps + mod_deps,
c_args: def.get('c_args', []), c_args: def.get('c_args', []),
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
install: true, install: true,
install_dir: modules_dir, install_dir: modules_dir,
) )

View File

@ -627,7 +627,7 @@ static const liPluginSetup setups[] = {
typedef struct { typedef struct {
liMemcachedRequest *req; liMemcachedRequest *req;
int result_ref; /* table if vr_ref == NULL, callback function otherwise */ int result_ref; /* table if vr_ref != NULL, callback function otherwise */
liJobRef *vr_ref; liJobRef *vr_ref;
lua_State *L; lua_State *L;
} mc_lua_request; } mc_lua_request;

View File

@ -29,7 +29,7 @@ foreach name, def: unittests
test_bin = executable( test_bin = executable(
def['binary'], def['binary'],
def['sources'], def['sources'],
include_directories: inc_dir, include_directories: [inc_dir] + search_includes,
dependencies: main_deps + def.get('dependencies', []), dependencies: main_deps + def.get('dependencies', []),
link_with: [ link_with: [
lib_shared, lib_shared,

View File

@ -8,7 +8,14 @@ LUA_STATE_ENV_INFO = """
-- globals should be reset after loading -- globals should be reset after loading
info = "global info" info = "global info"
-- tostring(custom_obj) should throw an error, but log functions should handle it
local custom_obj = {["data"] = "test string"}
setmetatable(custom_obj, {["__tostring"] = function(obj) return nil .. obj["data"] end})
print("bar", "custom_obj=", custom_obj)
local function extract_info(vr) local function extract_info(vr)
vr:error("extract_info: info=" .. (info or ""), "nil=", nil, "custom_obj=", custom_obj)
-- simple globals should be "per handler" (and request) -- simple globals should be "per handler" (and request)
info = (info or "") .. "handler global" info = (info or "") .. "handler global"
-- special `REQ` allows request-global state across handlers -- special `REQ` allows request-global state across handlers
@ -16,6 +23,7 @@ local function extract_info(vr)
end end
local function show_info(vr) local function show_info(vr)
lighty.error("show_info: info=" .. (info or "") .. "; REQ.info=" .. (REQ.info or ""))
if vr:handle_direct() then if vr:handle_direct() then
vr.resp.status = 200 vr.resp.status = 200
vr.resp.headers["Content-Type"] = "text/plain" vr.resp.headers["Content-Type"] = "text/plain"