You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@apache.org on 2013/12/01 12:23:23 UTC

svn commit: r1546801 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_headers.xml modules/metadata/mod_headers.c

Author: covener
Date: Sun Dec  1 11:23:22 2013
New Revision: 1546801

URL: http://svn.apache.org/r1546801
Log:
If the "value" argument is prefixed with expr=, parse it with ap_expr
rather than mod_headers' built-in format strings.


Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_headers.xml
    httpd/httpd/trunk/modules/metadata/mod_headers.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1546801&r1=1546800&r2=1546801&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sun Dec  1 11:23:22 2013
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_headers: Allow the "value" parameter of Header and RequestHeader to 
+     contain an ap_expr expression if prefixed with "expr=". [Eric Covener]
+
   *) Add suspend_connection and resume_connection hooks to notify modules
      when the thread/connection relationship changes.  (Currently implemented
      only for the Event MPM; should be implemented for all async MPMs.)

Modified: httpd/httpd/trunk/docs/manual/mod/mod_headers.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_headers.xml?rev=1546801&r1=1546800&r2=1546801&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_headers.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_headers.xml Sun Dec  1 11:23:22 2013
@@ -301,13 +301,12 @@ Header merge Cache-Control no-store env=
 <name>Header</name>
 <description>Configure HTTP response headers</description>
 <syntax>Header [<var>condition</var>] add|append|echo|edit|edit*|merge|set|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>
 <context>directory</context><context>.htaccess</context></contextlist>
 <override>FileInfo</override>
-<compatibility>Default condition was temporarily changed to "always" in 2.3.9 and 2.3.10</compatibility>
 
 <usage>
     <p>This directive can replace, merge or remove HTTP response
@@ -421,9 +420,12 @@ Header merge Cache-Control no-store env=
     <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>

Modified: httpd/httpd/trunk/modules/metadata/mod_headers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_headers.c?rev=1546801&r1=1546800&r2=1546801&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/metadata/mod_headers.c (original)
+++ httpd/httpd/trunk/modules/metadata/mod_headers.c Sun Dec  1 11:23:22 2013
@@ -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
  * 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_poo
         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_ino
     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 
  * (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);