summaryrefslogtreecommitdiffstats
path: root/modules/lua
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-25 04:41:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-25 04:41:27 +0000
commitc54018b07a9085c0a3aedbc2bd01a85a3b3e20cf (patch)
treef6e1d6fcf9f6db3794c418b2f89ecf9e08ff41c8 /modules/lua
parentAdding debian version 2.4.38-3+deb10u10. (diff)
downloadapache2-c54018b07a9085c0a3aedbc2bd01a85a3b3e20cf.tar.xz
apache2-c54018b07a9085c0a3aedbc2bd01a85a3b3e20cf.zip
Merging upstream version 2.4.59.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/lua')
-rw-r--r--modules/lua/config.m433
-rw-r--r--modules/lua/lua_apr.c8
-rw-r--r--modules/lua/lua_request.c225
-rw-r--r--modules/lua/mod_lua.c71
-rw-r--r--modules/lua/mod_lua.h12
5 files changed, 206 insertions, 143 deletions
diff --git a/modules/lua/config.m4 b/modules/lua/config.m4
index 29fd563..40ae6f0 100644
--- a/modules/lua/config.m4
+++ b/modules/lua/config.m4
@@ -34,7 +34,7 @@ AC_DEFUN([CHECK_LUA_PATH], [dnl
fi
])
-dnl Check for Lua 5.3/5.2/5.1 Libraries
+dnl Check for Lua Libraries
dnl CHECK_LUA(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
dnl Sets:
dnl LUA_CFLAGS
@@ -44,7 +44,7 @@ AC_DEFUN([CHECK_LUA],
AC_ARG_WITH(
lua,
- [AC_HELP_STRING([--with-lua=PATH],[Path to the Lua 5.3/5.2/5.1 prefix])],
+ [AC_HELP_STRING([--with-lua=PATH],[Path to the Lua installation prefix])],
lua_path="$withval",
:)
@@ -55,16 +55,25 @@ else
test_paths="${lua_path}"
fi
-if test -n "$PKGCONFIG" -a -z "$lua_path" \
- && $PKGCONFIG --atleast-version=5.1 lua; then
- LUA_LIBS="`$PKGCONFIG --libs lua`"
- LUA_CFLAGS="`$PKGCONFIG --cflags lua`"
- LUA_VERSION="`$PKGCONFIG --modversion lua`"
- AC_MSG_NOTICE([using Lua $LUA_VERSION configuration from pkg-config])
-else
+for pklua in lua lua5.4 lua5.3 lua5.2 lua5.1; do
+ if test -n "$PKGCONFIG" -a -z "$lua_path" \
+ && $PKGCONFIG --atleast-version=5.1 $pklua; then
+ LUA_LIBS="`$PKGCONFIG --libs $pklua`"
+ LUA_CFLAGS="`$PKGCONFIG --cflags $pklua`"
+ LUA_VERSION="`$PKGCONFIG --modversion $pklua`"
+ AC_MSG_NOTICE([using Lua $LUA_VERSION configuration from pkg-config])
+ break
+ fi
+done
+
+if test -z "$LUA_VERSION"; then
AC_CHECK_LIB(m, pow, lib_m="-lm")
AC_CHECK_LIB(m, sqrt, lib_m="-lm")
for x in $test_paths ; do
+ CHECK_LUA_PATH([${x}], [include/lua-5.4], [lib/lua-5.4], [lua-5.4])
+ CHECK_LUA_PATH([${x}], [include/lua5.4], [lib], [lua5.4])
+ CHECK_LUA_PATH([${x}], [include/lua54], [lib/lua54], [lua])
+
CHECK_LUA_PATH([${x}], [include/lua-5.3], [lib/lua-5.3], [lua-5.3])
CHECK_LUA_PATH([${x}], [include/lua5.3], [lib], [lua5.3])
CHECK_LUA_PATH([${x}], [include/lua53], [lib/lua53], [lua])
@@ -85,13 +94,13 @@ AC_SUBST(LUA_LIBS)
AC_SUBST(LUA_CFLAGS)
if test -z "${LUA_LIBS}"; then
- AC_MSG_WARN([*** Lua 5.3 5.2 or 5.1 library not found.])
+ AC_MSG_WARN([*** Lua 5.4 5.3 5.2 or 5.1 library not found.])
ifelse([$2], ,
enable_lua="no"
if test -z "${lua_path}"; then
- AC_MSG_WARN([Lua 5.3 5.2 or 5.1 library is required])
+ AC_MSG_WARN([Lua 5.4 5.3 5.2 or 5.1 library is required])
else
- AC_MSG_ERROR([Lua 5.3 5.2 or 5.1 library is required])
+ AC_MSG_ERROR([Lua 5.4 5.3 5.2 or 5.1 library is required])
fi,
$2)
else
diff --git a/modules/lua/lua_apr.c b/modules/lua/lua_apr.c
index 8e34cf3..9590fd6 100644
--- a/modules/lua/lua_apr.c
+++ b/modules/lua/lua_apr.c
@@ -39,7 +39,13 @@ static int lua_table_set(lua_State *L)
{
req_table_t *t = ap_lua_check_apr_table(L, 1);
const char *key = luaL_checkstring(L, 2);
- const char *val = luaL_checkstring(L, 3);
+ const char *val = luaL_optlstring(L, 3, NULL, NULL);
+
+ if (!val) {
+ apr_table_unset(t->t, key);
+ return 0;
+ }
+
/* Unless it's the 'notes' table, check for newline chars */
/* t->r will be NULL in case of the connection notes, but since
we aren't going to check anything called 'notes', we can safely
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index 77a88b4..bec8580 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -235,33 +235,36 @@ static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size,
{
int rc = OK;
+ *rbuf = NULL;
+ *size = 0;
+
if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
return (rc);
}
if (ap_should_client_block(r)) {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- char argsbuffer[HUGE_STRING_LEN];
- apr_off_t rsize, len_read, rpos = 0;
+ apr_off_t len_read = -1;
+ apr_off_t rpos = 0;
apr_off_t length = r->remaining;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (maxsize != 0 && length > maxsize) {
return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */
}
- *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1));
- *size = length;
- while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
- if ((rpos + len_read) > length) {
- rsize = length - rpos;
- }
- else {
- rsize = len_read;
- }
-
- memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize);
- rpos += rsize;
+ *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length) + 1);
+ while ((rpos < length)
+ && (len_read = ap_get_client_block(r, (char *) *rbuf + rpos,
+ length - rpos)) > 0) {
+ rpos += len_read;
+ }
+ if (len_read < 0) {
+ return APR_EINCOMPLETE;
}
+ *size = rpos;
+ }
+ else {
+ rc = DONE;
}
return (rc);
@@ -278,6 +281,8 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t *
{
apr_status_t rc = OK;
+ *size = 0;
+
if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
return rc;
if (ap_should_client_block(r)) {
@@ -303,10 +308,47 @@ static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t *
rpos += rsize;
}
}
+ else {
+ rc = DONE;
+ }
return rc;
}
+/* expose apr_table as (r/o) lua table */
+static int req_aprtable2luatable(lua_State *L, apr_table_t *t)
+{
+ lua_newtable(L);
+ lua_newtable(L); /* [table, table] */
+ apr_table_do(req_aprtable2luatable_cb, L, t, NULL);
+ return 2; /* [table<string, string>, table<string, array<string>>] */
+}
+
+static int req_headers_in_table(lua_State *L)
+{
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ return req_aprtable2luatable(L, r->headers_in);
+}
+static int req_headers_out_table(lua_State *L)
+{
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ return req_aprtable2luatable(L, r->headers_out);
+}
+static int req_err_headers_out_table(lua_State *L)
+{
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ return req_aprtable2luatable(L, r->err_headers_out);
+}
+static int req_notes_table(lua_State *L)
+{
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ return req_aprtable2luatable(L, r->notes);
+}
+static int req_subprocess_env_table(lua_State *L)
+{
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ return req_aprtable2luatable(L, r->subprocess_env);
+}
/* r:parseargs() returning a lua table */
static int req_parseargs(lua_State *L)
{
@@ -376,6 +418,7 @@ static int req_parsebody(lua_State *L)
if (end == NULL) break;
key = (char *) apr_pcalloc(r->pool, 256);
filename = (char *) apr_pcalloc(r->pool, 256);
+ if (end - crlf <= 8) break;
vlen = end - crlf - 8;
buffer = (char *) apr_pcalloc(r->pool, vlen+1);
memcpy(buffer, crlf + 4, vlen);
@@ -2185,23 +2228,20 @@ static int lua_websocket_greet(lua_State *L)
return 0;
}
-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer,
- apr_off_t len)
+static apr_status_t lua_websocket_readbytes(conn_rec* c,
+ apr_bucket_brigade *brigade,
+ char* buffer, apr_off_t len)
{
- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
+ apr_size_t delivered;
apr_status_t rv;
+
rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
APR_BLOCK_READ, len);
if (rv == APR_SUCCESS) {
- if (!APR_BRIGADE_EMPTY(brigade)) {
- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade);
- const char* data = NULL;
- apr_size_t data_length = 0;
- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
- if (rv == APR_SUCCESS) {
- memcpy(buffer, data, len);
- }
- apr_bucket_delete(bucket);
+ delivered = len;
+ rv = apr_brigade_flatten(brigade, buffer, &delivered);
+ if ((rv == APR_SUCCESS) && (delivered < len)) {
+ rv = APR_INCOMPLETE;
}
}
apr_brigade_cleanup(brigade);
@@ -2231,35 +2271,28 @@ static int lua_websocket_peek(lua_State *L)
static int lua_websocket_read(lua_State *L)
{
- apr_socket_t *sock;
apr_status_t rv;
int do_read = 1;
int n = 0;
- apr_size_t len = 1;
apr_size_t plen = 0;
unsigned short payload_short = 0;
apr_uint64_t payload_long = 0;
unsigned char *mask_bytes;
char byte;
- int plaintext;
-
-
+ apr_bucket_brigade *brigade;
+ conn_rec* c;
+
request_rec *r = ap_lua_check_request_rec(L, 1);
- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
+ c = r->connection;
-
mask_bytes = apr_pcalloc(r->pool, 4);
- sock = ap_get_conn_socket(r->connection);
+
+ brigade = apr_brigade_create(r->pool, c->bucket_alloc);
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);
- }
+ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
if (rv == APR_SUCCESS) {
unsigned char ubyte, fin, opcode, mask, payload;
ubyte = (unsigned char)byte;
@@ -2269,12 +2302,7 @@ static int lua_websocket_read(lua_State *L)
opcode = ubyte & 0xf;
/* Get the payload length and mask bit */
- if (plaintext) {
- rv = apr_socket_recv(sock, &byte, &len);
- }
- else {
- rv = lua_websocket_readbytes(r->connection, &byte, 1);
- }
+ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
if (rv == APR_SUCCESS) {
ubyte = (unsigned char)byte;
/* Mask is the first bit */
@@ -2285,40 +2313,25 @@ static int lua_websocket_read(lua_State *L)
/* 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);
+ rv = lua_websocket_readbytes(c, brigade,
+ (char*) &payload_short, 2);
- if (rv == APR_SUCCESS) {
- plen = payload_short;
- }
- else {
+ if (rv != APR_SUCCESS) {
return 0;
}
+
+ plen = ntohs(payload_short);
}
/* 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 {
+ rv = lua_websocket_readbytes(c, brigade,
+ (char*) &payload_long, 8);
+
+ if (rv != APR_SUCCESS) {
return 0;
}
+
+ plen = ap_ntoh64(&payload_long);
}
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
"Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
@@ -2327,46 +2340,27 @@ static int lua_websocket_read(lua_State *L)
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);
- }
+ rv = lua_websocket_readbytes(c, brigade,
+ (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;
- }
- }
- 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);
+ rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
+
+ if (rv != APR_SUCCESS) {
+ return 0;
}
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "Websocket: 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];
@@ -2378,14 +2372,25 @@ static int lua_websocket_read(lua_State *L)
return 2;
}
-
/* Decide if we need to react to the opcode or not */
if (opcode == 0x09) { /* ping */
char frame[2];
- plen = 2;
+ apr_bucket *b;
+
frame[0] = 0x8A;
frame[1] = 0;
- apr_socket_send(sock, frame, &plen); /* Pong! */
+
+ /* Pong! */
+ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(brigade, b);
+
+ rv = ap_pass_brigade(c->output_filters, brigade);
+ apr_brigade_cleanup(brigade);
+
+ if (rv != APR_SUCCESS) {
+ return 0;
+ }
+
do_read = 1;
}
}
@@ -2814,14 +2819,24 @@ void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_proxyreq_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "headers_in", APR_HASH_KEY_STRING,
makefun(&req_headers_in, APL_REQ_FUNTYPE_TABLE, p));
+ apr_hash_set(dispatch, "headers_in_table", APR_HASH_KEY_STRING,
+ makefun(&req_headers_in_table, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "headers_out", APR_HASH_KEY_STRING,
makefun(&req_headers_out, APL_REQ_FUNTYPE_TABLE, p));
+ apr_hash_set(dispatch, "headers_out_table", APR_HASH_KEY_STRING,
+ makefun(&req_headers_out_table, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "err_headers_out", APR_HASH_KEY_STRING,
makefun(&req_err_headers_out, APL_REQ_FUNTYPE_TABLE, p));
+ apr_hash_set(dispatch, "err_headers_out_table", APR_HASH_KEY_STRING,
+ makefun(&req_err_headers_out_table, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "notes", APR_HASH_KEY_STRING,
makefun(&req_notes, APL_REQ_FUNTYPE_TABLE, p));
+ apr_hash_set(dispatch, "notes_table", APR_HASH_KEY_STRING,
+ makefun(&req_notes_table, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "subprocess_env", APR_HASH_KEY_STRING,
makefun(&req_subprocess_env, APL_REQ_FUNTYPE_TABLE, p));
+ apr_hash_set(dispatch, "subprocess_env_table", APR_HASH_KEY_STRING,
+ makefun(&req_subprocess_env_table, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "flush", APR_HASH_KEY_STRING,
makefun(&lua_ap_rflush, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "port", APR_HASH_KEY_STRING,
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 6d79199..303890e 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -24,7 +24,6 @@
#include "lua_apr.h"
#include "lua_config.h"
#include "apr_optional.h"
-#include "mod_ssl.h"
#include "mod_auth.h"
#include "util_mutex.h"
@@ -53,8 +52,6 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open,
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
(lua_State *L, request_rec *r),
(L, r), OK, DECLINED)
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *lua_ssl_val = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *lua_ssl_is_https = NULL;
module AP_MODULE_DECLARE_DATA lua_module;
@@ -216,6 +213,7 @@ static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
case AP_LUA_SCOPE_ONCE:
case AP_LUA_SCOPE_UNSET:
apr_pool_create(&pool, r->pool);
+ apr_pool_tag(pool, "mod_lua-vm");
break;
case AP_LUA_SCOPE_REQUEST:
pool = r->pool;
@@ -341,7 +339,7 @@ static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_fil
{
apr_pool_t *pool;
ap_lua_vm_spec *spec;
- int n, rc;
+ int n, rc, nres;
lua_State *L;
lua_filter_ctx *ctx;
ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
@@ -409,7 +407,7 @@ static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_fil
/* If a Lua filter is interested in filtering a request, it must first do a yield,
* otherwise we'll assume that it's not interested and pretend we didn't find it.
*/
- rc = lua_resume(L, 1);
+ rc = lua_resume(L, 1, &nres);
if (rc == LUA_YIELD) {
if (f->frec->providers == NULL) {
/* Not wired by mod_filter */
@@ -431,7 +429,7 @@ static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_fil
static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade *pbbIn)
{
request_rec *r = f->r;
- int rc;
+ int rc, nres;
lua_State *L;
lua_filter_ctx* ctx;
conn_rec *c = r->connection;
@@ -491,7 +489,7 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
lua_setglobal(L, "bucket");
/* If Lua yielded, it means we have something to pass on */
- if (lua_resume(L, 0) == LUA_YIELD) {
+ if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
if (olen > 0) {
@@ -523,7 +521,7 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
apr_bucket *pbktEOS;
lua_pushnil(L);
lua_setglobal(L, "bucket");
- if (lua_resume(L, 0) == LUA_YIELD) {
+ if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
apr_bucket *pbktOut;
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
@@ -557,7 +555,7 @@ static apr_status_t lua_input_filter_handle(ap_filter_t *f,
apr_off_t nBytes)
{
request_rec *r = f->r;
- int rc, lastCall = 0;
+ int rc, lastCall = 0, nres;
lua_State *L;
lua_filter_ctx* ctx;
conn_rec *c = r->connection;
@@ -620,7 +618,7 @@ static apr_status_t lua_input_filter_handle(ap_filter_t *f,
lua_setglobal(L, "bucket");
/* If Lua yielded, it means we have something to pass on */
- if (lua_resume(L, 0) == LUA_YIELD) {
+ if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
pbktOut = apr_bucket_heap_create(output, olen, 0, c->bucket_alloc);
@@ -642,7 +640,7 @@ static apr_status_t lua_input_filter_handle(ap_filter_t *f,
apr_bucket *pbktEOS = apr_bucket_eos_create(c->bucket_alloc);
lua_pushnil(L);
lua_setglobal(L, "bucket");
- if (lua_resume(L, 0) == LUA_YIELD) {
+ if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
apr_bucket *pbktOut;
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
@@ -1204,6 +1202,11 @@ static int lua_check_user_id_harness_last(request_rec *r)
}
*/
+static int lua_pre_trans_name_harness(request_rec *r)
+{
+ return lua_request_rec_hook_harness(r, "pre_translate_name", APR_HOOK_MIDDLE);
+}
+
static int lua_translate_name_harness_first(request_rec *r)
{
return lua_request_rec_hook_harness(r, "translate_name", AP_LUA_HOOK_FIRST);
@@ -1276,6 +1279,21 @@ static int lua_quick_harness(request_rec *r, int lookup)
return lua_request_rec_hook_harness(r, "quick", APR_HOOK_MIDDLE);
}
+static const char *register_pre_trans_name_hook(cmd_parms *cmd, void *_cfg,
+ const char *file,
+ const char *function)
+{
+ return register_named_file_function_hook("pre_translate_name", cmd, _cfg, file,
+ function, APR_HOOK_MIDDLE);
+}
+
+static const char *register_pre_trans_name_block(cmd_parms *cmd, void *_cfg,
+ const char *line)
+{
+ return register_named_block_function_hook("pre_translate_name", cmd, _cfg,
+ line);
+}
+
static const char *register_translate_name_hook(cmd_parms *cmd, void *_cfg,
const char *file,
const char *function,
@@ -1632,7 +1650,7 @@ static const char *register_lua_scope(cmd_parms *cmd,
return apr_psprintf(cmd->pool,
"Scope type of '%s' cannot be used because this "
"server does not have threading support "
- "(APR_HAS_THREADS)"
+ "(APR_HAS_THREADS)",
scope);
#endif
cfg->vm_scope = AP_LUA_SCOPE_THREAD;
@@ -1643,7 +1661,7 @@ static const char *register_lua_scope(cmd_parms *cmd,
return apr_psprintf(cmd->pool,
"Scope type of '%s' cannot be used because this "
"server does not have threading support "
- "(APR_HAS_THREADS)"
+ "(APR_HAS_THREADS)",
scope);
#endif
cfg->vm_scope = AP_LUA_SCOPE_SERVER;
@@ -1687,15 +1705,12 @@ static const char *register_lua_root(cmd_parms *cmd, void *_cfg,
const char *ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c,
request_rec *r, const char *var)
{
- if (lua_ssl_val) {
- return (const char *)lua_ssl_val(p, s, c, r, (char *)var);
- }
- return NULL;
+ return ap_ssl_var_lookup(p, s, c, r, var);
}
int ap_lua_ssl_is_https(conn_rec *c)
{
- return lua_ssl_is_https ? lua_ssl_is_https(c) : 0;
+ return ap_ssl_conn_is_ssl(c);
}
/*******************************/
@@ -1833,7 +1848,7 @@ static const char *register_authz_provider(cmd_parms *cmd, void *_cfg,
}
-command_rec lua_commands[] = {
+static const command_rec lua_commands[] = {
AP_INIT_TAKE1("LuaRoot", register_lua_root, NULL, OR_ALL,
"Specify the base path for resolving relative paths for mod_lua directives"),
@@ -1847,6 +1862,14 @@ command_rec lua_commands[] = {
AP_INIT_TAKE3("LuaAuthzProvider", register_authz_provider, NULL, RSRC_CONF|EXEC_ON_READ,
"Provide an authorization provider"),
+ AP_INIT_TAKE2("LuaHookPreTranslateName", register_pre_trans_name_hook, NULL,
+ OR_ALL,
+ "Provide a hook for the pre_translate name phase of request processing"),
+
+ AP_INIT_RAW_ARGS("<LuaHookPreTranslateName", register_pre_trans_name_block, NULL,
+ EXEC_ON_READ | OR_ALL,
+ "Provide a hook for the pre_translate name phase of request processing"),
+
AP_INIT_TAKE23("LuaHookTranslateName", register_translate_name_hook, NULL,
OR_ALL,
"Provide a hook for the translate name phase of request processing"),
@@ -2001,9 +2024,6 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t **pool;
apr_status_t rs;
- lua_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
- lua_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-
if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
return OK;
@@ -2032,6 +2052,7 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
}
pool = (apr_pool_t **)apr_shm_baseaddr_get(lua_ivm_shm);
apr_pool_create(pool, pconf);
+ apr_pool_tag(*pool, "mod_lua-shared");
apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper,
apr_pool_cleanup_null);
return OK;
@@ -2099,6 +2120,9 @@ static void lua_register_hooks(apr_pool_t *p)
APR_HOOK_MIDDLE);
/* http_request.h hooks */
+ ap_hook_pre_translate_name(lua_pre_trans_name_harness, NULL, NULL,
+ APR_HOOK_MIDDLE);
+
ap_hook_translate_name(lua_translate_name_harness_first, NULL, NULL,
AP_LUA_HOOK_FIRST);
ap_hook_translate_name(lua_translate_name_harness, NULL, NULL,
@@ -2152,9 +2176,8 @@ static void lua_register_hooks(apr_pool_t *p)
/* Hook this right before FallbackResource kicks in */
ap_hook_fixups(lua_map_handler_fixups, NULL, NULL, AP_LUA_HOOK_LAST-2);
-#if APR_HAS_THREADS
ap_hook_child_init(ap_lua_init_mutex, NULL, NULL, APR_HOOK_MIDDLE);
-#endif
+
/* providers */
lua_authz_providers = apr_hash_make(p);
diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h
index 0e49cdc..33807fb 100644
--- a/modules/lua/mod_lua.h
+++ b/modules/lua/mod_lua.h
@@ -26,6 +26,7 @@
#include "http_request.h"
#include "http_log.h"
#include "http_protocol.h"
+#include "http_ssl.h"
#include "ap_regex.h"
#include "ap_config.h"
@@ -48,11 +49,20 @@
#if LUA_VERSION_NUM > 501
/* 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)
+
+#if LUA_VERSION_NUM > 503
+#define lua_resume(a,b,c) lua_resume(a, NULL, b, c)
+#else
+/* ### For version < 5.4, assume that exactly one stack item is on the
+ * stack, which is what the code did before but seems dubious. */
+#define lua_resume(a,b,c) (*(c) = 1, lua_resume(a, NULL, b))
+#endif
+
#define luaL_setfuncs_compat(a,b) luaL_setfuncs(a,b,0)
#else
#define lua_rawlen(L,i) lua_objlen(L, (i))
#define luaL_setfuncs_compat(a,b) luaL_register(a,NULL,b)
+#define lua_resume(a,b,c) (*(c) = 1, lua_resume(a, b))
#endif
#if LUA_VERSION_NUM > 502
#define lua_dump(a,b,c) lua_dump(a,b,c,0)