mod_lua.c revision 4b6783e47ad1c5346329e903ce1d24f5a0c6ca6b
842ae4bd224140319ae7feec1872b93dfd491143fielding * Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *lua_ssl_val = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic APR_OPTIONAL_FN_TYPE(ssl_is_https) *lua_ssl_is_https = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *name;
11f2b9c5d2411bb84925addb4c2bf66e3a375383wrowe * error reporting if lua has an error.
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm * Extracts the error from lua stack and prints
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colmstatic void report_lua_error(lua_State *L, request_rec *r)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *lua_response;
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, r->pool, APLOGNO(01471) "Lua error: %s",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void lua_open_callback(lua_State *L, apr_pool_t *p, void *ctx)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm return "once";
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm return "request";
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm return "conn";
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm return "thread";
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colmstatic ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *filename,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *bytecode,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *function,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *what)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_lua_vm_spec *spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
2b672ae3a6d190fb62d04f4f47bbdc0a2bde151fcolm spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache;
2b672ae3a6d190fb62d04f4f47bbdc0a2bde151fcolm ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO(02313)
db848a70422b56cf0f15a47c37e17ebe05e2ce04stoddard "%s details: scope: %s, file: %s, func: %s",
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm pool = apr_thread_pool_get(r->connection->current_thread);
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(01472)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm /* XXX: This seems wrong because it may generate wrong headers for HEAD requests */
e8f95a682820a599fe41b22977010636be5c2717jim const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_lua_vm_spec *spec = create_vm_spec(&pool, r, cfg, NULL, NULL, NULL,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm /* TODO annotate spec with failure reason */
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, APLOGNO(01474) "got a vm!");
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01475)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm "lua: Unable to find function %s in %s",
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm/* ---------------- Configury stuff --------------- */
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm/** harnesses for magic hooks **/
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colmstatic int lua_request_rec_hook_harness(request_rec *r, const char *name, int apr_hook_when)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm const char *key = apr_psprintf(r->pool, "%s_%d", name, apr_hook_when);
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm "request hook");
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01477)
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm "lua: Failed to obtain lua interpreter for %s %s",
0b4b04d8621478ba59f0a6ba2950ddc02ab92b58colm ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01478)
e8f95a682820a599fe41b22977010636be5c2717jim "lua: Unable to find function %s in %s",
db848a70422b56cf0f15a47c37e17ebe05e2ce04stoddardstatic apr_size_t config_getstr(ap_configfile_t *cfg, char *buf,
e8f95a682820a599fe41b22977010636be5c2717jim apr_status_t rc = (cfg->getstr) (buf, bufsiz, cfg->param);
while (i < bufsiz) {
char ch;
typedef struct cr_ctx
const char *endstr;
} cr_ctx;
static const char *lf =
return lf;
apr_size_t i = 0;
*plen = 0;
return NULL;
typedef struct hack_section_baton
const char *name;
int apr_hook_when;
const char *arg)
if (!hook_specs) {
sizeof(ap_lua_mapped_handler_spec *));
return NULL;
void *mconfig,
const char *line)
if (line[0]) {
const char *word;
char *tmp;
int rv;
if (function) {
/* This lua State is used only to compile the input strings -> bytecode, so we don't need anything extra. */
if (rv != 0) {
return errstr;
luaL_Buffer b;
luaL_pushresult(&b);
if (!*current) {
return NULL;
void *_cfg,
const char *file,
const char *function,
int apr_hook_when)
if (!hook_specs) {
sizeof(ap_lua_mapped_handler_spec *));
return NULL;
if (lookup) {
return DECLINED;
const char *file,
const char *function,
const char *when)
if (err) {
return err;
if (when) {
const char *line)
line);
const char *file,
const char *function)
const char *line)
const char *file,
const char *function)
const char *line)
line);
const char *file,
const char *function,
const char *when)
if (when) {
const char *line)
line);
const char *file,
const char *function)
const char *line)
line);
const char *file,
const char *function,
const char *when)
if (when) {
const char *line)
line);
const char *file,
const char *function,
const char *when)
if (when) {
const char *line)
line);
const char *file,
const char *function)
if (err) {
return err;
const char *line)
line);
const char *arg,
char *fixed_filename;
arg,
return NULL;
const char *arg)
void *_cfg,
const char *arg)
void *_cfg,
const char *arg)
arg);
return NULL;
void *_cfg,
const char *arg)
arg);
return NULL;
void *_cfg,
const char *scope,
const char *min,
const char *max)
#if !APR_HAS_THREADS
scope);
#if APR_HAS_THREADS
,scope);
return NULL;
const char *root)
&lua_module);
return NULL;
AP_LUA_DECLARE(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 NULL;
const void **parsed_require_line)
const char *provider_name;
const char *arg;
return NULL;
const void *parsed_require_line)
lua_State *L;
&lua_module);
&lua_module);
int result;
int nargs = 0;
if (L == NULL) {
return AUTHZ_GENERAL_ERROR;
return AUTHZ_GENERAL_ERROR;
ap_lua_run_lua_request(L, r);
return AUTHZ_GENERAL_ERROR;
return AUTHZ_GENERAL_ERROR;
return AUTHZ_GENERAL_ERROR;
switch (result) {
case AUTHZ_DENIED:
case AUTHZ_GRANTED:
case AUTHZ_NEUTRAL:
case AUTHZ_GENERAL_ERROR:
case AUTHZ_DENIED_NO_USER:
return result;
return AUTHZ_GENERAL_ERROR;
const char *function)
if (err)
return err;
return NULL;
"Add a directory to lua's package.cpath"),
NULL,
NULL,
NULL,
NULL,
{NULL}
return cfg;
return OK;
return cfg;
ap_lua_push_request(L, r);
return OK;
return OK;
const void *key,
const void *overlay_val,
const void *base_val,
const void *data)
a->codecache = (overrides->codecache== AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache;
/* http_request.h hooks */