]> granicus.if.org Git - apache/commitdiff
Backport of Lua exhancements from trunk, mostly to support 5.3
authorJim Jagielski <jim@apache.org>
Wed, 1 Mar 2017 16:54:35 +0000 (16:54 +0000)
committerJim Jagielski <jim@apache.org>
Wed, 1 Mar 2017 16:54:35 +0000 (16:54 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1784990 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/lua/NWGNUmakefile
modules/lua/README
modules/lua/lua_config.c
modules/lua/lua_dbd.c
modules/lua/lua_request.c
modules/lua/lua_request.h
modules/lua/lua_vmprep.c
modules/lua/mod_lua.c
modules/lua/mod_lua.h

diff --git a/CHANGES b/CHANGES
index 77140268f97b9cfb63a1f5a2448522473faa7af6..6aa5c6badfc31c5d8c9ff79ab2ccdaa167c74585 100644 (file)
--- 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.
index fd86b3c9ee6de33b2cf50999e1b4a1816f8aa63b..24f2703f58ea79da22781800bdb17f564b9f7126 100644 (file)
@@ -46,6 +46,9 @@ XCFLAGS               += \
 #
 XDEFINES       += \
                        -DLUA_COMPAT_ALL \
+                       -DLUA_COMPAT_5_2 \
+                       -DLUA_COMPAT_5_1 \
+                       -DLUA_COMPAT_MODULE \
                        $(EOLIST)
 
 #
index 0be0adeba05a7805d705c799801367410951a472..c8cacb40aa8548b7e39d793635c143dae282f89c 100644 (file)
@@ -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   
    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
index 3b307ebc0e4d7ca2eaedbc1f745ea4e97b7f925c..bc09bdcffb444f10b7e9b83c49177a5763bddde1 100644 (file)
@@ -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;
index 8b61a60b10752d9501cff86d8a5d9ff067ee2928..1b8d5b7764d17606c34ec5e2c22ba92aa2ae18ce 100644 (file)
@@ -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) {
index fbc88875747f222424d956e81e81f3883e5b3e70..4cb4fd00674333eef8a9cda54a776a6dde2acca5 100644 (file)
@@ -150,7 +150,7 @@ static int req_aprtable2luatable_cb(void *l, const char *key,
         }
     case LUA_TTABLE:{
             /* [array, table<s,t>, table<s,s>] */
-            int size = lua_objlen(L, -1);
+            int size = lua_rawlen(L, -1);
             lua_pushnumber(L, size + 1);        /* [#, array, table<s,t>, table<s,s>] */
             lua_pushstring(L, value);   /* [string, #, array, table<s,t>, table<s,s>] */
             lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>] */
@@ -197,9 +197,10 @@ static int req_aprtable2luatable_cb_len(void *l, const char *key,
             lua_setfield(L, -2, key);   /* [table<s,t>, table<s,s>] */
             break;
         }
+    
     case LUA_TTABLE:{
             /* [array, table<s,t>, table<s,s>] */
-            int size = lua_objlen(L, -1);
+            int size = lua_rawlen(L, -1);
             lua_pushnumber(L, size + 1);        /* [#, array, table<s,t>, table<s,s>] */
             lua_pushlstring(L, value, len);   /* [string, #, array, table<s,t>, table<s,s>] */
             lua_settable(L, -3);        /* [array, table<s,t>, table<s,s>] */
@@ -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_treq_headers_in(request_rec *r)
 {
-  req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t));
+  req_table_tt = 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_treq_headers_out(request_rec *r)
 {
-  req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t));
+  req_table_tt = 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_treq_err_headers_out(request_rec *r)
 {
-  req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t));
+  req_table_tt = 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_treq_subprocess_env(request_rec *r)
 {
-  req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t));
+  req_table_tt = 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_treq_notes(request_rec *r)
 {
-  req_table_t *t = apr_palloc(r->pool, sizeof(req_table_t));
+  req_table_tt = 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, "<virtualhost") && dir->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_tt;
     lua_boxpointer(L, c);
     luaL_getmetatable(L, "Apache2.Connection");
     lua_setmetatable(L, -2);
index eee6a7a8aaadc8c0b9842d862c0658079e10fb2d..a39f4b97b1b1b89994cddf8b89f8117b29b33e84 100644 (file)
@@ -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 {
index 5a639e0e588075cf162d578d1feb8ff30611f920..e6d68cf000a7a9955c2c5ee65e2588dfeb5ec162 100644 (file)
@@ -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;
                 }
             }
index b73d9cbd030f306f16566e109f5a0aaf65b9d496..46e71f365225eae2f96cbfe23e91ac6b3ed4227a 100644 (file)
@@ -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);
index 7fd115330b2b6cac7cc4039af2a56fd340343130..cd2025b1b760329d10e8d08079c58718bab4fb50 100644 (file)
 
 /* 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;