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