]> granicus.if.org Git - apache/commitdiff
Merge r1546801 from trunk:
authorJim Jagielski <jim@apache.org>
Thu, 17 Apr 2014 13:36:05 +0000 (13:36 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 17 Apr 2014 13:36:05 +0000 (13:36 +0000)
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
STATUS
docs/manual/mod/mod_headers.xml
modules/metadata/mod_headers.c

diff --git a/CHANGES b/CHANGES
index 61beda093aea2c7504e376f32ded8372261210ac..755654882850248095d27f6e1dd7c551d06a88fe 100644 (file)
--- 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 b3c7e2789c955173d99e5645df3b81dce7621522..d14575afa2fbcc7cc4b7d8552908961648c21470 100644 (file)
--- 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 ]
 
index a51916b8e1d42cee7d641f17e4f650ba0fc9c78e..8cdce9452e23f0dd28af9acd12eb7a8454e72da2 100644 (file)
@@ -310,7 +310,7 @@ Header merge Cache-Control no-store env=NO_STORE
 <name>Header</name>
 <description>Configure HTTP response headers</description>
 <syntax>Header [<var>condition</var>] add|append|echo|edit|edit*|merge|set|setifempty|unset|note
-<var>header</var> [<var>value</var>] [<var>replacement</var>]
+<var>header</var> [<var>[expr=]value]</var>] [<var>replacement</var>]
 [early|env=[!]<var>variable</var>]|expr=<var>expression</var>]
 </syntax>
 <contextlist><context>server config</context><context>virtual host</context>
@@ -437,9 +437,12 @@ SetIfEmpty and note available in 2.4.7 and later.</compatibility>
     <code>add</code> a <var>value</var> is specified as the next argument.
     If <var>value</var>
     contains spaces, it should be surrounded by double quotes.
-    <var>value</var> may be a character string, a string containing format
-    specifiers or a combination of both. The following format specifiers
-    are supported in <var>value</var>:</p>
+    <var>value</var> may be a character string, a string containing 
+    <module>mod_headers</module> specific format specifiers (and character 
+    literals), or an <a href="../expr.html">ap_expr</a> expression prefixed
+    with <em>expr=</em></p>
+    
+    <p> The following format specifiers are supported in <var>value</var>:</p>
 
     <table border="1" style="zebra">
     <columnspec><column width=".25"/><column width=".75"/></columnspec>
index d4e694bf71e0a60780237c0f9219aef08d0b6988..4608da7efebe2a753b9aeaacb0d070db8fa5029c 100644 (file)
@@ -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);