summaryrefslogtreecommitdiff
path: root/modules/lua
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2013-12-23 23:50:09 -1100
committerArno Töll <arno@debian.org>2013-12-23 23:50:09 -1100
commit86d5cc79d9d6750da8771fdb0c9ab22c19b8ad45 (patch)
tree5037da70bf37c0ee93f0ea09f054bdfb278befe0 /modules/lua
parent4a336a5b117419c33c29eadd6409c69df78cd586 (diff)
downloadapache2-86d5cc79d9d6750da8771fdb0c9ab22c19b8ad45.tar.gz
Imported Upstream version 2.4.7upstream/2.4.7
Diffstat (limited to 'modules/lua')
-rw-r--r--modules/lua/lua_passwd.h1
-rw-r--r--modules/lua/lua_request.c434
-rw-r--r--modules/lua/mod_lua.c89
-rw-r--r--modules/lua/mod_lua.dsp8
4 files changed, 509 insertions, 23 deletions
diff --git a/modules/lua/lua_passwd.h b/modules/lua/lua_passwd.h
index 797556bf..8606cc1d 100644
--- a/modules/lua/lua_passwd.h
+++ b/modules/lua/lua_passwd.h
@@ -70,7 +70,6 @@ struct passwd_ctx {
const char *errstr;
char *out;
apr_size_t out_len;
-// const char *passwd;
char *passwd;
int alg;
int cost;
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index c2cfb535..8dce13cc 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -26,8 +26,9 @@
#include "apr_date.h"
#include "apr_pools.h"
#include "apr_thread_mutex.h"
-
-#include <lua.h>
+#include "apr_tables.h"
+#include "util_cookies.h"
+#include "apr_want.h"
extern apr_thread_mutex_t* lua_ivm_mutex;
@@ -839,6 +840,7 @@ static int lua_apr_sha1(lua_State *L)
apr_sha1_init(&sha1);
apr_sha1_update(&sha1, buffer, len);
apr_sha1_final(digest, &sha1);
+
ap_bin2hex(digest, sizeof(digest), result);
lua_pushstring(L, result);
return 1;
@@ -884,7 +886,7 @@ static int lua_apr_touch(lua_State *L)
r = ap_lua_check_request_rec(L, 1);
luaL_checktype(L, 2, LUA_TSTRING);
path = lua_tostring(L, 2);
- mtime = luaL_optnumber(L, 3, apr_time_now());
+ mtime = (apr_time_t)luaL_optnumber(L, 3, (lua_Number)apr_time_now());
status = apr_file_mtime_set(path, mtime, r->pool);
lua_pushboolean(L, (status == 0));
return 1;
@@ -1887,6 +1889,414 @@ static int lua_ivm_set(lua_State *L)
return 0;
}
+static int lua_get_cookie(lua_State *L)
+{
+ const char *key, *cookie;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ key = luaL_checkstring(L, 2);
+ cookie = NULL;
+ ap_cookie_read(r, key, &cookie, 0);
+ if (cookie != NULL) {
+ lua_pushstring(L, cookie);
+ return 1;
+ }
+ return 0;
+}
+
+static int lua_set_cookie(lua_State *L)
+{
+ const char *key, *value, *out, *strexpires;
+ int secure, expires;
+ char cdate[APR_RFC822_DATE_LEN+1];
+ apr_status_t rv;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ key = luaL_checkstring(L, 2);
+ value = luaL_checkstring(L, 3);
+ secure = 0;
+ if (lua_isboolean(L, 4)) {
+ secure = lua_toboolean(L, 4);
+ }
+ expires = luaL_optinteger(L, 5, 0);
+ strexpires = "";
+ if (expires > 0) {
+ rv = apr_rfc822_date(cdate, apr_time_from_sec(expires));
+ if (rv == APR_SUCCESS) {
+ strexpires = apr_psprintf(r->pool, "Expires=%s", cdate);
+ }
+ }
+ out = apr_psprintf(r->pool, "%s=%s; %s %s", key, value, secure ? "Secure;" : "", expires ? strexpires : "");
+ apr_table_set(r->headers_out, "Set-Cookie", out);
+ return 0;
+}
+
+static apr_uint64_t ap_ntoh64(const apr_uint64_t *input)
+{
+ apr_uint64_t rval;
+ unsigned char *data = (unsigned char *)&rval;
+ if (APR_IS_BIGENDIAN) {
+ return *input;
+ }
+
+ data[0] = *input >> 56;
+ data[1] = *input >> 48;
+ data[2] = *input >> 40;
+ data[3] = *input >> 32;
+ data[4] = *input >> 24;
+ data[5] = *input >> 16;
+ data[6] = *input >> 8;
+ data[7] = *input >> 0;
+
+ return rval;
+}
+
+static int lua_websocket_greet(lua_State *L)
+{
+ const char *key = NULL;
+ unsigned char digest[APR_SHA1_DIGESTSIZE];
+ apr_sha1_ctx_t sha1;
+ char *encoded;
+ int encoded_len;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ key = apr_table_get(r->headers_in, "Sec-WebSocket-Key");
+ if (key != NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Got websocket key: %s", key);
+ key = apr_pstrcat(r->pool, key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
+ NULL);
+ apr_sha1_init(&sha1);
+ apr_sha1_update(&sha1, key, strlen(key));
+ apr_sha1_final(digest, &sha1);
+ encoded_len = apr_base64_encode_len(APR_SHA1_DIGESTSIZE);
+ if (encoded_len) {
+ 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);
+
+ /* Trick httpd into NOT using the chunked filter, IMPORTANT!!!111*/
+ apr_table_set(r->headers_out, "Transfer-Encoding", "chunked");
+
+ r->clength = 0;
+ r->bytes_sent = 0;
+ r->read_chunked = 0;
+ ap_rflush(r);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Upgraded from HTTP to Websocket");
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
+ "Websocket: Upgrade from HTTP to Websocket failed");
+ return 0;
+}
+
+static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer,
+ apr_off_t len)
+{
+ apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
+ 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);
+ }
+ }
+ apr_brigade_cleanup(brigade);
+ return rv;
+}
+
+static int lua_websocket_read(lua_State *L)
+{
+ apr_socket_t *sock;
+ apr_status_t rv;
+ 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;
+
+
+ request_rec *r = (request_rec *) lua_unboxpointer(L, 1);
+ plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
+
+
+ mask_bytes = apr_pcalloc(r->pool, 4);
+ sock = ap_get_conn_socket(r->connection);
+
+ /* 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 fin, opcode, mask, payload;
+ fin = byte >> 7;
+ opcode = (byte << 4) >> 4;
+
+ /* 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);
+ }
+ if (rv == APR_SUCCESS) {
+ mask = byte >> 7;
+ payload = byte - 128;
+ plen = payload;
+
+ /* Extended payload? */
+ if (payload == 126) {
+ len = 2;
+ if (plaintext) {
+ 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;
+ }
+ }
+ /* 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;
+ }
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Reading %lu (%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;
+ }
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "Websocket: Frame contained %lu 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 %lu 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! */
+ lua_websocket_read(L); /* read the next frame instead */
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int lua_websocket_write(lua_State *L)
+{
+ const char *string;
+ apr_status_t rv;
+ size_t len;
+ int raw = 0;
+ char prelude;
+ request_rec *r = (request_rec *) lua_unboxpointer(L, 1);
+
+ if (lua_isboolean(L, 3)) {
+ raw = lua_toboolean(L, 3);
+ }
+ string = lua_tolstring(L, 2, &len);
+
+ if (raw != 1) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Writing framed message to client");
+
+ prelude = 0x81; /* text frame, FIN */
+ ap_rputc(prelude, r);
+ if (len < 126) {
+ ap_rputc(len, r);
+ }
+ else if (len < 65535) {
+ apr_uint16_t slen = len;
+ ap_rputc(126, r);
+ slen = htons(slen);
+ ap_rwrite((char*) &slen, 2, r);
+ }
+ else {
+ apr_uint64_t llen = len;
+ ap_rputc(127, r);
+ llen = ap_ntoh64(&llen); /* ntoh doubles as hton */
+ ap_rwrite((char*) &llen, 8, r);
+ }
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Writing raw message to client");
+ }
+ ap_rwrite(string, len, r);
+ rv = ap_rflush(r);
+ if (rv == APR_SUCCESS) {
+ lua_pushboolean(L, 1);
+ }
+ else {
+ lua_pushboolean(L, 0);
+ }
+ return 1;
+}
+
+
+static int lua_websocket_close(lua_State *L)
+{
+ apr_socket_t *sock;
+ char prelude[2];
+ request_rec *r = (request_rec *) lua_unboxpointer(L, 1);
+
+ sock = ap_get_conn_socket(r->connection);
+
+ /* Send a header that says: socket is closing. */
+ prelude[0] = 0x88; /* closing socket opcode */
+ prelude[1] = 0; /* zero length frame */
+ ap_rwrite(prelude, 2, r);
+
+ /* Close up tell the MPM and filters to back off */
+ apr_socket_close(sock);
+ r->output_filters = NULL;
+ r->connection->keepalive = AP_CONN_CLOSE;
+ ap_destroy_sub_req(r);
+ return DONE;
+}
+
+
+static int lua_websocket_ping(lua_State *L)
+{
+ apr_socket_t *sock;
+ apr_size_t plen;
+ char prelude[2];
+ apr_status_t rv;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ sock = ap_get_conn_socket(r->connection);
+
+ /* Send a header that says: PING. */
+ prelude[0] = 0x89; /* ping opcode */
+ prelude[1] = 0;
+ plen = 2;
+ apr_socket_send(sock, prelude, &plen);
+
+
+ /* Get opcode and FIN bit from pong */
+ plen = 2;
+ rv = apr_socket_recv(sock, prelude, &plen);
+ if (rv == APR_SUCCESS) {
+ unsigned char opcode = prelude[0];
+ unsigned char len = prelude[1];
+ unsigned char mask = len >> 7;
+ if (mask) len -= 128;
+ plen = len;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Websocket: Got PONG opcode: %x", opcode);
+ if (opcode == 0x8A) {
+ lua_pushboolean(L, 1);
+ }
+ else {
+ lua_pushboolean(L, 0);
+ }
+ if (plen > 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "Websocket: Reading %lu bytes of PONG", plen);
+ return 1;
+ }
+ if (mask) {
+ plen = 2;
+ apr_socket_recv(sock, prelude, &plen);
+ plen = 2;
+ apr_socket_recv(sock, prelude, &plen);
+ }
+ }
+ else {
+ lua_pushboolean(L, 0);
+ }
+ return 1;
+}
+
+
#define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L) \
{ \
return req_log_at(L, APLOG_TRACE##lev); \
@@ -1994,6 +2404,7 @@ static const char* lua_ap_get_server_name(request_rec* r)
+
static const struct luaL_Reg server_methods[] = {
{NULL, NULL}
};
@@ -2236,7 +2647,22 @@ void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&lua_ivm_get, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "ivm_set", APR_HASH_KEY_STRING,
makefun(&lua_ivm_set, APL_REQ_FUNTYPE_LUACFUN, p));
-
+ apr_hash_set(dispatch, "getcookie", APR_HASH_KEY_STRING,
+ makefun(&lua_get_cookie, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "setcookie", APR_HASH_KEY_STRING,
+ makefun(&lua_set_cookie, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "wsupgrade", APR_HASH_KEY_STRING,
+ makefun(&lua_websocket_greet, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "wsread", APR_HASH_KEY_STRING,
+ makefun(&lua_websocket_read, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "wswrite", APR_HASH_KEY_STRING,
+ makefun(&lua_websocket_write, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "wsclose", APR_HASH_KEY_STRING,
+ 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));
+
+
lua_pushlightuserdata(L, dispatch);
lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 7c35011e..6e3390fb 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -318,7 +318,10 @@ static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_fil
ctx = apr_pcalloc(r->pool, sizeof(lua_filter_ctx));
ctx->broken = 0;
*c = ctx;
- /* Find the filter that was called */
+ /* Find the filter that was called.
+ * XXX: If we were wired with mod_filter, the filter (mod_filters name)
+ * and the provider (our underlying filters name) need to have matched.
+ */
for (n = 0; n < cfg->mapped_filters->nelts; n++) {
ap_lua_filter_handler_spec *hook_spec =
((ap_lua_filter_handler_spec **) cfg->mapped_filters->elts)[n];
@@ -374,6 +377,12 @@ static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_fil
*/
rc = lua_resume(L, 1);
if (rc == LUA_YIELD) {
+ if (f->frec->providers == NULL) {
+ /* Not wired by mod_filter */
+ apr_table_unset(r->headers_out, "Content-Length");
+ apr_table_unset(r->headers_out, "Content-MD5");
+ apr_table_unset(r->headers_out, "ETAG");
+ }
return OK;
}
else {
@@ -407,8 +416,25 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
ap_remove_output_filter(f);
return ap_pass_brigade(f->next,pbbIn);
}
- f->ctx = ctx;
- ctx->tmpBucket = apr_brigade_create(r->pool, c->bucket_alloc);
+ else {
+ /* We've got a willing lua filter, setup and check for a prefix */
+ size_t olen;
+ apr_bucket *pbktOut;
+ const char* output = lua_tolstring(ctx->L, 1, &olen);
+
+ f->ctx = ctx;
+ ctx->tmpBucket = apr_brigade_create(r->pool, c->bucket_alloc);
+
+ if (olen > 0) {
+ pbktOut = apr_bucket_heap_create(output, olen, NULL, c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
+ rv = ap_pass_brigade(f->next, ctx->tmpBucket);
+ apr_brigade_cleanup(ctx->tmpBucket);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ }
+ }
}
ctx = (lua_filter_ctx*) f->ctx;
L = ctx->L;
@@ -433,13 +459,15 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
if (lua_resume(L, 0) == LUA_YIELD) {
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
- pbktOut = apr_bucket_heap_create(output, olen, NULL,
- c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
- rv = ap_pass_brigade(f->next, ctx->tmpBucket);
- apr_brigade_cleanup(ctx->tmpBucket);
- if (rv != APR_SUCCESS) {
- return rv;
+ if (olen > 0) {
+ pbktOut = apr_bucket_heap_create(output, olen, NULL,
+ c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
+ rv = ap_pass_brigade(f->next, ctx->tmpBucket);
+ apr_brigade_cleanup(ctx->tmpBucket);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
}
}
else {
@@ -461,9 +489,11 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
apr_bucket *pbktOut;
size_t olen;
const char* output = lua_tolstring(L, 1, &olen);
- pbktOut = apr_bucket_heap_create(output, olen, NULL,
- c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
+ if (olen > 0) {
+ pbktOut = apr_bucket_heap_create(output, olen, NULL,
+ c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktOut);
+ }
}
pbktEOS = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(ctx->tmpBucket, pbktEOS);
@@ -661,6 +691,13 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
rc = DECLINED;
if (lua_isnumber(L, -1)) {
rc = lua_tointeger(L, -1);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "Lua hook %s:%s for phase %s returned %d",
+ hook_spec->file_name, hook_spec->function_name, name, rc);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "Lua hook %s:%s for phase %s did not return a numeric value",
+ hook_spec->file_name, hook_spec->function_name, name);
+ return HTTP_INTERNAL_SERVER_ERROR;
}
if (rc != DECLINED) {
ap_lua_release_state(L, spec, r);
@@ -1076,7 +1113,8 @@ static const char *register_filter_function_hook(const char *filter,
/* TODO: Make it work on other types than just AP_FTYPE_RESOURCE? */
if (direction == AP_LUA_FILTER_OUTPUT) {
spec->direction = AP_LUA_FILTER_OUTPUT;
- ap_register_output_filter(filter, lua_output_filter_handle, NULL, AP_FTYPE_RESOURCE);
+ ap_register_output_filter_protocol(filter, lua_output_filter_handle, NULL, AP_FTYPE_RESOURCE,
+ AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH);
}
else {
spec->direction = AP_LUA_FILTER_INPUT;
@@ -1155,6 +1193,11 @@ static void lua_insert_filter_harness(request_rec *r)
/* ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "LuaHookInsertFilter not yet implemented"); */
}
+static int lua_log_transaction_harness(request_rec *r)
+{
+ return lua_request_rec_hook_harness(r, "log_transaction", APR_HOOK_FIRST);
+}
+
static int lua_quick_harness(request_rec *r, int lookup)
{
if (lookup) {
@@ -1219,6 +1262,15 @@ static const char *register_map_to_storage_hook(cmd_parms *cmd, void *_cfg,
return register_named_file_function_hook("map_to_storage", cmd, _cfg,
file, function, APR_HOOK_MIDDLE);
}
+
+static const char *register_log_transaction_hook(cmd_parms *cmd, void *_cfg,
+ const char *file,
+ const char *function)
+{
+ return register_named_file_function_hook("log_transaction", cmd, _cfg,
+ file, function, APR_HOOK_FIRST);
+}
+
static const char *register_map_to_storage_block(cmd_parms *cmd, void *_cfg,
const char *line)
{
@@ -1226,6 +1278,7 @@ static const char *register_map_to_storage_block(cmd_parms *cmd, void *_cfg,
line);
}
+
static const char *register_check_user_id_hook(cmd_parms *cmd, void *_cfg,
const char *file,
const char *function,
@@ -1783,6 +1836,10 @@ command_rec lua_commands[] = {
AP_INIT_TAKE2("LuaHookInsertFilter", register_insert_filter_hook, NULL,
OR_ALL,
"Provide a hook for the insert_filter phase of request processing"),
+
+ AP_INIT_TAKE2("LuaHookLog", register_log_transaction_hook, NULL,
+ OR_ALL,
+ "Provide a hook for the logging phase of request processing"),
AP_INIT_TAKE123("LuaScope", register_lua_scope, NULL, OR_ALL,
"One of once, request, conn, server -- default is once"),
@@ -1983,6 +2040,10 @@ static void lua_register_hooks(apr_pool_t *p)
/* ivm mutex */
apr_thread_mutex_create(&lua_ivm_mutex, APR_THREAD_MUTEX_DEFAULT, p);
+
+ /* Logging catcher */
+ ap_hook_log_transaction(lua_log_transaction_harness,NULL,NULL,
+ APR_HOOK_FIRST);
}
AP_DECLARE_MODULE(lua) = {
diff --git a/modules/lua/mod_lua.dsp b/modules/lua/mod_lua.dsp
index 770c13a1..ef3294ed 100644
--- a/modules/lua/mod_lua.dsp
+++ b/modules/lua/mod_lua.dsp
@@ -52,8 +52,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
-# ADD LINK32 kernel32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /opt:ref /libpath:"../../srclib/lua/src"
+# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
+# ADD LINK32 kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /opt:ref /libpath:"../../srclib/lua/src"
# Begin Special Build Tool
TargetPath=.\Release\mod_lua.so
SOURCE="$(InputPath)"
@@ -84,8 +84,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
-# ADD LINK32 kernel32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /libpath:"../../srclib/lua/src"
+# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so
+# ADD LINK32 kernel32.lib ws2_32.lib lua51.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_lua.so" /base:@..\..\os\win32\BaseAddr.ref,mod_lua.so /libpath:"../../srclib/lua/src"
# Begin Special Build Tool
TargetPath=.\Debug\mod_lua.so
SOURCE="$(InputPath)"