From: Eric Covener
Date: Tue, 14 Jan 2020 23:25:24 +0000 (+0000)
Subject: mod_setenvif: add "early mode"
X-Git-Tag: 2.5.0-alpha2-ci-test-only~1697
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b26066da4c5f264969f053bfac0a391c11766e4;p=thirdparty%2Fapache%2Fhttpd.git
mod_setenvif: add "early mode"
Primarily to run before `RequestHeader ... ... early`
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1872797 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index e0893a94c0f..acee6957354 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.1
+ *) mod_setenvif: Passing an env-variable parameter of "--early" in non-perdir
+ context runs directives from this module before `RequestHeader ... early`
+ are evaluated. This allows results of SetEnvIf conditionals to be used
+ to modify request headers in early mode. [Eric Covener]
+
*) config: Speed up graceful restarts by using pre-hashed command table. PR 64066.
[Giovanni Bechis , Jim Jagielski]
diff --git a/docs/manual/mod/mod_setenvif.xml b/docs/manual/mod/mod_setenvif.xml
index 626c4cfc3d9..4024c9ec786 100644
--- a/docs/manual/mod/mod_setenvif.xml
+++ b/docs/manual/mod/mod_setenvif.xml
@@ -223,6 +223,13 @@ of
of regex. $0 provides access to the whole
string matched by that pattern.
+ If the special value --early is specified, and this
+ directive is not in directory context, the directive will be evaluated
+ earlier during request processing. This allows the output variables
+ set by this directive to be used as input to the "early mode" option of
+ the RequestHeader directive.
+ Available in 2.5.1 and later.
+
SetEnvIf Request_URI "\.gif$" object_is_image=gif
SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
diff --git a/modules/metadata/mod_setenvif.c b/modules/metadata/mod_setenvif.c
index 23d60cdba5a..97e6106d966 100644
--- a/modules/metadata/mod_setenvif.c
+++ b/modules/metadata/mod_setenvif.c
@@ -113,13 +113,20 @@ typedef struct {
apr_table_t *features; /* env vars to set (or unset) */
enum special special_type; /* is it a "special" header ? */
int icase; /* ignoring case? */
+ int early;
} sei_entry;
typedef struct {
apr_array_header_t *conditionals;
} sei_cfg_rec;
+
+typedef struct {
+ int pass;
+} sei_request_config;
+
module AP_MODULE_DECLARE_DATA setenvif_module;
+static int has_early; /* at least 1 server-scoped SEI needs to be run early */
/*
* These routines, the create- and merge-config functions, are called
@@ -163,7 +170,6 @@ static void *merge_setenvif_config(apr_pool_t *p, void *basev, void *overridesv)
* be used
*/
#define ICASE_MAGIC ((void *)(&setenvif_module))
-#define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag"
static ap_regex_t *is_header_regex_regex;
@@ -267,7 +273,13 @@ static const char *add_envvars(cmd_parms *cmd, const char *args, sei_entry *new)
apr_table_setn(new->features, var + 1, "!");
}
else {
- apr_table_setn(new->features, var, "1");
+ if (strcmp(var, "--early") == 0 && cmd->path == NULL) {
+ new->early = 1;
+ has_early = 1;
+ }
+ else {
+ apr_table_setn(new->features, var, "1");
+ }
}
}
@@ -332,6 +344,7 @@ static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig,
/* no match, create a new entry */
new = apr_array_push(sconf->conditionals);
+ new->early = 0;
new->name = fname;
new->regex = regex;
new->icase = icase;
@@ -479,6 +492,7 @@ static const command_rec setenvif_module_cmds[] =
{ NULL },
};
+
/*
* This routine gets called at two different points in request processing:
* once before the URI has been translated (during the post-read-request
@@ -491,6 +505,7 @@ static const command_rec setenvif_module_cmds[] =
static int match_headers(request_rec *r)
{
sei_cfg_rec *sconf;
+ sei_request_config *rconf;
sei_entry *entries;
const apr_table_entry_t *elts;
const char *val, *err;
@@ -498,12 +513,24 @@ static int match_headers(request_rec *r)
int i, j;
char *last_name;
ap_regmatch_t regm[AP_MAX_REG_MATCH];
+ int do_early = 0;
+
+ rconf = ap_get_module_config(r->request_config, &setenvif_module);
- if (!ap_get_module_config(r->request_config, &setenvif_module)) {
- ap_set_module_config(r->request_config, &setenvif_module,
- SEI_MAGIC_HEIRLOOM);
+ if (!rconf) {
+ sconf = (sei_cfg_rec *) ap_get_module_config(r->server->module_config,
+ &setenvif_module);
+ rconf = (sei_request_config*) apr_pcalloc(r->pool, sizeof(*rconf));
+ ap_set_module_config(r->request_config, &setenvif_module, rconf);
+ if (!has_early){
+ return DECLINED;
+ }
+ do_early = 1;
+ }
+ else if (rconf->pass == 0) {
sconf = (sei_cfg_rec *) ap_get_module_config(r->server->module_config,
&setenvif_module);
+ rconf->pass++;
}
else {
sconf = (sei_cfg_rec *) ap_get_module_config(r->per_dir_config,
@@ -514,6 +541,9 @@ static int match_headers(request_rec *r)
val = NULL;
for (i = 0; i < sconf->conditionals->nelts; ++i) {
sei_entry *b = &entries[i];
+ if (b->early && !do_early) {
+ continue;
+ }
if (!b->expr) {
/* Optimize the case where a bunch of directives in a row use the
@@ -636,10 +666,18 @@ static int match_headers(request_rec *r)
return DECLINED;
}
+static int sei_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
+{
+ has_early = 0;
+ return OK;
+}
+
static void register_hooks(apr_pool_t *p)
{
ap_hook_header_parser(match_headers, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_REALLY_FIRST);
+ ap_hook_pre_config(sei_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
is_header_regex_regex = ap_pregcomp(p, "^[-A-Za-z0-9_]*$",
(AP_REG_EXTENDED | AP_REG_NOSUB ));