summaryrefslogtreecommitdiff
path: root/modules/lua
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2012-10-20 02:58:14 +0200
committerArno Töll <arno@debian.org>2012-10-20 02:58:14 +0200
commit5c4fba3ffbe778bdffe10a93d04821579601a020 (patch)
tree91be9a7f99d3988ba48b0a619479aa46a3234191 /modules/lua
parent8f9c15530d0bc387af114619b3ff3f930eb23d3c (diff)
downloadapache2-5c4fba3ffbe778bdffe10a93d04821579601a020.tar.gz
Imported Upstream version 2.4.3upstream/2.4.3
Diffstat (limited to 'modules/lua')
-rw-r--r--modules/lua/README7
-rw-r--r--modules/lua/lua_config.c58
-rw-r--r--modules/lua/lua_request.c87
-rw-r--r--modules/lua/lua_vmprep.c218
-rw-r--r--modules/lua/lua_vmprep.h6
-rw-r--r--modules/lua/mod_lua.c331
-rw-r--r--modules/lua/mod_lua.h9
7 files changed, 420 insertions, 296 deletions
diff --git a/modules/lua/README b/modules/lua/README
index 4efa9cd6..c614b3e2 100644
--- a/modules/lua/README
+++ b/modules/lua/README
@@ -54,6 +54,13 @@
** TODO apw_rgetvm needs to handle connection scoped vms
** TODO options in server scoped vms (ie, min and max vm counts)
** TODO provide means to implement authn and authz providers
+** TODO: Flatten LuaHook* to LuaHook phase file fn ?
+** TODO: Lua and ap_expr integration in one or both directions
+** TODO: document or remove block sections
+** TODO: test per-dir behavior of block sections
+** TODO: Catch-up documentation on r: methods
+** TODO: 500 errors instead of 404 with AddHandler lua-script
+** TODO: Suppress internal details (fs path to scripts, etc) in error responses
* License
Apache License, Version 2.0,
diff --git a/modules/lua/lua_config.c b/modules/lua/lua_config.c
index 0e675652..07dd932b 100644
--- a/modules/lua/lua_config.c
+++ b/modules/lua/lua_config.c
@@ -154,14 +154,6 @@ static const struct luaL_Reg cfg_methods[] = {
{NULL, NULL}
};
-
-static int cmd_foo(lua_State *L)
-{
- cmd_parms *cmd = check_cmd_parms(L, 1);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, APLOGNO(01479) "FOO!");
- return 0;
-}
-
/* helper function for the logging functions below */
static int cmd_log_at(lua_State *L, int level)
{
@@ -181,88 +173,70 @@ static int cmd_log_at(lua_State *L, int level)
/* r:debug(String) and friends which use apache logging */
static int cmd_emerg(lua_State *L)
{
- cmd_log_at(L, APLOG_EMERG);
- return 0;
+ return cmd_log_at(L, APLOG_EMERG);
}
static int cmd_alert(lua_State *L)
{
- cmd_log_at(L, APLOG_ALERT);
- return 0;
+ return cmd_log_at(L, APLOG_ALERT);
}
static int cmd_crit(lua_State *L)
{
- cmd_log_at(L, APLOG_CRIT);
- return 0;
+ return cmd_log_at(L, APLOG_CRIT);
}
static int cmd_err(lua_State *L)
{
- cmd_log_at(L, APLOG_ERR);
- return 0;
+ return cmd_log_at(L, APLOG_ERR);
}
static int cmd_warn(lua_State *L)
{
- cmd_log_at(L, APLOG_WARNING);
- return 0;
+ return cmd_log_at(L, APLOG_WARNING);
}
static int cmd_notice(lua_State *L)
{
- cmd_log_at(L, APLOG_NOTICE);
- return 0;
+ return cmd_log_at(L, APLOG_NOTICE);
}
static int cmd_info(lua_State *L)
{
- cmd_log_at(L, APLOG_INFO);
- return 0;
+ return cmd_log_at(L, APLOG_INFO);
}
static int cmd_debug(lua_State *L)
{
- cmd_log_at(L, APLOG_DEBUG);
- return 0;
+ return cmd_log_at(L, APLOG_DEBUG);
}
static int cmd_trace1(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE1);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE1);
}
static int cmd_trace2(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE2);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE2);
}
static int cmd_trace3(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE3);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE3);
}
static int cmd_trace4(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE4);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE4);
}
static int cmd_trace5(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE5);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE5);
}
static int cmd_trace6(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE6);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE6);
}
static int cmd_trace7(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE7);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE7);
}
static int cmd_trace8(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE8);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE8);
}
static const struct luaL_Reg cmd_methods[] = {
- {"foo", cmd_foo},
-
{"trace8", cmd_trace8},
{"trace7", cmd_trace7},
{"trace6", cmd_trace6},
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index 91bd3b75..9a1cdf8c 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -164,6 +164,34 @@ static int req_parseargs(lua_State *L)
return 2; /* [table<string, string>, table<string, array<string>>] */
}
+/* r:parsebody() returning a lua table */
+static int req_parsebody(lua_State *L)
+{
+ apr_array_header_t *pairs;
+ apr_off_t len;
+ int res;
+ apr_size_t size;
+ apr_size_t max_post_size;
+ char *buffer;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ max_post_size = (apr_size_t) luaL_optint(L, 2, MAX_STRING_LEN);
+ lua_newtable(L);
+ lua_newtable(L); /* [table, table] */
+ res = ap_parse_form_data(r, NULL, &pairs, -1, max_post_size);
+ if (res == OK) {
+ while(pairs && !apr_is_empty_array(pairs)) {
+ ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ req_aprtable2luatable_cb(L, pair->name, buffer);
+ }
+ }
+ return 2; /* [table<string, string>, table<string, array<string>>] */
+}
+
/* wrap ap_rputs as r:puts(String) */
static int req_puts(lua_State *L)
{
@@ -235,6 +263,16 @@ static const char *req_document_root(request_rec *r)
return ap_document_root(r);
}
+static const char *req_context_prefix(request_rec *r)
+{
+ return ap_context_prefix(r);
+}
+
+static const char *req_context_document_root(request_rec *r)
+{
+ return ap_context_document_root(r);
+}
+
static char *req_uri_field(request_rec *r)
{
return r->uri;
@@ -323,6 +361,16 @@ static const char *req_the_request_field(request_rec *r)
return r->the_request;
}
+static const char *req_log_id_field(request_rec *r)
+{
+ return r->log_id;
+}
+
+static const char *req_useragent_ip_field(request_rec *r)
+{
+ return r->useragent_ip;
+}
+
static int req_status_field(request_rec *r)
{
return r->status;
@@ -452,49 +500,40 @@ static int req_log_at(lua_State *L, int level)
/* r:debug(String) and friends which use apache logging */
static int req_emerg(lua_State *L)
{
- req_log_at(L, APLOG_EMERG);
- return 0;
+ return req_log_at(L, APLOG_EMERG);
}
static int req_alert(lua_State *L)
{
- req_log_at(L, APLOG_ALERT);
- return 0;
+ return req_log_at(L, APLOG_ALERT);
}
static int req_crit(lua_State *L)
{
- req_log_at(L, APLOG_CRIT);
- return 0;
+ return req_log_at(L, APLOG_CRIT);
}
static int req_err(lua_State *L)
{
- req_log_at(L, APLOG_ERR);
- return 0;
+ return req_log_at(L, APLOG_ERR);
}
static int req_warn(lua_State *L)
{
- req_log_at(L, APLOG_WARNING);
- return 0;
+ return req_log_at(L, APLOG_WARNING);
}
static int req_notice(lua_State *L)
{
- req_log_at(L, APLOG_NOTICE);
- return 0;
+ return req_log_at(L, APLOG_NOTICE);
}
static int req_info(lua_State *L)
{
- req_log_at(L, APLOG_INFO);
- return 0;
+ return req_log_at(L, APLOG_INFO);
}
static int req_debug(lua_State *L)
{
- req_log_at(L, APLOG_DEBUG);
- return 0;
+ return req_log_at(L, APLOG_DEBUG);
}
#define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L) \
{ \
- req_log_at(L, APLOG_TRACE##lev); \
- return 0; \
+ return req_log_at(L, APLOG_TRACE##lev); \
}
APLUA_REQ_TRACE(1)
@@ -608,8 +647,14 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_write, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "document_root", APR_HASH_KEY_STRING,
makefun(&req_document_root, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "context_prefix", APR_HASH_KEY_STRING,
+ makefun(&req_context_prefix, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "context_document_root", APR_HASH_KEY_STRING,
+ makefun(&req_context_document_root, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "parseargs", APR_HASH_KEY_STRING,
makefun(&req_parseargs, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "parsebody", APR_HASH_KEY_STRING,
+ makefun(&req_parsebody, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "debug", APR_HASH_KEY_STRING,
makefun(&req_debug, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "info", APR_HASH_KEY_STRING,
@@ -688,6 +733,10 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_uri_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "the_request", APR_HASH_KEY_STRING,
makefun(&req_the_request_field, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "log_id", APR_HASH_KEY_STRING,
+ makefun(&req_log_id_field, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "useragent_ip", APR_HASH_KEY_STRING,
+ makefun(&req_useragent_ip_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "method", APR_HASH_KEY_STRING,
makefun(&req_method_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "proxyreq", APR_HASH_KEY_STRING,
@@ -744,7 +793,7 @@ AP_LUA_DECLARE(void) ap_lua_push_connection(lua_State *L, conn_rec *c)
lua_setfield(L, -2, "notes");
lua_pushstring(L, c->client_ip);
- lua_setfield(L, -2, "remote_ip");
+ lua_setfield(L, -2, "client_ip");
lua_pop(L, 1);
}
diff --git a/modules/lua/lua_vmprep.c b/modules/lua/lua_vmprep.c
index 7c383ca9..e821fee3 100644
--- a/modules/lua/lua_vmprep.c
+++ b/modules/lua/lua_vmprep.c
@@ -19,6 +19,7 @@
#include "apr_uuid.h"
#include "lua_config.h"
#include "apr_file_info.h"
+#include "mod_auth.h"
APLOG_USE_MODULE(lua);
@@ -96,6 +97,8 @@ static void pstack_dump(lua_State *L, apr_pool_t *r, int level,
/* BEGIN apache lmodule */
+#define makeintegerfield(L, n) lua_pushinteger(L, n); lua_setfield(L, -2, #n)
+
AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
{
lua_getglobal(L, "package");
@@ -106,130 +109,83 @@ AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
lua_pop(L, 1); /* empty stack */
lua_getglobal(L, "apache2");
- lua_pushinteger(L, OK);
- lua_setfield(L, -2, "OK");
-
- lua_pushinteger(L, DECLINED);
- lua_setfield(L, -2, "DECLINED");
-
- lua_pushinteger(L, DONE);
- lua_setfield(L, -2, "DONE");
lua_pushstring(L, ap_get_server_banner());
lua_setfield(L, -2, "version");
- lua_pushinteger(L, HTTP_MOVED_TEMPORARILY);
- lua_setfield(L, -2, "HTTP_MOVED_TEMPORARILY");
-
- lua_pushinteger(L, PROXYREQ_NONE);
- lua_setfield(L, -2, "PROXYREQ_NONE");
-
- lua_pushinteger(L, PROXYREQ_PROXY);
- lua_setfield(L, -2, "PROXYREQ_PROXY");
-
- lua_pushinteger(L, PROXYREQ_REVERSE);
- lua_setfield(L, -2, "PROXYREQ_REVERSE");
-
- lua_pushinteger(L, PROXYREQ_RESPONSE);
- lua_setfield(L, -2, "PROXYREQ_RESPONSE");
+ makeintegerfield(L, OK);
+ makeintegerfield(L, DECLINED);
+ makeintegerfield(L, DONE);
+ makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
+ makeintegerfield(L, PROXYREQ_NONE);
+ makeintegerfield(L, PROXYREQ_PROXY);
+ makeintegerfield(L, PROXYREQ_REVERSE);
+ makeintegerfield(L, PROXYREQ_RESPONSE);
+ makeintegerfield(L, PROXYREQ_RESPONSE);
+ makeintegerfield(L, AUTHZ_DENIED);
+ makeintegerfield(L, AUTHZ_GRANTED);
+ makeintegerfield(L, AUTHZ_NEUTRAL);
+ makeintegerfield(L, AUTHZ_GENERAL_ERROR);
+ makeintegerfield(L, AUTHZ_DENIED_NO_USER);
/*
- lua_pushinteger(L, HTTP_CONTINUE);
- lua_setfield(L, -2, "HTTP_CONTINUE");
- lua_pushinteger(L, HTTP_SWITCHING_PROTOCOLS);
- lua_setfield(L, -2, "HTTP_SWITCHING_PROTOCOLS");
- lua_pushinteger(L, HTTP_PROCESSING);
- lua_setfield(L, -2, "HTTP_PROCESSING");
- lua_pushinteger(L, HTTP_OK);
- lua_setfield(L, -2, "HTTP_OK");
- lua_pushinteger(L, HTTP_CREATED);
- lua_setfield(L, -2, "HTTP_CREATED");
- lua_pushinteger(L, HTTP_ACCEPTED);
- lua_setfield(L, -2, "HTTP_ACCEPTED");
- lua_pushinteger(L, HTTP_NON_AUTHORITATIVE);
- lua_setfield(L, -2, "HTTP_NON_AUTHORITATIVE");
- lua_pushinteger(L, HTTP_NO_CONTENT);
- lua_setfield(L, -2, "HTTP_NO_CONTENT");
- lua_pushinteger(L, HTTP_RESET_CONTENT);
- lua_setfield(L, -2, "HTTP_RESET_CONTENT");
- lua_pushinteger(L, HTTP_PARTIAL_CONTENT);
- lua_setfield(L, -2, "HTTP_PARTIAL_CONTENT");
- lua_pushinteger(L, HTTP_MULTI_STATUS);
- lua_setfield(L, -2, "HTTP_MULTI_STATUS");
- lua_pushinteger(L, HTTP_MULTIPLE_CHOICES);
- lua_setfield(L, -2, "HTTP_MULTIPLE_CHOICES");
- lua_pushinteger(L, HTTP_MOVED_PERMANENTLY);
- lua_setfield(L, -2, "HTTP_MOVED_PERMANENTLY");
- lua_pushinteger(L, HTTP_SEE_OTHER);
- lua_setfield(L, -2, "HTTP_SEE_OTHER");
- lua_pushinteger(L, HTTP_NOT_MODIFIED);
- lua_setfield(L, -2, "HTTP_NOT_MODIFIED");
- lua_pushinteger(L, HTTP_USE_PROXY);
- lua_setfield(L, -2, "HTTP_USE_PROXY");
- lua_pushinteger(L, HTTP_TEMPORARY_REDIRECT);
- lua_setfield(L, -2, "HTTP_TEMPORARY_REDIRECT");
- lua_pushinteger(L, HTTP_BAD_REQUEST);
- lua_setfield(L, -2, "HTTP_BAD_REQUEST");
- lua_pushinteger(L, HTTP_UNAUTHORIZED);
- lua_setfield(L, -2, "HTTP_UNAUTHORIZED");
- lua_pushinteger(L, HTTP_PAYMENT_REQUIRED);
- lua_setfield(L, -2, "HTTP_PAYMENT_REQUIRED");
- lua_pushinteger(L, HTTP_FORBIDDEN);
- lua_setfield(L, -2, "HTTP_FORBIDDEN");
- lua_pushinteger(L, HTTP_NOT_FOUND);
- lua_setfield(L, -2, "HTTP_NOT_FOUND");
- lua_pushinteger(L, HTTP_METHOD_NOT_ALLOWED);
- lua_setfield(L, -2, "HTTP_METHOD_NOT_ALLOWED");
- lua_pushinteger(L, HTTP_NOT_ACCEPTABLE);
- lua_setfield(L, -2, "HTTP_NOT_ACCEPTABLE");
- lua_pushinteger(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
- lua_setfield(L, -2, "HTTP_PROXY_AUTHENTICATION_REQUIRED");
- lua_pushinteger(L, HTTP_REQUEST_TIME_OUT);
- lua_setfield(L, -2, "HTTP_REQUEST_TIME_OUT");
- lua_pushinteger(L, HTTP_CONFLICT);
- lua_setfield(L, -2, "HTTP_CONFLICT");
- lua_pushinteger(L, HTTP_GONE);
- lua_setfield(L, -2, "HTTP_GONE");
- lua_pushinteger(L, HTTP_LENGTH_REQUIRED);
- lua_setfield(L, -2, "HTTP_LENGTH_REQUIRED");
- lua_pushinteger(L, HTTP_PRECONDITION_FAILED);
- lua_setfield(L, -2, "HTTP_PRECONDITION_FAILED");
- lua_pushinteger(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
- lua_setfield(L, -2, "HTTP_REQUEST_ENTITY_TOO_LARGE");
- lua_pushinteger(L, HTTP_REQUEST_URI_TOO_LARGE);
- lua_setfield(L, -2, "HTTP_REQUEST_URI_TOO_LARGE");
- lua_pushinteger(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
- lua_setfield(L, -2, "HTTP_UNSUPPORTED_MEDIA_TYPE");
- lua_pushinteger(L, HTTP_RANGE_NOT_SATISFIABLE);
- lua_setfield(L, -2, "HTTP_RANGE_NOT_SATISFIABLE");
- lua_pushinteger(L, HTTP_EXPECTATION_FAILED);
- lua_setfield(L, -2, "HTTP_EXPECTATION_FAILED");
- lua_pushinteger(L, HTTP_UNPROCESSABLE_ENTITY);
- lua_setfield(L, -2, "HTTP_UNPROCESSABLE_ENTITY");
- lua_pushinteger(L, HTTP_LOCKED);
- lua_setfield(L, -2, "HTTP_LOCKED");
- lua_pushinteger(L, HTTP_FAILED_DEPENDENCY);
- lua_setfield(L, -2, "HTTP_FAILED_DEPENDENCY");
- lua_pushinteger(L, HTTP_UPGRADE_REQUIRED);
- lua_setfield(L, -2, "HTTP_UPGRADE_REQUIRED");
- lua_pushinteger(L, HTTP_INTERNAL_SERVER_ERROR);
- lua_setfield(L, -2, "HTTP_INTERNAL_SERVER_ERROR");
- lua_pushinteger(L, HTTP_NOT_IMPLEMENTED);
- lua_setfield(L, -2, "HTTP_NOT_IMPLEMENTED");
- lua_pushinteger(L, HTTP_BAD_GATEWAY);
- lua_setfield(L, -2, "HTTP_BAD_GATEWAY");
- lua_pushinteger(L, HTTP_SERVICE_UNAVAILABLE);
- lua_setfield(L, -2, "HTTP_SERVICE_UNAVAILABLE");
- lua_pushinteger(L, HTTP_GATEWAY_TIME_OUT);
- lua_setfield(L, -2, "HTTP_GATEWAY_TIME_OUT");
- lua_pushinteger(L, HTTP_VERSION_NOT_SUPPORTED);
- lua_setfield(L, -2, "HTTP_VERSION_NOT_SUPPORTED");
- lua_pushinteger(L, HTTP_VARIANT_ALSO_VARIES);
- lua_setfield(L, -2, "HTTP_VARIANT_ALSO_VARIES");
- lua_pushinteger(L, HTTP_INSUFFICIENT_STORAGE);
- lua_setfield(L, -2, "HTTP_INSUFFICIENT_STORAGE");
- lua_pushinteger(L, HTTP_NOT_EXTENDED);
- lua_setfield(L, -2, "HTTP_NOT_EXTENDED");
+ makeintegerfield(L, HTTP_CONTINUE);
+ makeintegerfield(L, HTTP_SWITCHING_PROTOCOLS);
+ makeintegerfield(L, HTTP_PROCESSING);
+ makeintegerfield(L, HTTP_OK);
+ makeintegerfield(L, HTTP_CREATED);
+ makeintegerfield(L, HTTP_ACCEPTED);
+ makeintegerfield(L, HTTP_NON_AUTHORITATIVE);
+ makeintegerfield(L, HTTP_NO_CONTENT);
+ makeintegerfield(L, HTTP_RESET_CONTENT);
+ makeintegerfield(L, HTTP_PARTIAL_CONTENT);
+ makeintegerfield(L, HTTP_MULTI_STATUS);
+ makeintegerfield(L, HTTP_ALREADY_REPORTED);
+ makeintegerfield(L, HTTP_IM_USED);
+ makeintegerfield(L, HTTP_MULTIPLE_CHOICES);
+ makeintegerfield(L, HTTP_MOVED_PERMANENTLY);
+ makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
+ makeintegerfield(L, HTTP_SEE_OTHER);
+ makeintegerfield(L, HTTP_NOT_MODIFIED);
+ makeintegerfield(L, HTTP_USE_PROXY);
+ makeintegerfield(L, HTTP_TEMPORARY_REDIRECT);
+ makeintegerfield(L, HTTP_PERMANENT_REDIRECT);
+ makeintegerfield(L, HTTP_BAD_REQUEST);
+ makeintegerfield(L, HTTP_UNAUTHORIZED);
+ makeintegerfield(L, HTTP_PAYMENT_REQUIRED);
+ makeintegerfield(L, HTTP_FORBIDDEN);
+ makeintegerfield(L, HTTP_NOT_FOUND);
+ makeintegerfield(L, HTTP_METHOD_NOT_ALLOWED);
+ makeintegerfield(L, HTTP_NOT_ACCEPTABLE);
+ makeintegerfield(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
+ makeintegerfield(L, HTTP_REQUEST_TIME_OUT);
+ makeintegerfield(L, HTTP_CONFLICT);
+ makeintegerfield(L, HTTP_GONE);
+ makeintegerfield(L, HTTP_LENGTH_REQUIRED);
+ makeintegerfield(L, HTTP_PRECONDITION_FAILED);
+ makeintegerfield(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
+ makeintegerfield(L, HTTP_REQUEST_URI_TOO_LARGE);
+ makeintegerfield(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
+ makeintegerfield(L, HTTP_RANGE_NOT_SATISFIABLE);
+ makeintegerfield(L, HTTP_EXPECTATION_FAILED);
+ makeintegerfield(L, HTTP_UNPROCESSABLE_ENTITY);
+ makeintegerfield(L, HTTP_LOCKED);
+ makeintegerfield(L, HTTP_FAILED_DEPENDENCY);
+ makeintegerfield(L, HTTP_UPGRADE_REQUIRED);
+ makeintegerfield(L, HTTP_PRECONDITION_REQUIRED);
+ makeintegerfield(L, HTTP_TOO_MANY_REQUESTS);
+ makeintegerfield(L, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
+ makeintegerfield(L, HTTP_INTERNAL_SERVER_ERROR);
+ makeintegerfield(L, HTTP_NOT_IMPLEMENTED);
+ makeintegerfield(L, HTTP_BAD_GATEWAY);
+ makeintegerfield(L, HTTP_SERVICE_UNAVAILABLE);
+ makeintegerfield(L, HTTP_GATEWAY_TIME_OUT);
+ makeintegerfield(L, HTTP_VERSION_NOT_SUPPORTED);
+ makeintegerfield(L, HTTP_VARIANT_ALSO_VARIES);
+ makeintegerfield(L, HTTP_INSUFFICIENT_STORAGE);
+ makeintegerfield(L, HTTP_LOOP_DETECTED);
+ makeintegerfield(L, HTTP_NOT_EXTENDED);
+ makeintegerfield(L, HTTP_NETWORK_AUTHENTICATION_REQUIRED);
*/
}
@@ -240,6 +196,7 @@ AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
/* callback for cleaning up a lua vm when pool is closed */
static apr_status_t cleanup_lua(void *l)
{
+ AP_DEBUG_ASSERT(l != NULL);
lua_close((lua_State *) l);
return APR_SUCCESS;
}
@@ -319,7 +276,7 @@ static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
#endif
-static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_pool)
+static apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifecycle_pool)
{
lua_State* L;
@@ -357,24 +314,10 @@ static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_
"loading lua file %s", spec->file);
rc = luaL_loadfile(L, spec->file);
if (rc != 0) {
- char *err;
- switch (rc) {
- case LUA_ERRSYNTAX:
- err = "syntax error";
- break;
- case LUA_ERRMEM:
- err = "memory allocation error";
- break;
- case LUA_ERRFILE:
- err = "error opening or reading file";
- break;
- default:
- err = "unknown error";
- break;
- }
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
- "Loading lua file %s: %s",
- spec->file, err);
+ "Error loading %s: %s", spec->file,
+ rc == LUA_ERRMEM ? "memory allocation error"
+ : lua_tostring(L, 0));
return APR_EBADF;
}
lua_pcall(L, 0, LUA_MULTRET, 0);
@@ -407,7 +350,8 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
"creating lua_State with file %s", spec->file);
/* not available, so create */
- if(!vm_construct((void **)&L, spec, lifecycle_pool)) {
+ if(!vm_construct(&L, spec, lifecycle_pool)) {
+ AP_DEBUG_ASSERT(L != NULL);
apr_pool_userdata_set(L,
spec->file,
cleanup_lua,
diff --git a/modules/lua/lua_vmprep.h b/modules/lua/lua_vmprep.h
index be1750df..1d3758ca 100644
--- a/modules/lua/lua_vmprep.h
+++ b/modules/lua/lua_vmprep.h
@@ -54,7 +54,7 @@ typedef struct
apr_array_header_t *package_cpaths;
/* name of base file to load in the vm */
- char *file;
+ const char *file;
/* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_THREAD */
int scope;
@@ -75,8 +75,8 @@ typedef struct
typedef struct
{
- char *function_name;
- char *file_name;
+ const char *function_name;
+ const char *file_name;
int scope;
ap_regex_t *uri_pattern;
const char *bytecode;
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 095e54fd..b5b626d1 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -24,6 +24,7 @@
#include "lua_config.h"
#include "apr_optional.h"
#include "mod_ssl.h"
+#include "mod_auth.h"
#ifdef APR_HAS_THREADS
#include "apr_thread_proc.h"
@@ -39,11 +40,22 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
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;
+module AP_MODULE_DECLARE_DATA lua_module;
#define AP_LUA_HOOK_FIRST (APR_HOOK_FIRST - 1)
#define AP_LUA_HOOK_LAST (APR_HOOK_LAST + 1)
+typedef struct {
+ const char *name;
+ const char *file_name;
+ const char *function_name;
+ ap_lua_vm_spec *spec;
+ apr_array_header_t *args;
+} lua_authz_provider_spec;
+
+apr_hash_t *lua_authz_providers;
+
+
/**
* error reporting if lua has an error.
* Extracts the error from lua stack and prints
@@ -78,73 +90,114 @@ static int lua_open_hook(lua_State *L, apr_pool_t *p)
return OK;
}
+static const char *scope_to_string(unsigned int scope)
+{
+ switch (scope) {
+ case AP_LUA_SCOPE_ONCE:
+ case AP_LUA_SCOPE_UNSET:
+ return "once";
+ case AP_LUA_SCOPE_REQUEST:
+ return "request";
+ case AP_LUA_SCOPE_CONN:
+ return "conn";
+#if APR_HAS_THREADS
+ case AP_LUA_SCOPE_THREAD:
+ return "thread";
+#endif
+ default:
+ ap_assert(0);
+ }
+}
+
+static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
+ request_rec *r,
+ const ap_lua_dir_cfg *cfg,
+ const ap_lua_server_cfg *server_cfg,
+ const char *filename,
+ const char *bytecode,
+ apr_size_t bytecode_len,
+ const char *function,
+ const char *what)
+{
+ apr_pool_t *pool;
+ ap_lua_vm_spec *spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
+
+ spec->scope = cfg->vm_scope;
+ spec->pool = r->pool;
+ spec->package_paths = cfg->package_paths;
+ spec->package_cpaths = cfg->package_cpaths;
+ spec->cb = &lua_open_callback;
+ spec->cb_arg = NULL;
+ spec->bytecode = bytecode;
+ spec->bytecode_len = bytecode_len;
+
+ if (filename) {
+ char *file;
+ apr_filepath_merge(&file, server_cfg->root_path,
+ filename, APR_FILEPATH_NOTRELATIVE, r->pool);
+ spec->file = file;
+ }
+ else {
+ spec->file = r->filename;
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO(02313)
+ "%s details: scope: %s, file: %s, func: %s",
+ what, scope_to_string(spec->scope), spec->file,
+ function ? function : "-");
+
+ switch (spec->scope) {
+ case AP_LUA_SCOPE_ONCE:
+ case AP_LUA_SCOPE_UNSET:
+ apr_pool_create(&pool, r->pool);
+ break;
+ case AP_LUA_SCOPE_REQUEST:
+ pool = r->pool;
+ break;
+ case AP_LUA_SCOPE_CONN:
+ pool = r->connection->pool;
+ break;
+#if APR_HAS_THREADS
+ case AP_LUA_SCOPE_THREAD:
+ pool = apr_thread_pool_get(r->connection->current_thread);
+ break;
+#endif
+ default:
+ ap_assert(0);
+ }
+
+ *lifecycle_pool = pool;
+ return spec;
+}
+
/**
* "main"
*/
static int lua_handler(request_rec *r)
{
- ap_lua_dir_cfg *dcfg;
- apr_pool_t *pool;
if (strcmp(r->handler, "lua-script")) {
return DECLINED;
}
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01472) "handling [%s] in mod_lua",
- r->filename);
- dcfg = ap_get_module_config(r->per_dir_config, &lua_module);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(01472)
+ "handling [%s] in mod_lua", r->filename);
+ /* XXX: This seems wrong because it may generate wrong headers for HEAD requests */
if (!r->header_only) {
lua_State *L;
+ apr_pool_t *pool;
const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
&lua_module);
- ap_lua_vm_spec *spec = NULL;
+ ap_lua_vm_spec *spec = create_vm_spec(&pool, r, cfg, NULL, NULL, NULL,
+ 0, "handle", "request handler");
- spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
- spec->scope = dcfg->vm_scope;
- spec->pool = r->pool;
- spec->file = r->filename;
- spec->package_paths = cfg->package_paths;
- spec->package_cpaths = cfg->package_cpaths;
- spec->cb = &lua_open_callback;
- spec->cb_arg = NULL;
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01473)
- "request details scope:%u, filename:%s, function:%s",
- spec->scope,
- spec->file,
- "handle");
-
- switch (spec->scope) {
- case AP_LUA_SCOPE_ONCE:
- case AP_LUA_SCOPE_UNSET:
- apr_pool_create(&pool, r->pool);
- break;
- case AP_LUA_SCOPE_REQUEST:
- pool = r->pool;
- break;
- case AP_LUA_SCOPE_CONN:
- pool = r->connection->pool;
- break;
- case AP_LUA_SCOPE_THREAD:
- #if APR_HAS_THREADS
- pool = apr_thread_pool_get(r->connection->current_thread);
- break;
- #endif
- default:
- ap_assert(0);
- }
-
- L = ap_lua_get_lua_state(pool,
- spec);
-
+ L = ap_lua_get_lua_state(pool, spec);
if (!L) {
/* TODO annotate spec with failure reason */
r->status = HTTP_INTERNAL_SERVER_ERROR;
ap_rputs("Unable to compile VM, see logs", r);
return HTTP_INTERNAL_SERVER_ERROR;
}
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01474) "got a vm!");
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, APLOGNO(01474) "got a vm!");
lua_getglobal(L, "handle");
if (!lua_isfunction(L, -1)) {
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01475)
@@ -163,7 +216,6 @@ static int lua_handler(request_rec *r)
-
/* ---------------- Configury stuff --------------- */
/** harnesses for magic hooks **/
@@ -190,46 +242,12 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
if (hook_spec == NULL) {
continue;
}
- spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
-
- spec->file = hook_spec->file_name;
- spec->scope = cfg->vm_scope;
- spec->bytecode = hook_spec->bytecode;
- spec->bytecode_len = hook_spec->bytecode_len;
- spec->pool = r->pool;
- spec->package_paths = cfg->package_paths;
- spec->package_cpaths = cfg->package_cpaths;
- spec->cb = &lua_open_callback;
- spec->cb_arg = NULL;
-
- apr_filepath_merge(&spec->file, server_cfg->root_path,
- spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01476)
- "request details scope:%u, filename:%s, function:%s",
- spec->scope,
- spec->file,
- hook_spec->function_name ? hook_spec->function_name : "-");
-
- switch (spec->scope) {
- case AP_LUA_SCOPE_ONCE:
- case AP_LUA_SCOPE_UNSET:
- apr_pool_create(&pool, r->pool);
- break;
- case AP_LUA_SCOPE_REQUEST:
- pool = r->pool;
- break;
- case AP_LUA_SCOPE_CONN:
- pool = r->connection->pool;
- break;
- case AP_LUA_SCOPE_THREAD:
- #if APR_HAS_THREADS
- pool = apr_thread_pool_get(r->connection->current_thread);
- break;
- #endif
- default:
- ap_assert(0);
- }
+ spec = create_vm_spec(&pool, r, cfg, server_cfg,
+ hook_spec->file_name,
+ hook_spec->bytecode,
+ hook_spec->bytecode_len,
+ hook_spec->function_name,
+ "request hook");
L = ap_lua_get_lua_state(pool, spec);
@@ -450,16 +468,15 @@ static const char *register_named_block_function_hook(const char *name,
{
cr_ctx ctx;
- char buf[32];
lua_State *lvm;
char *tmp;
int rv;
ap_directive_t **current;
hack_section_baton *baton;
- apr_snprintf(buf, sizeof(buf), "%u", cmd->config_file->line_number);
- spec->file_name = apr_pstrcat(cmd->pool, cmd->config_file->name, ":",
- buf, NULL);
+ spec->file_name = apr_psprintf(cmd->pool, "%s:%u",
+ cmd->config_file->name,
+ cmd->config_file->line_number);
if (function) {
spec->function_name = (char *) function;
}
@@ -959,6 +976,131 @@ AP_LUA_DECLARE(int) ap_lua_ssl_is_https(conn_rec *c)
/*******************************/
+static const char *lua_authz_parse(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *provider_name;
+ lua_authz_provider_spec *spec;
+
+ apr_pool_userdata_get((void**)&provider_name, AUTHZ_PROVIDER_NAME_NOTE,
+ cmd->temp_pool);
+ ap_assert(provider_name != NULL);
+
+ spec = apr_hash_get(lua_authz_providers, provider_name, APR_HASH_KEY_STRING);
+ ap_assert(spec != NULL);
+
+ if (require_line && *require_line) {
+ const char *arg;
+ spec->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
+ while ((arg = ap_getword_conf(cmd->pool, &require_line)) && *arg) {
+ APR_ARRAY_PUSH(spec->args, const char *) = arg;
+ }
+ }
+
+ *parsed_require_line = spec;
+ return NULL;
+}
+
+static authz_status lua_authz_check(request_rec *r, const char *require_line,
+ const void *parsed_require_line)
+{
+ apr_pool_t *pool;
+ ap_lua_vm_spec *spec;
+ lua_State *L;
+ ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
+ &lua_module);
+ const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
+ &lua_module);
+ const lua_authz_provider_spec *prov_spec = parsed_require_line;
+ int result;
+ int nargs = 0;
+
+ spec = create_vm_spec(&pool, r, cfg, server_cfg, prov_spec->file_name,
+ NULL, 0, prov_spec->function_name, "authz provider");
+
+ L = ap_lua_get_lua_state(pool, spec);
+ if (L == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02314)
+ "Unable to compile VM for authz provider %s", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ lua_getglobal(L, prov_spec->function_name);
+ if (!lua_isfunction(L, -1)) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02319)
+ "Unable to find function %s in %s",
+ prov_spec->function_name, prov_spec->file_name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ ap_lua_run_lua_request(L, r);
+ if (prov_spec->args) {
+ int i;
+ if (!lua_checkstack(L, prov_spec->args->nelts)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
+ "Error: authz provider %s: too many arguments", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ for (i = 0; i < prov_spec->args->nelts; i++) {
+ const char *arg = APR_ARRAY_IDX(prov_spec->args, i, const char *);
+ lua_pushstring(L, arg);
+ }
+ nargs = prov_spec->args->nelts;
+ }
+ if (lua_pcall(L, 1 + nargs, 1, 0)) {
+ const char *err = lua_tostring(L, -1);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02316)
+ "Error executing authz provider %s: %s", prov_spec->name, err);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ if (!lua_isnumber(L, -1)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02317)
+ "Error: authz provider %s did not return integer", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ result = lua_tointeger(L, -1);
+ switch (result) {
+ case AUTHZ_DENIED:
+ case AUTHZ_GRANTED:
+ case AUTHZ_NEUTRAL:
+ case AUTHZ_GENERAL_ERROR:
+ case AUTHZ_DENIED_NO_USER:
+ return result;
+ default:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02318)
+ "Error: authz provider %s: invalid return value %d",
+ prov_spec->name, result);
+ }
+ return AUTHZ_GENERAL_ERROR;
+}
+
+static const authz_provider lua_authz_provider =
+{
+ &lua_authz_check,
+ &lua_authz_parse,
+};
+
+static const char *register_authz_provider(cmd_parms *cmd, void *_cfg,
+ const char *name, const char *file,
+ const char *function)
+{
+ lua_authz_provider_spec *spec;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err)
+ return err;
+
+ spec = apr_pcalloc(cmd->pool, sizeof(*spec));
+ spec->name = name;
+ spec->file_name = file;
+ spec->function_name = function;
+
+ apr_hash_set(lua_authz_providers, name, APR_HASH_KEY_STRING, spec);
+ ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP, name,
+ AUTHZ_PROVIDER_VERSION,
+ &lua_authz_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ return NULL;
+}
+
+
command_rec lua_commands[] = {
AP_INIT_TAKE1("LuaRoot", register_lua_root, NULL, OR_ALL,
@@ -970,6 +1112,8 @@ command_rec lua_commands[] = {
AP_INIT_TAKE1("LuaPackageCPath", register_package_cdir, NULL, OR_ALL,
"Add a directory to lua's package.cpath"),
+ AP_INIT_TAKE3("LuaAuthzProvider", register_authz_provider, NULL, RSRC_CONF|EXEC_ON_READ,
+ "Provide an authorization provider"),
AP_INIT_TAKE23("LuaHookTranslateName", register_translate_name_hook, NULL,
OR_ALL,
@@ -1202,6 +1346,9 @@ static void lua_register_hooks(apr_pool_t *p)
APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL,
APR_HOOK_REALLY_FIRST);
+
+ /* providers */
+ lua_authz_providers = apr_hash_make(p);
}
AP_DECLARE_MODULE(lua) = {
diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h
index 5394f7a4..52ff96ad 100644
--- a/modules/lua/mod_lua.h
+++ b/modules/lua/mod_lua.h
@@ -40,6 +40,9 @@
#include "apr_time.h"
#include "apr_hooks.h"
+/* Allow for Lua 5.2 backwards compatibility */
+#define LUA_COMPAT_ALL
+
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
@@ -113,7 +116,7 @@ typedef struct
apr_hash_t *hooks; /* <wombat_hook_info> */
/* the actual directory being configured */
- char *dir;
+ const char *dir;
/* Whether Lua scripts in a sub-dir are run before parents */
ap_lua_inherit_t inherit;
@@ -131,7 +134,7 @@ typedef struct
typedef struct
{
- char *function_name;
+ const char *function_name;
ap_lua_vm_spec *spec;
} mapped_request_details;
@@ -144,7 +147,7 @@ typedef struct
typedef struct
{
lua_State *L;
- char *function;
+ const char *function;
} ap_lua_filter_ctx;
extern module AP_MODULE_DECLARE_DATA lua_module;