From 1837ae341b5916b01932a84a9b641a5c00c96b15 Mon Sep 17 00:00:00 2001 From: Ken Coar Date: Tue, 6 Jun 2000 20:41:45 +0000 Subject: [PATCH] Bring forward a change from 1.3 (the ability to use SetEnvIf* and BrowserMatch* in .htaccess files). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85447 13f79535-47bb-0310-9956-ffa450edef68 --- modules/metadata/mod_setenvif.c | 82 +++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/modules/metadata/mod_setenvif.c b/modules/metadata/mod_setenvif.c index 13a63170cf..dec50c9e6d 100644 --- a/modules/metadata/mod_setenvif.c +++ b/modules/metadata/mod_setenvif.c @@ -148,7 +148,16 @@ typedef struct { module MODULE_VAR_EXPORT setenvif_module; -static void *create_setenvif_config(ap_pool_t *p, server_rec *dummy) +/* + * These routines, the create- and merge-config functions, are called + * for both the server-wide and the per-directory contexts. This is + * because the different definitions are used at different times; the + * server-wide ones are used in the post-read-request phase, and the + * per-directory ones are used during the header-parse phase (after + * the URI has been mapped to a file and we have anything from the + * .htaccess file and and containers). + */ +static void *create_setenvif_config(ap_pool_t *p) { sei_cfg_rec *new = (sei_cfg_rec *) ap_palloc(p, sizeof(sei_cfg_rec)); @@ -156,6 +165,16 @@ static void *create_setenvif_config(ap_pool_t *p, server_rec *dummy) return (void *) new; } +static void *create_setenvif_config_svr(ap_pool_t *p, server_rec *dummy) +{ + return create_setenvif_config(p); +} + +static void *create_setenvif_config_dir(ap_pool_t *p, char *dummy) +{ + return create_setenvif_config(p); +} + static void *merge_setenvif_config(ap_pool_t *p, void *basev, void *overridesv) { sei_cfg_rec *a = ap_pcalloc(p, sizeof(sei_cfg_rec)); @@ -166,24 +185,36 @@ static void *merge_setenvif_config(ap_pool_t *p, void *basev, void *overridesv) return a; } -/* any non-NULL magic constant will do... used to indicate if REG_ICASE should +/* + * any non-NULL magic constant will do... used to indicate if REG_ICASE should * be used */ #define ICASE_MAGIC ((void *)(&setenvif_module)) +#define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag" static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, char *fname, const char *args) { char *regex; const char *feature; - sei_cfg_rec *sconf = ap_get_module_config(cmd->server->module_config, - &setenvif_module); - sei_entry *new, *entries = (sei_entry *) sconf->conditionals->elts; + sei_cfg_rec *sconf; + sei_entry *new; + sei_entry *entries; char *var; int i; int beenhere = 0; unsigned icase; + /* + * Determine from our context into which record to put the entry. + * cmd->path == NULL means we're in server-wide context; otherwise, + * we're dealing with a per-directory setting. + */ + sconf = (cmd->path != NULL) + ? (sei_cfg_rec *) mconfig + : (sei_cfg_rec *) ap_get_module_config(cmd->server->module_config, + &setenvif_module); + entries = (sei_entry *) sconf->conditionals->elts; /* get regex */ regex = ap_getword_conf(cmd->pool, &args); if (!*regex) { @@ -205,7 +236,7 @@ static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, } } - /* if the last entry has an idential headername and regex then + /* if the last entry has an identical headername and regex then * merge with it */ i = sconf->conditionals->nelts - 1; @@ -310,19 +341,27 @@ static const char *add_browser(cmd_parms *cmd, void *mconfig, const char *args) static const command_rec setenvif_module_cmds[] = { { "SetEnvIf", add_setenvif, NULL, - RSRC_CONF, RAW_ARGS, "A header-name, regex and a list of variables." }, + OR_FILEINFO, RAW_ARGS, "A header-name, regex and a list of variables." }, { "SetEnvIfNoCase", add_setenvif, ICASE_MAGIC, - RSRC_CONF, RAW_ARGS, "a header-name, regex and a list of variables." }, + OR_FILEINFO, RAW_ARGS, "a header-name, regex and a list of variables." }, { "BrowserMatch", add_browser, NULL, - RSRC_CONF, RAW_ARGS, "A browser regex and a list of variables." }, + OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." }, { "BrowserMatchNoCase", add_browser, ICASE_MAGIC, - RSRC_CONF, RAW_ARGS, "A browser regex and a list of variables." }, + OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." }, { NULL }, }; +/* + * This routine gets called at two different points in request processing: + * once before the URI has been translated (during the post-read-request + * phase) and once after (during the header-parse phase). We use different + * config records for the two different calls to reduce overhead (by not + * re-doing the server-wide settings during directory processing), and + * signal which call it is by having the earlier one pass a flag to the + * later one. + */ static int match_headers(request_rec *r) { - server_rec *s = r->server; sei_cfg_rec *sconf; sei_entry *entries; ap_table_entry_t *elts; @@ -330,8 +369,15 @@ static int match_headers(request_rec *r) int i, j; char *last_name; - sconf = (sei_cfg_rec *) ap_get_module_config(s->module_config, - &setenvif_module); + if (ap_table_get(r->notes, SEI_MAGIC_HEIRLOOM) == NULL) { + ap_table_set(r->notes, SEI_MAGIC_HEIRLOOM, "post-read done"); + sconf = (sei_cfg_rec *) ap_get_module_config(r->server->module_config, + &setenvif_module); + } + else { + sconf = (sei_cfg_rec *) ap_get_module_config(r->per_dir_config, + &setenvif_module); + } entries = (sei_entry *) sconf->conditionals->elts; last_name = NULL; val = NULL; @@ -404,18 +450,18 @@ static int match_headers(request_rec *r) static void register_hooks(void) { - ap_hook_post_read_request(match_headers,NULL,NULL,AP_HOOK_MIDDLE); + ap_hook_header_parser(match_headers, NULL, NULL, AP_HOOK_MIDDLE); + ap_hook_post_read_request(match_headers, NULL, NULL, AP_HOOK_MIDDLE); } module MODULE_VAR_EXPORT setenvif_module = { STANDARD20_MODULE_STUFF, - NULL, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_setenvif_config, /* server config */ + create_setenvif_config_dir, /* dir config creater */ + merge_setenvif_config, /* dir merger --- default is to override */ + create_setenvif_config_svr, /* server config */ merge_setenvif_config, /* merge server configs */ setenvif_module_cmds, /* command ap_table_t */ NULL, /* handlers */ register_hooks /* register hooks */ }; - -- 2.50.1