From c0ecaab949c571938b96242aacb7adbe6ce72515 Mon Sep 17 00:00:00 2001
From: Jim Jagielski
Date: Thu, 17 Apr 2014 13:36:05 +0000
Subject: [PATCH] Merge r1546801 from trunk:
If the "value" argument is prefixed with expr=, parse it with ap_expr
rather than mod_headers' built-in format strings.
Submitted by: covener
Reviewed/backported by: jim
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1588244 13f79535-47bb-0310-9956-ffa450edef68
---
CHANGES | 3 +++
STATUS | 5 -----
docs/manual/mod/mod_headers.xml | 11 +++++++----
modules/metadata/mod_headers.c | 35 ++++++++++++++++++++++++++++++---
4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/CHANGES b/CHANGES
index 61beda093a..7556548828 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
Changes with Apache 2.4.10
+ *) mod_headers: Allow the "value" parameter of Header and RequestHeader to
+ contain an ap_expr expression if prefixed with "expr=". [Eric Covener]
+
*) rotatelogs: Avoid creation of zombie processes when -p is used on
Unix platforms. [Joe Orton]
diff --git a/STATUS b/STATUS
index b3c7e2789c..d14575afa2 100644
--- a/STATUS
+++ b/STATUS
@@ -117,11 +117,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2.4.x patch: trunk patch works (modulo CHANGES)
+1: kbrand, ylavic, jorton
- * mod_headers: allow expr= in the value argument of Header/RequestHeader
- trunk patch: http://svn.apache.org/r1546801
- 2.4.x patch: trunk works
- +1 covener, gsmith, ylavic
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
diff --git a/docs/manual/mod/mod_headers.xml b/docs/manual/mod/mod_headers.xml
index a51916b8e1..8cdce9452e 100644
--- a/docs/manual/mod/mod_headers.xml
+++ b/docs/manual/mod/mod_headers.xml
@@ -310,7 +310,7 @@ Header merge Cache-Control no-store env=NO_STORE
Header
Configure HTTP response headers
Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note
-header [value] [replacement]
+header [[expr=]value]] [replacement]
[early|env=[!]variable]|expr=expression]
server configvirtual host
@@ -437,9 +437,12 @@ SetIfEmpty and note available in 2.4.7 and later.
add
a value is specified as the next argument.
If value
contains spaces, it should be surrounded by double quotes.
- value may be a character string, a string containing format
- specifiers or a combination of both. The following format specifiers
- are supported in value:
+ value may be a character string, a string containing
+ mod_headers specific format specifiers (and character
+ literals), or an ap_expr expression prefixed
+ with expr=
+
+ The following format specifiers are supported in value:
diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c
index d4e694bf71..4608da7efe 100644
--- a/modules/metadata/mod_headers.c
+++ b/modules/metadata/mod_headers.c
@@ -133,6 +133,7 @@ typedef struct {
const char *condition_var;
const char *subs;
ap_expr_info_t *expr;
+ ap_expr_info_t *expr_out;
} header_entry;
/* echo_do is used for Header echo to iterate through the request headers*/
@@ -387,8 +388,9 @@ static char *parse_format_tag(apr_pool_t *p, format_tag *tag, const char **sa)
* contains a pointer to the function used to format the tag. Then save each
* tag in the tag array anchored in the header_entry.
*/
-static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s)
+static char *parse_format_string(cmd_parms *cmd, header_entry *hdr, const char *s)
{
+ apr_pool_t *p = cmd->pool;
char *res;
/* No string to parse with unset and echo commands */
@@ -400,6 +402,18 @@ static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s
s = hdr->subs;
}
+ if (!strncmp(s, "expr=", 5)) {
+ const char *err;
+ hdr->expr_out = ap_expr_parse_cmd(cmd, s+5,
+ AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_pstrcat(cmd->pool,
+ "Can't parse value expression : ", err, NULL);
+ }
+ return NULL;
+ }
+
hdr->ta = apr_array_make(p, 10, sizeof(format_tag));
while (*s) {
@@ -542,7 +556,7 @@ static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd,
new->condition_var = condition_var;
new->expr = expr;
- return parse_format_string(cmd->pool, new, value);
+ return parse_format_string(cmd, new, value);
}
/* Handle all (xxx)Header directives */
@@ -584,14 +598,29 @@ static const char *header_cmd(cmd_parms *cmd, void *indirconf,
* (formatter) specific to the tag. Handlers return text strings.
* Concatenate the return from each handler into one string that is
* returned from this call.
+ * If the original value was prefixed with "expr=", processing is
+ * handled instead by ap_expr.
*/
static char* process_tags(header_entry *hdr, request_rec *r)
{
int i;
const char *s;
char *str = NULL;
+ format_tag *tag = NULL;
+
+ if (hdr->expr_out) {
+ const char *err;
+ const char *val;
+ val = ap_expr_str_exec(r, hdr->expr_out, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02557)
+ "Can't evaluate value expression: %s", err);
+ return "";
+ }
+ return apr_pstrdup(r->pool, val);
+ }
- format_tag *tag = (format_tag*) hdr->ta->elts;
+ tag = (format_tag*) hdr->ta->elts;
for (i = 0; i < hdr->ta->nelts; i++) {
s = tag[i].func(r, tag[i].arg);
--
2.40.0