From: Jim Jagielski Date: Wed, 1 Mar 2017 16:54:35 +0000 (+0000) Subject: Backport of Lua exhancements from trunk, mostly to support 5.3 X-Git-Tag: 2.4.26~278 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6b3dbb8f5a778ef993390cf29f51c2ec7840c0b;p=apache Backport of Lua exhancements from trunk, mostly to support 5.3 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1784990 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 77140268f9..6aa5c6badf 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,8 @@ Changes with Apache 2.4.26 + *) mod_lua: Support for Lua 5.3 + *) mod_proxy_http2: support for ProxyPreserverHost directive. [Stefan Eissing] *) mod_http2: fix for crash when running out of memory. diff --git a/modules/lua/NWGNUmakefile b/modules/lua/NWGNUmakefile index fd86b3c9ee..24f2703f58 100644 --- a/modules/lua/NWGNUmakefile +++ b/modules/lua/NWGNUmakefile @@ -46,6 +46,9 @@ XCFLAGS += \ # XDEFINES += \ -DLUA_COMPAT_ALL \ + -DLUA_COMPAT_5_2 \ + -DLUA_COMPAT_5_1 \ + -DLUA_COMPAT_MODULE \ $(EOLIST) # diff --git a/modules/lua/README b/modules/lua/README index 0be0adeba0..c8cacb40aa 100644 --- a/modules/lua/README +++ b/modules/lua/README @@ -1,7 +1,7 @@ -*- mode:org -*- * Requirements: -** lua 5.1 ( http://www.lua.org/ ) -** Apache HTTPD 2.2 ( http://httpd.apache.org/ ) or Apache HTTPD 2.3 +** lua 5.1, 5.2, 5.3 ( http://www.lua.org/ ) or LuaJIT 2.x ( http://www.luajit.org/ ) +** Apache HTTPD 2.4 ( http://httpd.apache.org/ ) or higher * Documentation See docs/README @@ -9,32 +9,6 @@ * Building For now, see docs/building-from-subversion.txt -* To Consider - Allow definition of lua_State instances associated with arbitrary - pool using the pool's user_data constuct. There would, here, be two - types, pooled and singleton. On the other hand, singleton would work - fine for almost all cases -- the exception being a process or server - pool, and then we could stay singleton anyway and lock around it. - - The current "server scope" behavior could, instead, fall into - connection scope, for long-lived connections, really we want thread - scope (which Brian Akins knows how to do). Is there a pool - associated with a thread? Contention on the pool is a pain in a - highly concurrent environment. - - Could use apr_thread_data_(get|set) if I can find a way to hook into - thread destruction. Looks like apr threads let you use the standard - APR_POOL_DECLARE_ACCESSOR(thread); defined method, just need to look - up what form that takes. -- apr_thread_pool_get -- just attach to - that pool. - - Given that, we can associate a hash of lua_State instances with - arbitrary pools, such as the request pool, thread pool, server pool, - etc. We then use the file as key into the hash. Users, able to - specify the handler function, can then make use of the same file - with different handlers to reuse states. - - * Task List ** TODO Use r->file to determine file, doing rewriting in translate_name @@ -43,13 +17,8 @@ it is pre-handler, will prolly be on the request_config somewhere, but sometimes cannot put there, so... fun ** TODO Mapping in the server_rec -** TODO Connection scoped vms ** TODO Figure out how reentrancy works regarding filter chain stuff. Do we need new "threads"? -** TODO Flesh out apw_*getvm for each flavor we allow -** TODO Rework apw_sgetvm to use the create_vm stuff like apw_rgetvm -** TODO apw_rgetvm needs to handle connection scoped vms -** TODO provide means to implement authn and authz providers ** TODO: Flatten LuaHook* to LuaHook phase file fn ? ** TODO: document or remove block sections ** TODO: test per-dir behavior of block sections @@ -78,3 +47,5 @@ ** Stefan Fritsch ** Eric Covener ** Daniel Gruno +** Günter Knauf +** Jim Jagielski diff --git a/modules/lua/lua_config.c b/modules/lua/lua_config.c index 3b307ebc0e..bc09bdcffb 100644 --- a/modules/lua/lua_config.c +++ b/modules/lua/lua_config.c @@ -166,6 +166,7 @@ static int cmd_log_at(lua_State *L, int level) lua_getinfo(L, "Sl", &dbg); msg = luaL_checkstring(L, 2); + /* Intentional no APLOGNO */ ap_log_error(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0, cmd->server, "%s", msg); return 0; diff --git a/modules/lua/lua_dbd.c b/modules/lua/lua_dbd.c index 8b61a60b10..1b8d5b7764 100644 --- a/modules/lua/lua_dbd.c +++ b/modules/lua/lua_dbd.c @@ -782,7 +782,7 @@ int lua_db_acquire(lua_State *L) arguments = lua_tostring(L, 3); lua_settop(L, 0); - if (strlen(arguments)) { + if (*arguments) { rc = apr_dbd_open_ex(dbdhandle->driver, pool, arguments, &dbdhandle->handle, &error); if (rc == APR_SUCCESS) { diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c index fbc8887574..4cb4fd0067 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -150,7 +150,7 @@ static int req_aprtable2luatable_cb(void *l, const char *key, } case LUA_TTABLE:{ /* [array, table, table] */ - int size = lua_objlen(L, -1); + int size = lua_rawlen(L, -1); lua_pushnumber(L, size + 1); /* [#, array, table, table] */ lua_pushstring(L, value); /* [string, #, array, table, table] */ lua_settable(L, -3); /* [array, table, table] */ @@ -197,9 +197,10 @@ static int req_aprtable2luatable_cb_len(void *l, const char *key, lua_setfield(L, -2, key); /* [table, table] */ break; } + case LUA_TTABLE:{ /* [array, table, table] */ - int size = lua_objlen(L, -1); + int size = lua_rawlen(L, -1); lua_pushnumber(L, size + 1); /* [#, array, table, table] */ lua_pushlstring(L, value, len); /* [string, #, array, table, table] */ lua_settable(L, -3); /* [array, table, table] */ @@ -285,7 +286,6 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t * len_read, rpos = 0; apr_off_t length = r->remaining; - apr_size_t written; *size = length; while ((len_read = @@ -297,9 +297,7 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t * rsize = len_read; rc = apr_file_write_full(file, argsbuffer, (apr_size_t) rsize, - &written); - if (written != rsize || rc != OK) - return APR_ENOSPC; + NULL); if (rc != APR_SUCCESS) return rc; rpos += rsize; @@ -384,7 +382,7 @@ static int req_parsebody(lua_State *L) sscanf(start + len + 2, "Content-Disposition: form-data; name=\"%255[^\"]\"; filename=\"%255[^\"]\"", key, filename); - if (strlen(key)) { + if (*key) { req_aprtable2luatable_cb_len(L, key, buffer, vlen); } } @@ -663,45 +661,45 @@ static int req_assbackwards_field(request_rec *r) return r->assbackwards; } -static req_table_t *req_headers_in(request_rec *r) +static req_table_t* req_headers_in(request_rec *r) { - req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t)); + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); t->r = r; t->t = r->headers_in; t->n = "headers_in"; return t; } -static req_table_t *req_headers_out(request_rec *r) +static req_table_t* req_headers_out(request_rec *r) { - req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t)); + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); t->r = r; t->t = r->headers_out; t->n = "headers_out"; return t; } -static req_table_t *req_err_headers_out(request_rec *r) +static req_table_t* req_err_headers_out(request_rec *r) { - req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t)); + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); t->r = r; t->t = r->err_headers_out; t->n = "err_headers_out"; return t; } -static req_table_t *req_subprocess_env(request_rec *r) +static req_table_t* req_subprocess_env(request_rec *r) { - req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t)); + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); t->r = r; t->t = r->subprocess_env; t->n = "subprocess_env"; return t; } -static req_table_t *req_notes(request_rec *r) +static req_table_t* req_notes(request_rec *r) { - req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t)); + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); t->r = r; t->t = r->notes; t->n = "notes"; @@ -1896,6 +1894,7 @@ static int req_log_at(lua_State *L, int level) lua_getinfo(L, "Sl", &dbg); msg = luaL_checkstring(L, 2); + /* Intentional no APLOGNO */ ap_log_rerror(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0, r, "%s", msg); return 0; @@ -2111,8 +2110,8 @@ static int lua_set_cookie(lua_State *L) secure ? "Secure;" : "", expires ? strexpires : "", httponly ? "HttpOnly;" : "", - strlen(strdomain) ? strdomain : "", - strlen(strpath) ? strpath : ""); + *strdomain ? strdomain : "", + *strpath ? strpath : ""); apr_table_add(r->err_headers_out, "Set-Cookie", out); return 0; @@ -2160,12 +2159,12 @@ static int lua_websocket_greet(lua_State *L) encoded = apr_palloc(r->pool, encoded_len); encoded_len = apr_base64_encode(encoded, (char*) digest, APR_SHA1_DIGESTSIZE); r->status = 101; - apr_table_set(r->headers_out, "Upgrade", "websocket"); - apr_table_set(r->headers_out, "Connection", "Upgrade"); - apr_table_set(r->headers_out, "Sec-WebSocket-Accept", encoded); + apr_table_setn(r->headers_out, "Upgrade", "websocket"); + apr_table_setn(r->headers_out, "Connection", "Upgrade"); + apr_table_setn(r->headers_out, "Sec-WebSocket-Accept", encoded); /* Trick httpd into NOT using the chunked filter, IMPORTANT!!!111*/ - apr_table_set(r->headers_out, "Transfer-Encoding", "chunked"); + apr_table_setn(r->headers_out, "Transfer-Encoding", "chunked"); r->clength = 0; r->bytes_sent = 0; @@ -2248,24 +2247,9 @@ static int lua_websocket_read(lua_State *L) mask_bytes = apr_pcalloc(r->pool, 4); sock = ap_get_conn_socket(r->connection); - while (do_read) { - do_read = 0; - /* Get opcode and FIN bit */ - if (plaintext) { - rv = apr_socket_recv(sock, &byte, &len); - } - else { - rv = lua_websocket_readbytes(r->connection, &byte, 1); - } - if (rv == APR_SUCCESS) { - unsigned char ubyte, fin, opcode, mask, payload; - ubyte = (unsigned char)byte; - /* fin bit is the first bit */ - fin = ubyte >> (CHAR_BIT - 1); - /* opcode is the last four bits (there's 3 reserved bits we don't care about) */ - opcode = ubyte & 0xf; - - /* Get the payload length and mask bit */ + while (do_read) { + do_read = 0; + /* Get opcode and FIN bit */ if (plaintext) { rv = apr_socket_recv(sock, &byte, &len); } @@ -2273,121 +2257,136 @@ static int lua_websocket_read(lua_State *L) rv = lua_websocket_readbytes(r->connection, &byte, 1); } if (rv == APR_SUCCESS) { + unsigned char ubyte, fin, opcode, mask, payload; ubyte = (unsigned char)byte; - /* Mask is the first bit */ - mask = ubyte >> (CHAR_BIT - 1); - /* Payload is the last 7 bits */ - payload = ubyte & 0x7f; - plen = payload; - - /* Extended payload? */ - if (payload == 126) { - len = 2; - if (plaintext) { - /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */ - rv = apr_socket_recv(sock, (char*) &payload_short, &len); - } - else { - rv = lua_websocket_readbytes(r->connection, - (char*) &payload_short, 2); - } - payload_short = ntohs(payload_short); - - if (rv == APR_SUCCESS) { - plen = payload_short; - } - else { - return 0; - } + /* fin bit is the first bit */ + fin = ubyte >> (CHAR_BIT - 1); + /* opcode is the last four bits (there's 3 reserved bits we don't care about) */ + opcode = ubyte & 0xf; + + /* Get the payload length and mask bit */ + if (plaintext) { + rv = apr_socket_recv(sock, &byte, &len); } - /* Super duper extended payload? */ - if (payload == 127) { - len = 8; - if (plaintext) { - rv = apr_socket_recv(sock, (char*) &payload_long, &len); - } - else { - rv = lua_websocket_readbytes(r->connection, - (char*) &payload_long, 8); - } - if (rv == APR_SUCCESS) { - plen = ap_ntoh64(&payload_long); - } - else { - return 0; - } + else { + rv = lua_websocket_readbytes(r->connection, &byte, 1); } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210) - "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", - plen, - (payload >= 126) ? "extra payload" : "no extra payload", - mask ? "on" : "off", - fin ? "This is a final frame" : "more to follow"); - if (mask) { - len = 4; - if (plaintext) { - rv = apr_socket_recv(sock, (char*) mask_bytes, &len); + if (rv == APR_SUCCESS) { + ubyte = (unsigned char)byte; + /* Mask is the first bit */ + mask = ubyte >> (CHAR_BIT - 1); + /* Payload is the last 7 bits */ + payload = ubyte & 0x7f; + plen = payload; + + /* Extended payload? */ + if (payload == 126) { + len = 2; + if (plaintext) { + /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */ + rv = apr_socket_recv(sock, (char*) &payload_short, &len); + } + else { + rv = lua_websocket_readbytes(r->connection, + (char*) &payload_short, 2); + } + payload_short = ntohs(payload_short); + + if (rv == APR_SUCCESS) { + plen = payload_short; + } + else { + return 0; + } } - else { - rv = lua_websocket_readbytes(r->connection, - (char*) mask_bytes, 4); + /* Super duper extended payload? */ + if (payload == 127) { + len = 8; + if (plaintext) { + rv = apr_socket_recv(sock, (char*) &payload_long, &len); + } + else { + rv = lua_websocket_readbytes(r->connection, + (char*) &payload_long, 8); + } + if (rv == APR_SUCCESS) { + plen = ap_ntoh64(&payload_long); + } + else { + return 0; + } } - if (rv != APR_SUCCESS) { - return 0; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210) + "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", + plen, + (payload >= 126) ? "extra payload" : "no extra payload", + mask ? "on" : "off", + fin ? "This is a final frame" : "more to follow"); + if (mask) { + len = 4; + if (plaintext) { + rv = apr_socket_recv(sock, (char*) mask_bytes, &len); + } + else { + rv = lua_websocket_readbytes(r->connection, + (char*) mask_bytes, 4); + } + if (rv != APR_SUCCESS) { + return 0; + } } - } - if (plen < (HUGE_STRING_LEN*1024) && plen > 0) { - apr_size_t remaining = plen; - apr_size_t received; - apr_off_t at = 0; - char *buffer = apr_palloc(r->pool, plen+1); - buffer[plen] = 0; - - if (plaintext) { - while (remaining > 0) { - received = remaining; - rv = apr_socket_recv(sock, buffer+at, &received); - if (received > 0 ) { - remaining -= received; - at += received; + if (plen < (HUGE_STRING_LEN*1024) && plen > 0) { + apr_size_t remaining = plen; + apr_size_t received; + apr_off_t at = 0; + char *buffer = apr_palloc(r->pool, plen+1); + buffer[plen] = 0; + + if (plaintext) { + while (remaining > 0) { + received = remaining; + rv = apr_socket_recv(sock, buffer+at, &received); + if (received > 0 ) { + remaining -= received; + at += received; + } } + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, + "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack", + at); } - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, - "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack", - at); - } - else { - rv = lua_websocket_readbytes(r->connection, buffer, - remaining); - ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, - "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\ - "pushed to Lua stack", - remaining); - } - if (mask) { - for (n = 0; n < plen; n++) { - buffer[n] ^= mask_bytes[n%4]; + else { + rv = lua_websocket_readbytes(r->connection, buffer, + remaining); + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, + "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\ + "pushed to Lua stack", + remaining); } + if (mask) { + for (n = 0; n < plen; n++) { + buffer[n] ^= mask_bytes[n%4]; + } + } + + lua_pushlstring(L, buffer, (size_t) plen); /* push to stack */ + lua_pushboolean(L, fin); /* push FIN bit to stack as boolean */ + return 2; + } + + + /* Decide if we need to react to the opcode or not */ + if (opcode == 0x09) { /* ping */ + char frame[2]; + plen = 2; + frame[0] = 0x8A; + frame[1] = 0; + apr_socket_send(sock, frame, &plen); /* Pong! */ + do_read = 1; } - - lua_pushlstring(L, buffer, (size_t) plen); /* push to stack */ - lua_pushboolean(L, fin); /* push FIN bit to stack as boolean */ - return 2; - } - - - /* Decide if we need to react to the opcode or not */ - if (opcode == 0x09) { /* ping */ - char frame[2]; - plen = 2; - frame[0] = 0x8A; - frame[1] = 0; - apr_socket_send(sock, frame, &plen); /* Pong! */ - do_read = 1; } } } - } return 0; } @@ -2595,6 +2594,73 @@ static int req_newindex(lua_State *L) return 0; } + + +/* helper function for walking config trees */ +static void read_cfg_tree(lua_State *L, request_rec *r, ap_directive_t *rcfg) { + int x = 0; + const char* value; + ap_directive_t *cfg; + lua_newtable(L); + + for (cfg = rcfg; cfg; cfg = cfg->next) { + x++; + lua_pushnumber(L, x); + lua_newtable(L); + value = apr_psprintf(r->pool, "%s %s", cfg->directive, cfg->args); + lua_pushstring(L, "directive"); + lua_pushstring(L, value); + lua_settable(L, -3); + lua_pushstring(L, "file"); + lua_pushstring(L, cfg->filename); + lua_settable(L, -3); + lua_pushstring(L, "line"); + lua_pushnumber(L, cfg->line_num); + lua_settable(L, -3); + if (cfg->first_child) { + lua_pushstring(L, "children"); + read_cfg_tree(L, r, cfg->first_child); + lua_settable(L, -3); + } + lua_settable(L, -3); + } +} + +static int lua_ap_get_config(lua_State *L) { + request_rec *r = ap_lua_check_request_rec(L, 1); + read_cfg_tree(L, r, ap_conftree); + + return 1; +} + + +/* Hack, hack, hack...! TODO: Make this actually work properly */ +static int lua_ap_get_active_config(lua_State *L) { + ap_directive_t *subdir; + ap_directive_t *dir = ap_conftree; + request_rec *r = ap_lua_check_request_rec(L, 1); + + for (dir = ap_conftree; dir; dir = dir->next) { + if (ap_strcasestr(dir->directive, "first_child) { + for (subdir = dir->first_child; subdir; subdir = subdir->next) { + if (ap_strcasecmp_match(subdir->directive, "servername") && + !ap_strcasecmp_match(r->hostname, subdir->args)) { + read_cfg_tree(L, r, dir->first_child); + return 1; + } + if (ap_strcasecmp_match(subdir->directive, "serveralias") && + !ap_strcasecmp_match(r->hostname, subdir->args)) { + read_cfg_tree(L, r, dir->first_child); + return 1; + } + } + } + } + return 0; +} + + + static const struct luaL_Reg request_methods[] = { {"__index", req_dispatch}, {"__newindex", req_newindex}, @@ -2882,7 +2948,10 @@ void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p) makefun(&lua_websocket_close, APL_REQ_FUNTYPE_LUACFUN, p)); apr_hash_set(dispatch, "wsping", APR_HASH_KEY_STRING, makefun(&lua_websocket_ping, APL_REQ_FUNTYPE_LUACFUN, p)); - + apr_hash_set(dispatch, "config", APR_HASH_KEY_STRING, + makefun(&lua_ap_get_config, APL_REQ_FUNTYPE_LUACFUN, p)); + apr_hash_set(dispatch, "activeconfig", APR_HASH_KEY_STRING, + makefun(&lua_ap_get_active_config, APL_REQ_FUNTYPE_LUACFUN, p)); lua_pushlightuserdata(L, dispatch); lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch"); @@ -2914,7 +2983,7 @@ void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p) void ap_lua_push_connection(lua_State *L, conn_rec *c) { - req_table_t *t; + req_table_t* t; lua_boxpointer(L, c); luaL_getmetatable(L, "Apache2.Connection"); lua_setmetatable(L, -2); diff --git a/modules/lua/lua_request.h b/modules/lua/lua_request.h index eee6a7a8aa..a39f4b97b1 100644 --- a/modules/lua/lua_request.h +++ b/modules/lua/lua_request.h @@ -44,7 +44,7 @@ typedef struct { request_rec *r; /* Request_rec */ apr_table_t *t; /* apr_table_t* */ - char *n; /* name of table */ + const char *n; /* name of table */ } req_table_t; typedef struct { diff --git a/modules/lua/lua_vmprep.c b/modules/lua/lua_vmprep.c index 5a639e0e58..e6d68cf000 100644 --- a/modules/lua/lua_vmprep.c +++ b/modules/lua/lua_vmprep.c @@ -37,12 +37,28 @@ APLOG_USE_MODULE(lua); #if APR_HAS_THREADS apr_thread_mutex_t *ap_lua_mutex; +#endif +extern apr_global_mutex_t *lua_ivm_mutex; void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s) { + apr_status_t rv; + + /* global IVM mutex */ + rv = apr_global_mutex_child_init(&lua_ivm_mutex, + apr_global_mutex_lockfile(lua_ivm_mutex), + pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03016) + "mod_lua: Failed to reopen mutex lua-ivm-shm in child"); + exit(1); /* bah :( */ + } + + /* Server pool mutex */ +#if APR_HAS_THREADS apr_thread_mutex_create(&ap_lua_mutex, APR_THREAD_MUTEX_DEFAULT, pool); -} #endif +} /* forward dec'l from this file */ @@ -455,6 +471,9 @@ lua_State *ap_lua_get_lua_state(apr_pool_t *lifecycle_pool, cache_info = sspec->finfo; } else { +#if APR_HAS_THREADS + apr_thread_mutex_unlock(ap_lua_mutex); +#endif return NULL; } } diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c index b73d9cbd03..46e71f3652 100644 --- a/modules/lua/mod_lua.c +++ b/modules/lua/mod_lua.c @@ -83,6 +83,8 @@ typedef struct int broken; } lua_filter_ctx; +#define DEFAULT_LUA_SHMFILE "lua_ivm_shm" + apr_global_mutex_t *lua_ivm_mutex; apr_shm_t *lua_ivm_shm; char *lua_ivm_shmfile; @@ -1979,8 +1981,6 @@ static void *create_server_config(apr_pool_t *p, server_rec *s) { ap_lua_server_cfg *cfg = apr_pcalloc(p, sizeof(ap_lua_server_cfg)); - cfg->vm_reslists = apr_hash_make(p); - apr_thread_rwlock_create(&cfg->vm_reslists_lock, p); cfg->root_path = NULL; return cfg; @@ -2003,7 +2003,6 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_pool_t **pool; - const char *tempdir; apr_status_t rs; lua_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); @@ -2019,21 +2018,20 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog, return HTTP_INTERNAL_SERVER_ERROR; } - /* Create shared memory space */ - rs = apr_temp_dir_get(&tempdir, pconf); - if (rs != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02664) - "mod_lua IVM: Failed to find temporary directory"); - return HTTP_INTERNAL_SERVER_ERROR; + /* Create shared memory space, anonymous first if possible. */ + rs = apr_shm_create(&lua_ivm_shm, sizeof pool, NULL, pconf); + if (APR_STATUS_IS_ENOTIMPL(rs)) { + /* Fall back to filename-based; nuke any left-over first. */ + lua_ivm_shmfile = ap_runtime_dir_relative(pconf, DEFAULT_LUA_SHMFILE); + + apr_shm_remove(lua_ivm_shmfile, pconf); + + rs = apr_shm_create(&lua_ivm_shm, sizeof pool, lua_ivm_shmfile, pconf); } - lua_ivm_shmfile = apr_psprintf(pconf, "%s/httpd_lua_shm.%ld", tempdir, - (long int)getpid()); - rs = apr_shm_create(&lua_ivm_shm, sizeof(apr_pool_t**), - (const char *) lua_ivm_shmfile, pconf); if (rs != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02665) "mod_lua: Failed to create shared memory segment on file %s", - lua_ivm_shmfile); + lua_ivm_shmfile ? lua_ivm_shmfile : "(anonymous)"); return HTTP_INTERNAL_SERVER_ERROR; } pool = (apr_pool_t **)apr_shm_baseaddr_get(lua_ivm_shm); diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h index 7fd115330b..cd2025b1b7 100644 --- a/modules/lua/mod_lua.h +++ b/modules/lua/mod_lua.h @@ -43,6 +43,10 @@ /* Allow for Lua 5.2 backwards compatibility */ #define LUA_COMPAT_ALL +/* Allow for Lua 5.3 backwards compatibility */ +#define LUA_COMPAT_5_2 +#define LUA_COMPAT_5_1 +#define LUA_COMPAT_MODULE #include "lua.h" #include "lauxlib.h" @@ -52,6 +56,8 @@ /* Load mode for lua_load() */ #define lua_load(a,b,c,d) lua_load(a,b,c,d,NULL) #define lua_resume(a,b) lua_resume(a, NULL, b) +#else +#define lua_rawlen(L,i) lua_objlen(L, (i)) #endif /* Create a set of AP_LUA_DECLARE(type), AP_LUA_DECLARE_NONSTD(type) and @@ -135,9 +141,6 @@ typedef struct typedef struct { - apr_hash_t *vm_reslists; - apr_thread_rwlock_t *vm_reslists_lock; - /* value of the LuaRoot directive */ const char *root_path; } ap_lua_server_cfg;