From b53e38b314ee235c223227ce83ed78b6fb014b90 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Sun, 13 Nov 2011 15:48:06 +0000 Subject: [PATCH] add per-dir config merging to mod_lua so LuaHook* in multiple per-dir sections behaves as expected instead of discarding previous sections. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1201443 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++ docs/manual/mod/mod_lua.html.en | 21 ++++++++ docs/manual/mod/mod_lua.xml | 20 +++++++ modules/lua/lua_vmprep.h | 1 + modules/lua/mod_lua.c | 92 +++++++++++++++++++++++++++++++-- modules/lua/mod_lua.h | 10 ++++ 6 files changed, 143 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index b611a77d66..5c395c37f4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.3.16 + *) mod_lua: Stop losing track of all but the most specific LuaHook* directives + when multiple per-directory config sections are used. Adds LuaInherit + directive to control how parent sections are merged. [Eric Covener] + *) mod_cache: Make sure we merge headers correctly when we handle a non cacheable conditional response. PR52120. [Graham Leggett] diff --git a/docs/manual/mod/mod_lua.html.en b/docs/manual/mod/mod_lua.html.en index 04b59d987b..43a2553ae8 100644 --- a/docs/manual/mod/mod_lua.html.en +++ b/docs/manual/mod/mod_lua.html.en @@ -57,6 +57,7 @@ at any time.
  • LuaHookMapToStorage
  • LuaHookTranslateName
  • LuaHookTypeChecker
  • +
  • LuaInherit
  • LuaMapHandler
  • LuaPackageCPath
  • LuaPackagePath
  • @@ -630,6 +631,26 @@ end

    ...

    top
    +

    LuaInherit Directive

    + + + + + + + + + +
    Description:Controls how parent configuration sections are merged into children
    Syntax:LuaInherit none|parent-first|parent-last
    Default:LuaInherit parent-first
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Experimental
    Module:mod_lua
    Compatibility:2.5.0 and later

    By default, if LuaHook* directives are used in overlapping + Directory or Location configuration sections, the scripts defined in the + more specific section are run after those defined in the more + generic section (LuaInherit parent-first). You can reverse this order, or + make the parent context not apply at all.

    + +

    In previous 2.3.x releases, the default was effectively to ignore LuaHook* + directives from parent configuration sections.

    +
    +
    top

    LuaMapHandler Directive

    diff --git a/docs/manual/mod/mod_lua.xml b/docs/manual/mod/mod_lua.xml index f28f7300da..7c46463e36 100644 --- a/docs/manual/mod/mod_lua.xml +++ b/docs/manual/mod/mod_lua.xml @@ -725,6 +725,26 @@ hook function usually returns OK, DECLINED, or HTTP_FORBIDDEN.

    Not Yet Implemented

    + +LuaInherit +Controls how parent configuration sections are merged into children +LuaInherit none|parent-first|parent-last +LuaInherit parent-first +2.5.0 and later +server configvirtual host +directory.htaccess + +All +

    By default, if LuaHook* directives are used in overlapping + Directory or Location configuration sections, the scripts defined in the + more specific section are run after those defined in the more + generic section (LuaInherit parent-first). You can reverse this order, or + make the parent context not apply at all.

    + +

    In previous 2.3.x releases, the default was effectively to ignore LuaHook* + directives from parent configuration sections.

    +
    + LuaQuickHandler Provide a hook for the quick handler of request processing diff --git a/modules/lua/lua_vmprep.h b/modules/lua/lua_vmprep.h index ed9c65ef28..be1750df7c 100644 --- a/modules/lua/lua_vmprep.h +++ b/modules/lua/lua_vmprep.h @@ -34,6 +34,7 @@ #ifndef VMPREP_H #define VMPREP_H +#define AP_LUA_SCOPE_UNSET 0 #define AP_LUA_SCOPE_ONCE 1 #define AP_LUA_SCOPE_REQUEST 2 #define AP_LUA_SCOPE_CONN 3 diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c index a248e95d7d..53dbdab1b6 100644 --- a/modules/lua/mod_lua.c +++ b/modules/lua/mod_lua.c @@ -115,8 +115,9 @@ static int lua_handler(request_rec *r) spec->file, "handle"); - switch (dcfg->vm_scope) { + 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: @@ -190,7 +191,7 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec)); spec->file = hook_spec->file_name; - spec->scope = hook_spec->scope; + spec->scope = cfg->vm_scope; spec->bytecode = hook_spec->bytecode; spec->bytecode_len = hook_spec->bytecode_len; spec->pool = r->pool; @@ -210,6 +211,7 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap 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: @@ -864,7 +866,29 @@ static const char *register_package_cdir(cmd_parms *cmd, 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_scope(cmd_parms *cmd, void *_cfg, const char *scope, @@ -900,6 +924,7 @@ static const char *register_lua_scope(cmd_parms *cmd, #endif ,scope); } + return NULL; } @@ -1008,6 +1033,10 @@ command_rec lua_commands[] = { 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_TAKE2("LuaQuickHandler", register_quick_hook, NULL, OR_ALL, "Provide a hook for the quick handler of request processing"), AP_INIT_RAW_ARGS("pool = p; cfg->hooks = apr_hash_make(p); cfg->dir = apr_pstrdup(p, dir); - cfg->vm_scope = AP_LUA_SCOPE_ONCE; + cfg->vm_scope = AP_LUA_SCOPE_UNSET; + return cfg; } @@ -1067,6 +1097,58 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog, lua_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https); 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; + apr_array_header_t *newspecs = apr_array_make(p, 2, + sizeof(ap_lua_mapped_handler_spec *)); + + newspecs = apr_array_append(p, base_info, overlay_info); + return newspecs; +} + +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; + + 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->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->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->package_cpaths = overrides->package_cpaths; + a->mapped_handlers= overrides->mapped_handlers; + a->hooks= overrides->hooks; + } + + return a; +} static void lua_register_hooks(apr_pool_t *p) { @@ -1126,7 +1208,7 @@ static void lua_register_hooks(apr_pool_t *p) AP_DECLARE_MODULE(lua) = { STANDARD20_MODULE_STUFF, create_dir_config, /* create per-dir config structures */ - NULL, /* merge 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 */ diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h index 82a0e4ffcb..16627240eb 100644 --- a/modules/lua/mod_lua.h +++ b/modules/lua/mod_lua.h @@ -69,6 +69,12 @@ #include "lua_request.h" #include "lua_vmprep.h" +typedef enum { + AP_LUA_INHERIT_UNSET = -1, + AP_LUA_INHERIT_NONE = 0, + AP_LUA_INHERIT_PARENT_FIRST = 1, + AP_LUA_INHERIT_PARENT_LAST = 2, +} ap_lua_inherit_t; /** * make a userdata out of a C pointer, and vice versa @@ -103,6 +109,10 @@ typedef struct /* the actual directory being configured */ char *dir; + + /* Whether Lua scripts in a sub-dir are run before parents */ + ap_lua_inherit_t inherit; + } ap_lua_dir_cfg; typedef struct -- 2.40.0
    Description:Map a path to a lua handler