/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mod_lua.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <apr_thread_mutex.h>
#include <apr_pools.h>
#include "lua_apr.h"
#include "lua_config.h"
#include "apr_optional.h"
#include "mod_auth.h"
#include "util_mutex.h"


#ifdef APR_HAS_THREADS
#include "apr_thread_proc.h"
#endif

/* getpid for *NIX */
#if APR_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif

/* getpid for Windows */
#if APR_HAVE_PROCESS_H
#include <process.h>
#endif

APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open,
                                    (lua_State *L, apr_pool_t *p),
                                    (L, p), OK, DECLINED)

APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
                                    (lua_State *L, request_rec *r),
                                    (L, r), OK, DECLINED)

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;
} lua_authz_provider_spec;

typedef struct {
    lua_authz_provider_spec *spec;
    apr_array_header_t *args;
} lua_authz_provider_func;

apr_hash_t *lua_authz_providers;

typedef struct
{
    apr_bucket_brigade *tmpBucket;
    lua_State *L;
    ap_lua_vm_spec *spec;
    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;

static apr_status_t shm_cleanup_wrapper(void *unused)
{
    if (lua_ivm_shm) {
        return apr_shm_destroy(lua_ivm_shm);
    }
    return OK;
}

/**
 * error reporting if lua has an error.
 * Extracts the error from lua stack and prints
 */
static void report_lua_error(lua_State *L, request_rec *r)
{
    const char *lua_response;
    r->status = HTTP_INTERNAL_SERVER_ERROR;
    r->content_type = "text/html";
    ap_rputs("<h3>Error!</h3>\n", r);
    ap_rputs("<pre>", r);
    lua_response = lua_tostring(L, -1);
    ap_rputs(ap_escape_html(r->pool, lua_response), r);
    ap_rputs("</pre>\n", r);

    ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, r->pool, APLOGNO(01471) "Lua error: %s",
                  lua_response);
}

static void lua_open_callback(lua_State *L, apr_pool_t *p, void *ctx)
{
    ap_lua_init(L, p);
    ap_lua_load_apache2_lmodule(L);
    ap_lua_load_request_lmodule(L, p);
    ap_lua_load_config_lmodule(L);
}

static int lua_open_hook(lua_State *L, apr_pool_t *p)
{
    lua_open_callback(L, p, NULL);
    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";
    case AP_LUA_SCOPE_SERVER:
        return "server";
#endif
    default:
        ap_assert(0);
        return 0;
    }
}

static void ap_lua_release_state(lua_State* L, ap_lua_vm_spec* spec, request_rec* r)
{
    char *hash;
    apr_reslist_t* reslist = NULL;

    if (spec->scope == AP_LUA_SCOPE_SERVER) {
        ap_lua_server_spec* sspec = NULL;
        lua_settop(L, 0);
        lua_getfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
        sspec = (ap_lua_server_spec*) lua_touserdata(L, 1);
        hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
        if (apr_pool_userdata_get((void **)&reslist, hash,
                                r->server->process->pool) == APR_SUCCESS) {
            AP_DEBUG_ASSERT(sspec != NULL);
            if (reslist != NULL) {
                apr_reslist_release(reslist, sspec);
            }
        }
    }
}

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;
    spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache;
    spec->vm_min = cfg->vm_min ? cfg->vm_min : 1;
    spec->vm_max = cfg->vm_max ? cfg->vm_max : 1;
    
    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,
                  "%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);
        apr_pool_tag(pool, "mod_lua-vm");
        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;
    case AP_LUA_SCOPE_SERVER:
        pool = r->server->process->pool;
        break;
#endif
    default:
        ap_assert(0);
    }

    *lifecycle_pool = pool;
    return spec;
}

static const char* ap_lua_interpolate_string(apr_pool_t* pool, const char* string, const char** values)
{
    char *stringBetween;
    const char* ret;
    int srclen,x,y;
    srclen = strlen(string);
    ret = "";
    y = 0;
    for (x=0; x < srclen; x++) {
        if (string[x] == '$' && x != srclen-1 && string[x+1] >= '0' && string[x+1] <= '9') {
            int v = *(string+x+1) - '0';
            if (x-y > 0) {
                stringBetween = apr_pstrndup(pool, string+y, x-y);
            }
            else {
                stringBetween = "";
            }
            ret = apr_pstrcat(pool, ret, stringBetween, values[v], NULL);
            y = ++x+1;
        }
    }
    
    if (x-y > 0 && y > 0) {
        stringBetween = apr_pstrndup(pool, string+y, x-y);
        ret = apr_pstrcat(pool, ret, stringBetween, NULL);
    }
    /* If no replacement was made, just return the original string */
    else if (y == 0) {
        return string;
    }
    return ret;
}



/**
 * "main"
 */
static int lua_handler(request_rec *r)
{
    int rc = OK;
    if (strcmp(r->handler, "lua-script")) {
        return DECLINED;
    }
    /* Decline the request if the script does not exist (or is a directory),
     * rather than just returning internal server error */
    if (
            (r->finfo.filetype == APR_NOFILE)
            || (r->finfo.filetype & APR_DIR)
        ) {
        return DECLINED;
    }
    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                  "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 = create_vm_spec(&pool, r, cfg, NULL, NULL, NULL,
                                              0, "handle", "request handler");

        L = ap_lua_get_lua_state(pool, spec, r);
        if (!L) {
            /* TODO annotate spec with failure reason */
            r->status = HTTP_INTERNAL_SERVER_ERROR;
            ap_rputs("Unable to compile VM, see logs", r);
            ap_lua_release_state(L, spec, r);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "got a vm!");
        lua_getglobal(L, "handle");
        if (!lua_isfunction(L, -1)) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01475)
                          "lua: Unable to find entry function '%s' in %s (not a valid function)",
                          "handle",
                          spec->file);
            ap_lua_release_state(L, spec, r);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ap_lua_run_lua_request(L, r);
        if (lua_pcall(L, 1, 1, 0)) {
            report_lua_error(L, r);
        }
        if (lua_isnumber(L, -1)) {
            rc = lua_tointeger(L, -1);
        }
        ap_lua_release_state(L, spec, r);
    }
    return rc;
}


/* ------------------- Input/output content filters ------------------- */


static apr_status_t lua_setup_filter_ctx(ap_filter_t* f, request_rec* r, lua_filter_ctx** c)
{
    apr_pool_t *pool;
    ap_lua_vm_spec *spec;
    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,
                                                        &lua_module);
    const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                    &lua_module);
    
    ctx = apr_pcalloc(r->pool, sizeof(lua_filter_ctx));
    ctx->broken = 0;
    *c = ctx;
    /* 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];

        if (hook_spec == NULL) {
            continue;
        }
        if (!strcasecmp(hook_spec->filter_name, f->frec->name)) {
            spec = create_vm_spec(&pool, r, cfg, server_cfg,
                                    hook_spec->file_name,
                                    NULL,
                                    0,
                                    hook_spec->function_name,
                                    "filter");
            L = ap_lua_get_lua_state(pool, spec, r);
            if (L) {
                L = lua_newthread(L);
            }

            if (!L) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02328)
                                "lua: Failed to obtain lua interpreter for %s %s",
                                hook_spec->function_name, hook_spec->file_name);
                ap_lua_release_state(L, spec, r);
                return APR_EGENERAL;
            }
            if (hook_spec->function_name != NULL) {
                lua_getglobal(L, hook_spec->function_name);
                if (!lua_isfunction(L, -1)) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02329)
                                "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                    hook_spec->function_name,
                                    hook_spec->file_name);
                    ap_lua_release_state(L, spec, r);
                    return APR_EGENERAL;
                }

                ap_lua_run_lua_request(L, r);
            }
            else {
                int t;
                ap_lua_run_lua_request(L, r);

                t = lua_gettop(L);
                lua_setglobal(L, "r");
                lua_settop(L, t);
            }
            ctx->L = L;
            ctx->spec = spec;
            
            /* 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, &nres);
            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 {
                ap_lua_release_state(L, spec, r);
                return APR_ENOENT;
            }
        }
    }
    return APR_ENOENT;
}

static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade *pbbIn)
{
    request_rec *r = f->r;
    int rc, nres;
    lua_State *L;
    lua_filter_ctx* ctx;
    conn_rec *c = r->connection;
    apr_bucket *pbktIn;
    apr_status_t rv;
    
    /* Set up the initial filter context and acquire the function.
     * The corresponding Lua function should yield here.
     */
    if (!f->ctx) {
        rc = lua_setup_filter_ctx(f,r,&ctx);
        if (rc == APR_EGENERAL) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (rc == APR_ENOENT) {
            /* No filter entry found (or the script declined to filter), just pass on the buckets */
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next,pbbIn);
        }
        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;
    /* While the Lua function is still yielding, pass in buckets to the coroutine */
    if (!ctx->broken) {
        while (!APR_BRIGADE_EMPTY(pbbIn)) {
            const char *data;
            apr_size_t len;
            apr_bucket *pbktOut;

            pbktIn = APR_BRIGADE_FIRST(pbbIn);
            if (APR_BUCKET_IS_EOS(pbktIn)) {
                break;
            }

            /* read the bucket */
            apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);

            /* Push the bucket onto the Lua stack as a global var */
            lua_pushlstring(L, data, len);
            lua_setglobal(L, "bucket");
            
            /* If Lua yielded, it means we have something to pass on */
            if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                size_t olen;
                const char* output = lua_tolstring(L, 1, &olen);
                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 {
                ctx->broken = 1;
                ap_lua_release_state(L, ctx->spec, r);
                ap_remove_output_filter(f);
                apr_brigade_cleanup(pbbIn);
                apr_brigade_cleanup(ctx->tmpBucket);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02663)
                              "lua: Error while executing filter: %s",
                              lua_tostring(L, -1));
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            apr_bucket_delete(pbktIn);
        }
        /* If we've safely reached the end, do a final call to Lua to allow for any 
        finishing moves by the script, such as appending a tail. */
        if (!APR_BRIGADE_EMPTY(pbbIn) && APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(pbbIn))) {
            apr_bucket *pbktEOS;
            lua_pushnil(L);
            lua_setglobal(L, "bucket");
            if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                apr_bucket *pbktOut;
                size_t olen;
                const char* output = lua_tolstring(L, 1, &olen);
                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);
            ap_lua_release_state(L, ctx->spec, r);
            rv = ap_pass_brigade(f->next, ctx->tmpBucket);
            apr_brigade_cleanup(ctx->tmpBucket);
            if (rv != APR_SUCCESS) {
                return rv;
            }
        }
    }
    /* Clean up */
    apr_brigade_cleanup(pbbIn);
    return APR_SUCCESS;    
}



static apr_status_t lua_input_filter_handle(ap_filter_t *f,
                                       apr_bucket_brigade *pbbOut,
                                       ap_input_mode_t eMode,
                                       apr_read_type_e eBlock,
                                       apr_off_t nBytes) 
{
    request_rec *r = f->r;
    int rc, lastCall = 0, nres;
    lua_State *L;
    lua_filter_ctx* ctx;
    conn_rec *c = r->connection;
    apr_status_t ret;
    
    /* Set up the initial filter context and acquire the function.
     * The corresponding Lua function should yield here.
     */
    if (!f->ctx) {
        rc = lua_setup_filter_ctx(f,r,&ctx);
        f->ctx = ctx;
        if (rc == APR_EGENERAL) {
            ctx->broken = 1;
            ap_remove_input_filter(f); 
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (rc == APR_ENOENT ) {
            ap_remove_input_filter(f);
            ctx->broken = 1;
        }
        if (rc == APR_SUCCESS) {
            ctx->tmpBucket = apr_brigade_create(r->pool, c->bucket_alloc);
        }
    }
    ctx = (lua_filter_ctx*) f->ctx;
    L = ctx->L;
    /* If the Lua script broke or denied serving the request, just pass the buckets through */
    if (ctx->broken) {
        return ap_get_brigade(f->next, pbbOut, eMode, eBlock, nBytes);
    }
    
    if (APR_BRIGADE_EMPTY(ctx->tmpBucket)) {
        ret = ap_get_brigade(f->next, ctx->tmpBucket, eMode, eBlock, nBytes);
        if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS)
            return ret;
    }
    
    /* While the Lua function is still yielding, pass buckets to the coroutine */
    if (!ctx->broken) {
        lastCall = 0;
        while (!APR_BRIGADE_EMPTY(ctx->tmpBucket)) {
            apr_bucket *pbktIn = APR_BRIGADE_FIRST(ctx->tmpBucket);
            apr_bucket *pbktOut;
            const char *data;
            apr_size_t len;
            
            if (APR_BUCKET_IS_EOS(pbktIn)) {
                APR_BUCKET_REMOVE(pbktIn);
                break;
            }

            /* read the bucket */
            ret = apr_bucket_read(pbktIn, &data, &len, eBlock);
            if (ret != APR_SUCCESS)
                return ret;

            /* Push the bucket onto the Lua stack as a global var */
            lastCall++;
            lua_pushlstring(L, data, len);
            lua_setglobal(L, "bucket");
            
            /* If Lua yielded, it means we have something to pass on */
            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);
                APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut);
                apr_bucket_delete(pbktIn);
                return APR_SUCCESS;
            }
            else {
                ctx->broken = 1;
                ap_lua_release_state(L, ctx->spec, r);
                ap_remove_input_filter(f); 
                apr_bucket_delete(pbktIn);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
        /* If we've safely reached the end, do a final call to Lua to allow for any 
        finishing moves by the script, such as appending a tail. */
        if (lastCall == 0) {
            apr_bucket *pbktEOS = apr_bucket_eos_create(c->bucket_alloc);
            lua_pushnil(L);
            lua_setglobal(L, "bucket");
            if (lua_resume(L, 0, &nres) == LUA_YIELD && nres == 1) {
                apr_bucket *pbktOut;
                size_t olen;
                const char* output = lua_tolstring(L, 1, &olen);
                pbktOut = apr_bucket_heap_create(output, olen, 0, c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut);
            }
            APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
            ap_lua_release_state(L, ctx->spec, r);
        }
    }
    return APR_SUCCESS;
}


/* ---------------- Configury stuff --------------- */

/** harnesses for magic hooks **/

static int lua_request_rec_hook_harness(request_rec *r, const char *name, int apr_hook_when)
{
    int rc;
    apr_pool_t *pool;
    lua_State *L;
    ap_lua_vm_spec *spec;
    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 char *key = apr_psprintf(r->pool, "%s_%d", name, apr_hook_when);
    apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                  APR_HASH_KEY_STRING);
    if (hook_specs) {
        int i;
        for (i = 0; i < hook_specs->nelts; i++) {
            ap_lua_mapped_handler_spec *hook_spec =
                ((ap_lua_mapped_handler_spec **) hook_specs->elts)[i];

            if (hook_spec == NULL) {
                continue;
            }
            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, r);

            if (!L) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01477)
                    "lua: Failed to obtain lua interpreter for entry function '%s' in %s",
                              hook_spec->function_name, hook_spec->file_name);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            if (hook_spec->function_name != NULL) {
                lua_getglobal(L, hook_spec->function_name);
                if (!lua_isfunction(L, -1)) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01478)
                               "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                  hook_spec->function_name,
                                  hook_spec->file_name);
                    ap_lua_release_state(L, spec, r);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }

                ap_lua_run_lua_request(L, r);
            }
            else {
                int t;
                ap_lua_run_lua_request(L, r);

                t = lua_gettop(L);
                lua_setglobal(L, "r");
                lua_settop(L, t);
            }

            if (lua_pcall(L, 1, 1, 0)) {
                report_lua_error(L, r);
                ap_lua_release_state(L, spec, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            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, APLOGNO(03017)
                              "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);
                return rc;
            }
            ap_lua_release_state(L, spec, r);
        }
    }
    return DECLINED;
}


/* Fix for making sure that LuaMapHandler works when FallbackResource is set */
static int lua_map_handler_fixups(request_rec *r)
{
    /* If there is no handler set yet, this might be a LuaMapHandler request */
    if (r->handler == NULL) {
        int n = 0;
        ap_regmatch_t match[10];
        const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
                                                     &lua_module);
        for (n = 0; n < cfg->mapped_handlers->nelts; n++) {
            ap_lua_mapped_handler_spec *hook_spec =
            ((ap_lua_mapped_handler_spec **) cfg->mapped_handlers->elts)[n];

            if (hook_spec == NULL) {
                continue;
            }
            if (!ap_regexec(hook_spec->uri_pattern, r->uri, 10, match, 0)) {
                r->handler = apr_pstrdup(r->pool, "lua-map-handler");
                return OK;
            }
        }
    }
    return DECLINED;
}


static int lua_map_handler(request_rec *r)
{
    int rc, n = 0;
    apr_pool_t *pool;
    lua_State *L;
    const char *filename, *function_name;
    const char *values[10];
    ap_lua_vm_spec *spec;
    ap_regmatch_t match[10];
    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);
    for (n = 0; n < cfg->mapped_handlers->nelts; n++) {
        ap_lua_mapped_handler_spec *hook_spec =
            ((ap_lua_mapped_handler_spec **) cfg->mapped_handlers->elts)[n];

        if (hook_spec == NULL) {
            continue;
        }
        if (!ap_regexec(hook_spec->uri_pattern, r->uri, 10, match, 0)) {
            int i;
            for (i=0 ; i < 10; i++) {
                if (match[i].rm_eo >= 0) {
                    values[i] = apr_pstrndup(r->pool, r->uri+match[i].rm_so, match[i].rm_eo - match[i].rm_so);
                }
                else values[i] = "";
            }
            filename = ap_lua_interpolate_string(r->pool, hook_spec->file_name, values);
            function_name = ap_lua_interpolate_string(r->pool, hook_spec->function_name, values);
            spec = create_vm_spec(&pool, r, cfg, server_cfg,
                                    filename,
                                    hook_spec->bytecode,
                                    hook_spec->bytecode_len,
                                    function_name,
                                    "mapped handler");
            L = ap_lua_get_lua_state(pool, spec, r);

            if (!L) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02330)
                                "lua: Failed to obtain Lua interpreter for entry function '%s' in %s",
                                function_name, filename);
                ap_lua_release_state(L, spec, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            if (function_name != NULL) {
                lua_getglobal(L, function_name);
                if (!lua_isfunction(L, -1)) {
                    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02331)
                                    "lua: Unable to find entry function '%s' in %s (not a valid function)",
                                    function_name,
                                    filename);
                    ap_lua_release_state(L, spec, r);
                    return HTTP_INTERNAL_SERVER_ERROR;
                }

                ap_lua_run_lua_request(L, r);
            }
            else {
                int t;
                ap_lua_run_lua_request(L, r);

                t = lua_gettop(L);
                lua_setglobal(L, "r");
                lua_settop(L, t);
            }

            if (lua_pcall(L, 1, 1, 0)) {
                report_lua_error(L, r);
                ap_lua_release_state(L, spec, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            rc = DECLINED;
            if (lua_isnumber(L, -1)) {
                rc = lua_tointeger(L, -1);
            }
            else { 
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02483)
                              "lua: Lua handler %s in %s did not return a value, assuming apache2.OK",
                              function_name,
                              filename);
                rc = OK;
            }
            ap_lua_release_state(L, spec, r);
            if (rc != DECLINED) {
                return rc;
            }
        }
    }
    return DECLINED;
}


static apr_size_t config_getstr(ap_configfile_t *cfg, char *buf,
                                size_t bufsiz)
{
    apr_size_t i = 0;

    if (cfg->getstr) {
        apr_status_t rc = (cfg->getstr) (buf, bufsiz, cfg->param);
        if (rc == APR_SUCCESS) {
            i = strlen(buf);
            if (i && buf[i - 1] == '\n')
                ++cfg->line_number;
        }
        else {
            buf[0] = '\0';
            i = 0;
        }
    }
    else {
        while (i < bufsiz) {
            char ch;
            apr_status_t rc = (cfg->getch) (&ch, cfg->param);
            if (rc != APR_SUCCESS)
                break;
            buf[i++] = ch;
            if (ch == '\n') {
                ++cfg->line_number;
                break;
            }
        }
    }
    return i;
}

typedef struct cr_ctx
{
    cmd_parms *cmd;
    ap_configfile_t *cfp;
    size_t startline;
    const char *endstr;
    char buf[HUGE_STRING_LEN];
} cr_ctx;


/* Okay, this deserves a little explanation -- in order for the errors that lua
 * generates to be 'accuarate', including line numbers, we basically inject
 * N line number new lines into the 'top' of the chunk reader.....
 *
 * be happy. this is cool.
 *
 */
static const char *lf =
    "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
#define N_LF 32

static const char *direct_chunkreader(lua_State *lvm, void *udata,
                                      size_t *plen)
{
    const char *p;
    struct cr_ctx *ctx = udata;

    if (ctx->startline) {
        *plen = ctx->startline > N_LF ? N_LF : ctx->startline;
        ctx->startline -= *plen;
        return lf;
    }
    *plen = config_getstr(ctx->cfp, ctx->buf, HUGE_STRING_LEN);

    for (p = ctx->buf; isspace(*p); ++p);
    if (p[0] == '<' && p[1] == '/') {
        apr_size_t i = 0;
        while (i < strlen(ctx->endstr)) {
            if (tolower(p[i + 2]) != ctx->endstr[i])
                return ctx->buf;
            ++i;
        }
        *plen = 0;
        return NULL;
    }
    /*fprintf(stderr, "buf read: %s\n", ctx->buf); */
    return ctx->buf;
}

static int ldump_writer(lua_State *L, const void *b, size_t size, void *B)
{
    (void) L;
    luaL_addlstring((luaL_Buffer *) B, (const char *) b, size);
    return 0;
}

typedef struct hack_section_baton
{
    const char *name;
    ap_lua_mapped_handler_spec *spec;
    int apr_hook_when;
} hack_section_baton;

/* You can be unhappy now.
 *
 * This is uncool.
 *
 * When you create a <Section handler in httpd, the only 'easy' way to create
 * a directory context is to parse the section, and convert it into a 'normal'
 * Configureation option, and then collapse the entire section, in memory,
 * back into the parent section -- from which you can then get the new directive
 * invoked.... anyways. evil. Rici taught me how to do this hack :-)
 */
static const char *hack_section_handler(cmd_parms *cmd, void *_cfg,
                                        const char *arg)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    ap_directive_t *directive = cmd->directive;
    hack_section_baton *baton = directive->data;
    const char *key = apr_psprintf(cmd->pool, "%s_%d", baton->name, baton->apr_hook_when);

    apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                  APR_HASH_KEY_STRING);
    if (!hook_specs) {
        hook_specs = apr_array_make(cmd->pool, 2,
                                    sizeof(ap_lua_mapped_handler_spec *));
        apr_hash_set(cfg->hooks, key,
                     APR_HASH_KEY_STRING, hook_specs);
    }

    baton->spec->scope = cfg->vm_scope;

    *(ap_lua_mapped_handler_spec **) apr_array_push(hook_specs) = baton->spec;

    return NULL;
}

static const char *register_named_block_function_hook(const char *name,
                                                      cmd_parms *cmd,
                                                      void *mconfig,
                                                      const char *line)
{
    const char *function = NULL;
    ap_lua_mapped_handler_spec *spec;
    int when = APR_HOOK_MIDDLE;
    const char *endp = ap_strrchr_c(line, '>');

    if (endp == NULL) {
        return apr_pstrcat(cmd->pool, cmd->cmd->name,
                           "> directive missing closing '>'", NULL);
    }

    line = apr_pstrndup(cmd->temp_pool, line, endp - line);

    if (line[0]) { 
        const char *word;
        word = ap_getword_conf(cmd->temp_pool, &line);
        if (*word) {
            function = apr_pstrdup(cmd->pool, word);
        }
        word = ap_getword_conf(cmd->temp_pool, &line);
        if (*word) {
            if (!strcasecmp("early", word)) { 
                when = AP_LUA_HOOK_FIRST;
            }
            else if (!strcasecmp("late", word)) {
                when = AP_LUA_HOOK_LAST;
            }
            else { 
                return apr_pstrcat(cmd->pool, cmd->cmd->name,
                                   "> 2nd argument must be 'early' or 'late'", NULL);
            }
        }
    }

    spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));

    {
        cr_ctx ctx;
        lua_State *lvm;
        char *tmp;
        int rv;
        ap_directive_t **current;
        hack_section_baton *baton;

        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;
        }
        else {
            function = NULL;
        }

        ctx.cmd = cmd;
        tmp = apr_pstrdup(cmd->pool, cmd->err_directive->directive + 1);
        ap_str_tolower(tmp);
        ctx.endstr = tmp;
        ctx.cfp = cmd->config_file;
        ctx.startline = cmd->config_file->line_number;

        /* This lua State is used only to compile the input strings -> bytecode, so we don't need anything extra. */
        lvm = luaL_newstate();

        lua_settop(lvm, 0);

        rv = lua_load(lvm, direct_chunkreader, &ctx, spec->file_name);

        if (rv != 0) {
            const char *errstr = apr_pstrcat(cmd->pool, "Lua Error:",
                                             lua_tostring(lvm, -1), NULL);
            lua_close(lvm);
            return errstr;
        }
        else {
            luaL_Buffer b;
            luaL_buffinit(lvm, &b);
            lua_dump(lvm, ldump_writer, &b);
            luaL_pushresult(&b);
            spec->bytecode_len = lua_rawlen(lvm, -1);
            spec->bytecode = apr_pstrmemdup(cmd->pool, lua_tostring(lvm, -1),
                                            spec->bytecode_len);
            lua_close(lvm);
        }

        current = mconfig;

        /* Here, we have to replace our current config node for the next pass */
        if (!*current) {
            *current = apr_pcalloc(cmd->pool, sizeof(**current));
        }

        baton = apr_pcalloc(cmd->pool, sizeof(hack_section_baton));
        baton->name = name;
        baton->spec = spec;
        baton->apr_hook_when = when;

        (*current)->filename = cmd->config_file->name;
        (*current)->line_num = cmd->config_file->line_number;
        (*current)->directive = apr_pstrdup(cmd->pool, "Lua_____ByteCodeHack");
        (*current)->args = NULL;
        (*current)->data = baton;
    }

    return NULL;
}

static const char *register_named_file_function_hook(const char *name,
                                                     cmd_parms *cmd,
                                                     void *_cfg,
                                                     const char *file,
                                                     const char *function,
                                                     int apr_hook_when)
{
    ap_lua_mapped_handler_spec *spec;
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    const char *key = apr_psprintf(cmd->pool, "%s_%d", name, apr_hook_when);
    apr_array_header_t *hook_specs = apr_hash_get(cfg->hooks, key,
                                                  APR_HASH_KEY_STRING);

    if (!hook_specs) {
        hook_specs = apr_array_make(cmd->pool, 2,
                                    sizeof(ap_lua_mapped_handler_spec *));
        apr_hash_set(cfg->hooks, key, APR_HASH_KEY_STRING, hook_specs);
    }

    spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));
    spec->file_name = apr_pstrdup(cmd->pool, file);
    spec->function_name = apr_pstrdup(cmd->pool, function);
    spec->scope = cfg->vm_scope;

    *(ap_lua_mapped_handler_spec **) apr_array_push(hook_specs) = spec;
    return NULL;
}
static const char *register_mapped_file_function_hook(const char *pattern,
                                                     cmd_parms *cmd,
                                                     void *_cfg,
                                                     const char *file,
                                                     const char *function)
{
    ap_lua_mapped_handler_spec *spec;
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    ap_regex_t *regex = apr_pcalloc(cmd->pool, sizeof(ap_regex_t));
    if (ap_regcomp(regex, pattern,0)) {
        return "Invalid regex pattern!";
    }

    spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_mapped_handler_spec));
    spec->file_name = apr_pstrdup(cmd->pool, file);
    spec->function_name = apr_pstrdup(cmd->pool, function);
    spec->scope = cfg->vm_scope;
    spec->uri_pattern = regex;

    *(ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) = spec;
    return NULL;
}
static const char *register_filter_function_hook(const char *filter,
                                                     cmd_parms *cmd,
                                                     void *_cfg,
                                                     const char *file,
                                                     const char *function,
                                                     int direction)
{
    ap_lua_filter_handler_spec *spec;
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
   
    spec = apr_pcalloc(cmd->pool, sizeof(ap_lua_filter_handler_spec));
    spec->file_name = apr_pstrdup(cmd->pool, file);
    spec->function_name = apr_pstrdup(cmd->pool, function);
    spec->filter_name = filter;

    *(ap_lua_filter_handler_spec **) apr_array_push(cfg->mapped_filters) = spec;
    /* 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_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;
        ap_register_input_filter(filter, lua_input_filter_handle, NULL, AP_FTYPE_RESOURCE);
    }
    return NULL;
}
/* disabled (see reference below)
static int lua_check_user_id_harness_first(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "check_user_id", AP_LUA_HOOK_FIRST);
}
*/
static int lua_check_user_id_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "check_user_id", APR_HOOK_MIDDLE);
}
/* disabled (see reference below)
static int lua_check_user_id_harness_last(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "check_user_id", AP_LUA_HOOK_LAST);
}
*/

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);
}
static int lua_translate_name_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "translate_name", APR_HOOK_MIDDLE);
}
static int lua_translate_name_harness_last(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "translate_name", AP_LUA_HOOK_LAST);
}

static int lua_fixup_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "fixups", APR_HOOK_MIDDLE);
}

static int lua_map_to_storage_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "map_to_storage", APR_HOOK_MIDDLE);
}

static int lua_type_checker_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "type_checker", APR_HOOK_MIDDLE);
}

static int lua_access_checker_harness_first(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "access_checker", AP_LUA_HOOK_FIRST);
}
static int lua_access_checker_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "access_checker", APR_HOOK_MIDDLE);
}
static int lua_access_checker_harness_last(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "access_checker", AP_LUA_HOOK_LAST);
}

static int lua_auth_checker_harness_first(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "auth_checker", AP_LUA_HOOK_FIRST);
}
static int lua_auth_checker_harness(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "auth_checker", APR_HOOK_MIDDLE);
}
static int lua_auth_checker_harness_last(request_rec *r)
{
    return lua_request_rec_hook_harness(r, "auth_checker", AP_LUA_HOOK_LAST);
}
static void lua_insert_filter_harness(request_rec *r)
{
    /* ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03223)
     *               "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) {
        return DECLINED;
    }
    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,
                                                const char *when)
{
    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                           NOT_IN_HTACCESS);
    int apr_hook_when = APR_HOOK_MIDDLE;
    if (err) {
        return err;
    }
    
    if (when) { 
        if (!strcasecmp(when, "early")) { 
            apr_hook_when = AP_LUA_HOOK_FIRST;
        } 
        else if (!strcasecmp(when, "late")) { 
            apr_hook_when = AP_LUA_HOOK_LAST;
        } 
        else { 
            return "Third argument must be 'early' or 'late'";
        }
    }

    return register_named_file_function_hook("translate_name", cmd, _cfg,
                                             file, function, apr_hook_when);
}

static const char *register_translate_name_block(cmd_parms *cmd, void *_cfg,
                                                 const char *line)
{
    return register_named_block_function_hook("translate_name", cmd, _cfg,
                                              line);
}


static const char *register_fixups_hook(cmd_parms *cmd, void *_cfg,
                                        const char *file,
                                        const char *function)
{
    return register_named_file_function_hook("fixups", cmd, _cfg, file,
                                             function, APR_HOOK_MIDDLE);
}
static const char *register_fixups_block(cmd_parms *cmd, void *_cfg,
                                         const char *line)
{
    return register_named_block_function_hook("fixups", cmd, _cfg, line);
}

static const char *register_map_to_storage_hook(cmd_parms *cmd, void *_cfg,
                                                const char *file,
                                                const char *function)
{
    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)
{
    return register_named_block_function_hook("map_to_storage", cmd, _cfg,
                                              line);
}


static const char *register_check_user_id_hook(cmd_parms *cmd, void *_cfg,
                                               const char *file,
                                               const char *function,
                                               const char *when)
{
    int apr_hook_when = APR_HOOK_MIDDLE;
/* XXX: This does not currently work!!
    if (when) {
        if (!strcasecmp(when, "early")) {
            apr_hook_when = AP_LUA_HOOK_FIRST;
        }
        else if (!strcasecmp(when, "late")) {
            apr_hook_when = AP_LUA_HOOK_LAST;
        }
        else {
            return "Third argument must be 'early' or 'late'";
        }
    }
*/
    return register_named_file_function_hook("check_user_id", cmd, _cfg, file,
                                             function, apr_hook_when);
}
static const char *register_check_user_id_block(cmd_parms *cmd, void *_cfg,
                                                const char *line)
{
    return register_named_block_function_hook("check_user_id", cmd, _cfg,
                                              line);
}

static const char *register_type_checker_hook(cmd_parms *cmd, void *_cfg,
                                              const char *file,
                                              const char *function)
{
    return register_named_file_function_hook("type_checker", cmd, _cfg, file,
                                             function, APR_HOOK_MIDDLE);
}
static const char *register_type_checker_block(cmd_parms *cmd, void *_cfg,
                                               const char *line)
{
    return register_named_block_function_hook("type_checker", cmd, _cfg,
                                              line);
}

static const char *register_access_checker_hook(cmd_parms *cmd, void *_cfg,
                                                const char *file,
                                                const char *function,
                                                const char *when)
{
    int apr_hook_when = APR_HOOK_MIDDLE;

    if (when) {
        if (!strcasecmp(when, "early")) {
            apr_hook_when = AP_LUA_HOOK_FIRST;
        }
        else if (!strcasecmp(when, "late")) {
            apr_hook_when = AP_LUA_HOOK_LAST;
        }
        else {
            return "Third argument must be 'early' or 'late'";
        }
    }

    return register_named_file_function_hook("access_checker", cmd, _cfg,
                                             file, function, apr_hook_when);
}
static const char *register_access_checker_block(cmd_parms *cmd, void *_cfg,
                                                 const char *line)
{

    return register_named_block_function_hook("access_checker", cmd, _cfg,
                                              line);
}

static const char *register_auth_checker_hook(cmd_parms *cmd, void *_cfg,
                                              const char *file,
                                              const char *function,
                                              const char *when)
{
    int apr_hook_when = APR_HOOK_MIDDLE;

    if (when) {
        if (!strcasecmp(when, "early")) {
            apr_hook_when = AP_LUA_HOOK_FIRST;
        }
        else if (!strcasecmp(when, "late")) {
            apr_hook_when = AP_LUA_HOOK_LAST;
        }
        else {
            return "Third argument must be 'early' or 'late'";
        }
    }

    return register_named_file_function_hook("auth_checker", cmd, _cfg, file,
                                             function, apr_hook_when);
}
static const char *register_auth_checker_block(cmd_parms *cmd, void *_cfg,
                                               const char *line)
{
    return register_named_block_function_hook("auth_checker", cmd, _cfg,
                                              line);
}

static const char *register_insert_filter_hook(cmd_parms *cmd, void *_cfg,
                                               const char *file,
                                               const char *function)
{
    return "LuaHookInsertFilter not yet implemented";
}

static const char *register_quick_hook(cmd_parms *cmd, void *_cfg,
                                       const char *file, const char *function)
{
    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                NOT_IN_HTACCESS);
    if (err) {
        return err;
    }
    return register_named_file_function_hook("quick", cmd, _cfg, file,
                                             function, APR_HOOK_MIDDLE);
}
static const char *register_map_handler(cmd_parms *cmd, void *_cfg,
                                       const char* match, const char *file, const char *function)
{
    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                NOT_IN_HTACCESS);
    if (err) {
        return err;
    }
    if (!function) function = "handle";
    return register_mapped_file_function_hook(match, cmd, _cfg, file,
                                             function);
}
static const char *register_output_filter(cmd_parms *cmd, void *_cfg,
                                       const char* filter, const char *file, const char *function)
{
    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                NOT_IN_HTACCESS);
    if (err) {
        return err;
    }
    if (!function) function = "handle";
    return register_filter_function_hook(filter, cmd, _cfg, file,
                                             function, AP_LUA_FILTER_OUTPUT);
}
static const char *register_input_filter(cmd_parms *cmd, void *_cfg,
                                       const char* filter, const char *file, const char *function)
{
    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES|
                                                NOT_IN_HTACCESS);
    if (err) {
        return err;
    }
    if (!function) function = "handle";
    return register_filter_function_hook(filter, cmd, _cfg, file,
                                             function, AP_LUA_FILTER_INPUT);
}
static const char *register_quick_block(cmd_parms *cmd, void *_cfg,
                                        const char *line)
{
    return register_named_block_function_hook("quick", cmd, _cfg,
                                              line);
}



static const char *register_package_helper(cmd_parms *cmd, 
                                           const char *arg,
                                           apr_array_header_t *dir_array)
{
    apr_status_t rv;

    ap_lua_server_cfg *server_cfg =
        ap_get_module_config(cmd->server->module_config, &lua_module);

    char *fixed_filename;
    rv = apr_filepath_merge(&fixed_filename, 
                            server_cfg->root_path, 
                            arg,
                            APR_FILEPATH_NOTRELATIVE, 
                            cmd->pool);

    if (rv != APR_SUCCESS) {
        return apr_psprintf(cmd->pool,
                            "Unable to build full path to file, %s", arg);
    }

    *(const char **) apr_array_push(dir_array) = fixed_filename;
    return NULL;
}


/**
 * Called for config directive which looks like
 * LuaPackagePath /lua/package/path/mapped/thing/like/this/?.lua
 */
static const char *register_package_dir(cmd_parms *cmd, void *_cfg,
                                        const char *arg)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;

    return register_package_helper(cmd, arg, cfg->package_paths);
}

/**
 * Called for config directive which looks like
 * LuaPackageCPath /lua/package/path/mapped/thing/like/this/?.so
 */
static const char *register_package_cdir(cmd_parms *cmd, 
                                         void *_cfg,
                                         const char *arg)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;

    return register_package_helper(cmd, arg, cfg->package_cpaths);
}

static const char *register_lua_inherit(cmd_parms *cmd, 
                                      void *_cfg,
                                      const char *arg)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    
    if (strcasecmp("none", arg) == 0) {
        cfg->inherit = AP_LUA_INHERIT_NONE;
    }
    else if (strcasecmp("parent-first", arg) == 0) {
        cfg->inherit = AP_LUA_INHERIT_PARENT_FIRST;
    }
    else if (strcasecmp("parent-last", arg) == 0) {
        cfg->inherit = AP_LUA_INHERIT_PARENT_LAST;
    }
    else { 
        return apr_psprintf(cmd->pool,
                            "LuaInherit type of '%s' not recognized, valid "
                            "options are 'none', 'parent-first', and 'parent-last'", 
                            arg);
    }
    return NULL;
}
static const char *register_lua_codecache(cmd_parms *cmd, 
                                      void *_cfg,
                                      const char *arg)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    
    if (strcasecmp("never", arg) == 0) {
        cfg->codecache = AP_LUA_CACHE_NEVER;
    }
    else if (strcasecmp("stat", arg) == 0) {
        cfg->codecache = AP_LUA_CACHE_STAT;
    }
    else if (strcasecmp("forever", arg) == 0) {
        cfg->codecache = AP_LUA_CACHE_FOREVER;
    }
    else { 
        return apr_psprintf(cmd->pool,
                            "LuaCodeCache type of '%s' not recognized, valid "
                            "options are 'never', 'stat', and 'forever'", 
                            arg);
    }
    return NULL;
}
static const char *register_lua_scope(cmd_parms *cmd, 
                                      void *_cfg,
                                      const char *scope, 
                                      const char *min,
                                      const char *max)
{
    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
    if (strcmp("once", scope) == 0) {
        cfg->vm_scope = AP_LUA_SCOPE_ONCE;
    }
    else if (strcmp("request", scope) == 0) {
        cfg->vm_scope = AP_LUA_SCOPE_REQUEST;
    }
    else if (strcmp("conn", scope) == 0) {
        cfg->vm_scope = AP_LUA_SCOPE_CONN;
    }
    else if (strcmp("thread", scope) == 0) {
#if !APR_HAS_THREADS
        return apr_psprintf(cmd->pool,
                            "Scope type of '%s' cannot be used because this "
                            "server does not have threading support "
                            "(APR_HAS_THREADS)",
                            scope);
#endif
        cfg->vm_scope = AP_LUA_SCOPE_THREAD;
    }
    else if (strcmp("server", scope) == 0) {
        unsigned int vmin, vmax;
#if !APR_HAS_THREADS
        return apr_psprintf(cmd->pool,
                            "Scope type of '%s' cannot be used because this "
                            "server does not have threading support "
                            "(APR_HAS_THREADS)",
                            scope);
#endif
        cfg->vm_scope = AP_LUA_SCOPE_SERVER;
        vmin = min ? atoi(min) : 1;
        vmax = max ? atoi(max) : 1;
        if (vmin == 0) {
            vmin = 1;
        }
        if (vmax < vmin) {
            vmax = vmin;
        }
        cfg->vm_min = vmin;
        cfg->vm_max = vmax;
    }
    else {
        return apr_psprintf(cmd->pool,
                            "Invalid value for LuaScope, '%s', acceptable "
                            "values are: 'once', 'request', 'conn'"
#if APR_HAS_THREADS
                            ", 'thread', 'server'"
#endif
                            ,scope);
    }

    return NULL;
}



static const char *register_lua_root(cmd_parms *cmd, void *_cfg,
                                     const char *root)
{
    /* ap_lua_dir_cfg* cfg = (ap_lua_dir_cfg*)_cfg; */
    ap_lua_server_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                                  &lua_module);

    cfg->root_path = root;
    return NULL;
}

const char *ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c,
                           request_rec *r, const char *var)
{
    return ap_ssl_var_lookup(p, s, c, r, var);
}

int ap_lua_ssl_is_https(conn_rec *c)
{
    return ap_ssl_conn_is_ssl(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;
    lua_authz_provider_func *func = apr_pcalloc(cmd->pool, sizeof(lua_authz_provider_func));

    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);
    func->spec = spec;

    if (require_line && *require_line) {
        const char *arg;
        func->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
        while ((arg = ap_getword_conf(cmd->pool, &require_line)) && *arg) {
            APR_ARRAY_PUSH(func->args, const char *) = arg;
        }
    }

    *parsed_require_line = func;
    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_func *prov_func = parsed_require_line;
    const lua_authz_provider_spec *prov_spec = prov_func->spec;
    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, r);
    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 entry function '%s' in %s (not a valid function)",
                      prov_spec->function_name, prov_spec->file_name);
        ap_lua_release_state(L, spec, r);
        return AUTHZ_GENERAL_ERROR;
    }
    ap_lua_run_lua_request(L, r);
    if (prov_func->args) {
        int i;
        if (!lua_checkstack(L, prov_func->args->nelts)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
                          "Error: authz provider %s: too many arguments", prov_spec->name);
            ap_lua_release_state(L, spec, r);
            return AUTHZ_GENERAL_ERROR;
        }
        for (i = 0; i < prov_func->args->nelts; i++) {
            const char *arg = APR_ARRAY_IDX(prov_func->args, i, const char *);
            lua_pushstring(L, arg);
        }
        nargs = prov_func->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);
        ap_lua_release_state(L, spec, r);
        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);
        ap_lua_release_state(L, spec, r);
        return AUTHZ_GENERAL_ERROR;
    }
    result = lua_tointeger(L, -1);
    ap_lua_release_state(L, spec, r);
    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;
}


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"),

    AP_INIT_TAKE1("LuaPackagePath", register_package_dir, NULL, OR_ALL,
                  "Add a directory to lua's package.path"),

    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_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"),

    AP_INIT_RAW_ARGS("<LuaHookTranslateName", register_translate_name_block,
                     NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the translate name phase of request processing"),

    AP_INIT_TAKE2("LuaHookFixups", register_fixups_hook, NULL, OR_ALL,
                  "Provide a hook for the fixups phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookFixups", register_fixups_block, NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a inline hook for the fixups phase of request processing"),

    /* todo: test */
    AP_INIT_TAKE2("LuaHookMapToStorage", register_map_to_storage_hook, NULL,
                  OR_ALL,
                  "Provide a hook for the map_to_storage phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookMapToStorage", register_map_to_storage_block,
                     NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the map_to_storage phase of request processing"),

    /* todo: test */
    AP_INIT_TAKE23("LuaHookCheckUserID", register_check_user_id_hook, NULL,
                  OR_ALL,
                  "Provide a hook for the check_user_id phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookCheckUserID", register_check_user_id_block,
                     NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the check_user_id phase of request processing"),

    /* todo: test */
    AP_INIT_TAKE2("LuaHookTypeChecker", register_type_checker_hook, NULL,
                  OR_ALL,
                  "Provide a hook for the type_checker phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookTypeChecker", register_type_checker_block, NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the type_checker phase of request processing"),

    /* todo: test */
    AP_INIT_TAKE23("LuaHookAccessChecker", register_access_checker_hook, NULL,
                  OR_ALL,
                  "Provide a hook for the access_checker phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookAccessChecker", register_access_checker_block,
                     NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the access_checker phase of request processing"),

    /* todo: test */
    AP_INIT_TAKE23("LuaHookAuthChecker", register_auth_checker_hook, NULL,
                  OR_ALL,
                  "Provide a hook for the auth_checker phase of request processing"),
    AP_INIT_RAW_ARGS("<LuaHookAuthChecker", register_auth_checker_block, NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the auth_checker phase of request processing"),

    /* todo: test */
    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"),

    AP_INIT_TAKE1("LuaInherit", register_lua_inherit, NULL, OR_ALL,
     "Controls how Lua scripts in parent contexts are merged with the current " 
     " context: none|parent-last|parent-first (default: parent-first) "),
    
    AP_INIT_TAKE1("LuaCodeCache", register_lua_codecache, NULL, OR_ALL,
     "Controls the behavior of the in-memory code cache " 
     " context: stat|forever|never (default: stat) "),

    AP_INIT_TAKE2("LuaQuickHandler", register_quick_hook, NULL, OR_ALL,
                  "Provide a hook for the quick handler of request processing"),
    AP_INIT_RAW_ARGS("<LuaQuickHandler", register_quick_block, NULL,
                     EXEC_ON_READ | OR_ALL,
                     "Provide a hook for the quick handler of request processing"),
    AP_INIT_RAW_ARGS("Lua_____ByteCodeHack", hack_section_handler, NULL,
                     OR_ALL,
                     "(internal) Byte code handler"),
    AP_INIT_TAKE23("LuaMapHandler", register_map_handler, NULL, OR_ALL,
                  "Maps a path to a lua handler"),
    AP_INIT_TAKE3("LuaOutputFilter", register_output_filter, NULL, OR_ALL,
                  "Registers a Lua function as an output filter"),
    AP_INIT_TAKE3("LuaInputFilter", register_input_filter, NULL, OR_ALL,
                  "Registers a Lua function as an input filter"),
    {NULL}
};


static void *create_dir_config(apr_pool_t *p, char *dir)
{
    ap_lua_dir_cfg *cfg = apr_pcalloc(p, sizeof(ap_lua_dir_cfg));
    cfg->package_paths = apr_array_make(p, 2, sizeof(char *));
    cfg->package_cpaths = apr_array_make(p, 2, sizeof(char *));
    cfg->mapped_handlers =
        apr_array_make(p, 1, sizeof(ap_lua_mapped_handler_spec *));
    cfg->mapped_filters =
        apr_array_make(p, 1, sizeof(ap_lua_filter_handler_spec *));
    cfg->pool = p;
    cfg->hooks = apr_hash_make(p);
    cfg->dir = apr_pstrdup(p, dir);
    cfg->vm_scope = AP_LUA_SCOPE_UNSET;
    cfg->codecache = AP_LUA_CACHE_UNSET;
    cfg->vm_min = 0;
    cfg->vm_max = 0;
    cfg->inherit = AP_LUA_INHERIT_UNSET;

    return cfg;
}

static int create_request_config(request_rec *r)
{
    ap_lua_request_cfg *cfg = apr_palloc(r->pool, sizeof(ap_lua_request_cfg));
    cfg->mapped_request_details = NULL;
    cfg->request_scoped_vms = apr_hash_make(r->pool);
    ap_set_module_config(r->request_config, &lua_module, cfg);
    return OK;
}

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->root_path = NULL;

    return cfg;
}

static int lua_request_hook(lua_State *L, request_rec *r)
{
    ap_lua_push_request(L, r);
    return OK;
}

static int lua_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                            apr_pool_t *ptemp)
{
    ap_mutex_register(pconf, "lua-ivm-shm", NULL, APR_LOCK_DEFAULT, 0);
    return OK;
}

static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                             apr_pool_t *ptemp, server_rec *s)
{
    apr_pool_t **pool;
    apr_status_t rs;

    if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
        return OK;

    /* Create ivm mutex */
    rs = ap_global_mutex_create(&lua_ivm_mutex, NULL, "lua-ivm-shm", NULL,
                            s, pconf, 0);
    if (APR_SUCCESS != rs) {
        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);
    }
    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 : "(anonymous)");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    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;
}
static void *overlay_hook_specs(apr_pool_t *p,
                                        const void *key,
                                        apr_ssize_t klen,
                                        const void *overlay_val,
                                        const void *base_val,
                                        const void *data)
{
    const apr_array_header_t *overlay_info = (const apr_array_header_t*)overlay_val;
    const apr_array_header_t *base_info = (const apr_array_header_t*)base_val;
    return apr_array_append(p, base_info, overlay_info);
}

static void *merge_dir_config(apr_pool_t *p, void *basev, void *overridesv)
{
    ap_lua_dir_cfg *a, *base, *overrides;

    a         = (ap_lua_dir_cfg *)apr_pcalloc(p, sizeof(ap_lua_dir_cfg));
    base      = (ap_lua_dir_cfg*)basev;
    overrides = (ap_lua_dir_cfg*)overridesv;

    a->pool = overrides->pool;
    a->dir = apr_pstrdup(p, overrides->dir);

    a->vm_scope = (overrides->vm_scope == AP_LUA_SCOPE_UNSET) ? base->vm_scope: overrides->vm_scope;
    a->inherit = (overrides->inherit == AP_LUA_INHERIT_UNSET) ? base->inherit : overrides->inherit;
    a->codecache = (overrides->codecache == AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache;
    
    a->vm_min = (overrides->vm_min == 0) ? base->vm_min : overrides->vm_min;
    a->vm_max = (overrides->vm_max == 0) ? base->vm_max : overrides->vm_max;

    if (a->inherit == AP_LUA_INHERIT_UNSET || a->inherit == AP_LUA_INHERIT_PARENT_FIRST) { 
        a->package_paths = apr_array_append(p, base->package_paths, overrides->package_paths);
        a->package_cpaths = apr_array_append(p, base->package_cpaths, overrides->package_cpaths);
        a->mapped_handlers = apr_array_append(p, base->mapped_handlers, overrides->mapped_handlers);
        a->mapped_filters = apr_array_append(p, base->mapped_filters, overrides->mapped_filters);
        a->hooks = apr_hash_merge(p, overrides->hooks, base->hooks, overlay_hook_specs, NULL);
    }
    else if (a->inherit == AP_LUA_INHERIT_PARENT_LAST) { 
        a->package_paths = apr_array_append(p, overrides->package_paths, base->package_paths);
        a->package_cpaths = apr_array_append(p, overrides->package_cpaths, base->package_cpaths);
        a->mapped_handlers = apr_array_append(p, overrides->mapped_handlers, base->mapped_handlers);
        a->mapped_filters = apr_array_append(p, overrides->mapped_filters, base->mapped_filters);
        a->hooks = apr_hash_merge(p, base->hooks, overrides->hooks, overlay_hook_specs, NULL);
    }
    else { 
        a->package_paths = overrides->package_paths;
        a->package_cpaths = overrides->package_cpaths;
        a->mapped_handlers= overrides->mapped_handlers;
        a->mapped_filters= overrides->mapped_filters;
        a->hooks= overrides->hooks;
    }

    return a;
}

static void lua_register_hooks(apr_pool_t *p)
{
    /* ap_register_output_filter("luahood", luahood, NULL, AP_FTYPE_RESOURCE); */
    ap_hook_handler(lua_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_create_request(create_request_config, NULL, NULL,
                           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,
                           APR_HOOK_MIDDLE);
    ap_hook_translate_name(lua_translate_name_harness_last, NULL, NULL,
                           AP_LUA_HOOK_LAST);

    ap_hook_fixups(lua_fixup_harness, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_map_to_storage(lua_map_to_storage_harness, NULL, NULL,
                           APR_HOOK_MIDDLE);

/*  XXX: Does not work :(  
 *  ap_hook_check_user_id(lua_check_user_id_harness_first, NULL, NULL,
                          AP_LUA_HOOK_FIRST);
 */
    ap_hook_check_user_id(lua_check_user_id_harness, NULL, NULL,
                           APR_HOOK_MIDDLE);
/*  XXX: Does not work :(
 * ap_hook_check_user_id(lua_check_user_id_harness_last, NULL, NULL,
                          AP_LUA_HOOK_LAST);
*/
    ap_hook_type_checker(lua_type_checker_harness, NULL, NULL,
                         APR_HOOK_MIDDLE);

    ap_hook_access_checker(lua_access_checker_harness_first, NULL, NULL,
                           AP_LUA_HOOK_FIRST);
    ap_hook_access_checker(lua_access_checker_harness, NULL, NULL,
                           APR_HOOK_MIDDLE);
    ap_hook_access_checker(lua_access_checker_harness_last, NULL, NULL,
                           AP_LUA_HOOK_LAST);
    ap_hook_auth_checker(lua_auth_checker_harness_first, NULL, NULL,
                         AP_LUA_HOOK_FIRST);
    ap_hook_auth_checker(lua_auth_checker_harness, NULL, NULL,
                         APR_HOOK_MIDDLE);
    ap_hook_auth_checker(lua_auth_checker_harness_last, NULL, NULL,
                         AP_LUA_HOOK_LAST);

    ap_hook_insert_filter(lua_insert_filter_harness, NULL, NULL,
                          APR_HOOK_MIDDLE);
    ap_hook_quick_handler(lua_quick_harness, NULL, NULL, APR_HOOK_FIRST);

    ap_hook_post_config(lua_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_pre_config(lua_pre_config, NULL, NULL, APR_HOOK_MIDDLE);

    APR_OPTIONAL_HOOK(ap_lua, lua_open, lua_open_hook, NULL, NULL,
                      APR_HOOK_REALLY_FIRST);

    APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL,
                      APR_HOOK_REALLY_FIRST);
    ap_hook_handler(lua_map_handler, NULL, NULL, AP_LUA_HOOK_FIRST);
    
    /* Hook this right before FallbackResource kicks in */
    ap_hook_fixups(lua_map_handler_fixups, NULL, NULL, AP_LUA_HOOK_LAST-2);
    ap_hook_child_init(ap_lua_init_mutex, NULL, NULL, APR_HOOK_MIDDLE);

    /* providers */
    lua_authz_providers = apr_hash_make(p);
    
    /* Logging catcher */
    ap_hook_log_transaction(lua_log_transaction_harness,NULL,NULL,
                            APR_HOOK_FIRST);
}

AP_DECLARE_MODULE(lua) = {
    STANDARD20_MODULE_STUFF,
    create_dir_config,          /* create per-dir    config structures */
    merge_dir_config,           /* merge  per-dir    config structures */
    create_server_config,       /* create per-server config structures */
    NULL,                       /* merge  per-server config structures */
    lua_commands,               /* table of config file commands       */
    lua_register_hooks          /* register hooks                      */
};
