]> granicus.if.org Git - apache/commitdiff
* mod_headers: Allow for format specifiers to be used in the base
authorJim Jagielski <jim@apache.org>
Sat, 9 Nov 2013 14:37:23 +0000 (14:37 +0000)
committerJim Jagielski <jim@apache.org>
Sat, 9 Nov 2013 14:37:23 +0000 (14:37 +0000)
      substitution string when using Header edit
          trunk patch: http://people.apache.org/~druggeri/patches/HeaderEditENV.trunk.patch
              2.4.x patch: http://people.apache.org/~druggeri/patches/HeaderEditENV.2.4.patch
                  +1: druggeri, covener, jim

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1540313 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 c8801cb5781a1d65894b77c06106d92976f0027e..8c3a90df62936d20ff9b92c131009e6cbc8f6dfa 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,9 @@ Changes with Apache 2.4.7
      SessionHeader directive, remove the value from the response. PR 55279.
      [Graham Leggett]
 
+  *) mod_headers: Allow for format specifiers in the substitution string
+     when using Header edit. [Daniel Ruggeri]
+
   *) mod_dav: dav_resource->uri is treated as unencoded. This was an
      unnecessary ABI changed introduced in 2.4.6. PR 55397.
 
diff --git a/STATUS b/STATUS
index cc5e3952d2fcee2a7ec6014588fb8eb67d438e26..d76da71c735a5f7f7c4927aeb734f5df0e44c216 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -97,12 +97,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  * mod_headers: Allow for format specifiers to be used in the base
-    substitution string when using Header edit
-    trunk patch: http://people.apache.org/~druggeri/patches/HeaderEditENV.trunk.patch
-    2.4.x patch: http://people.apache.org/~druggeri/patches/HeaderEditENV.2.4.patch
-    +1: druggeri, covener, jim
-
 
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
index 68ba926adda8bd71d458154901d932572298ea0c..fc8c46b00a32ab3d45f8efaeef0b6f94fab154b0 100644 (file)
@@ -229,7 +229,7 @@ Header merge Cache-Control no-store env=NO_STORE
     to a <glossary ref="regex">regular expression</glossary>
     search-and-replace.  The <var>value</var> argument is a <glossary
     ref="regex">regular expression</glossary>, and the <var>replacement</var>
-    is a replacement string, which may contain backreferences.
+    is a replacement string, which may contain backreferences or format specifiers.
     The <code>edit</code> form will match and replace exactly once
     in a header value, whereas the <code>edit*</code> form will replace
     <em>every</em> instance of the search pattern if it appears more
@@ -372,7 +372,7 @@ Header merge Cache-Control no-store env=NO_STORE
     to a <glossary ref="regex">regular expression</glossary>
     search-and-replace.  The <var>value</var> argument is a <glossary
     ref="regex">regular expression</glossary>, and the <var>replacement</var>
-    is a replacement string, which may contain backreferences.
+    is a replacement string, which may contain backreferences or format specifiers.
     The <code>edit</code> form will match and replace exactly once
     in a header value, whereas the <code>edit*</code> form will replace
     <em>every</em> instance of the search pattern if it appears more
@@ -481,7 +481,8 @@ Header merge Cache-Control no-store env=NO_STORE
 
     <p>For <code>edit</code> there is both a <var>value</var> argument
     which is a <glossary ref="regex">regular expression</glossary>,
-    and an additional <var>replacement</var> string.</p>
+    and an additional <var>replacement</var> string.</p> As of version 2.4.7
+    the replacement string may also contain format specifiers.
 
     <p>The <directive>Header</directive> directive may be followed by
     an additional argument, which may be any of:</p>
index 55cfb50a9bfac8b025b27a75ce2bf0bbeb13a566..d4e694bf71e0a60780237c0f9219aef08d0b6988 100644 (file)
@@ -143,7 +143,7 @@ typedef struct {
 
 /* edit_do is used for Header edit to iterate through the request headers */
 typedef struct {
-    apr_pool_t *p;
+    request_rec *r;
     header_entry *hdr;
     apr_table_t *t;
 } edit_do;
@@ -392,12 +392,13 @@ static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s
     char *res;
 
     /* No string to parse with unset and echo commands */
-    if (hdr->action == hdr_unset ||
-        hdr->action == hdr_edit ||
-        hdr->action == hdr_edit_r ||
-        hdr->action == hdr_echo) {
+    if (hdr->action == hdr_unset || hdr->action == hdr_echo) {
         return NULL;
     }
+    /* Tags are in the replacement value for edit */
+    else if (hdr->action == hdr_edit || hdr->action == hdr_edit_r ) {
+        s = hdr->subs;
+    }
 
     hdr->ta = apr_array_make(p, 10, sizeof(format_tag));
 
@@ -602,7 +603,7 @@ static char* process_tags(header_entry *hdr, request_rec *r)
     return str ? str : "";
 }
 static const char *process_regexp(header_entry *hdr, const char *value,
-                                  apr_pool_t *pool)
+                                  request_rec *r)
 {
     ap_regmatch_t pmatch[AP_MAX_REG_MATCH];
     const char *subs;
@@ -613,7 +614,10 @@ static const char *process_regexp(header_entry *hdr, const char *value,
         /* no match, nothing to do */
         return value;
     }
-    subs = ap_pregsub(pool, hdr->subs, value, AP_MAX_REG_MATCH, pmatch);
+    /* Process tags in the input string rather than the resulting
+       * substitution to avoid surprises
+       */
+    subs = ap_pregsub(r->pool, process_tags(hdr, r), value, AP_MAX_REG_MATCH, pmatch);
     if (subs == NULL)
         return NULL;
     diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
@@ -621,12 +625,12 @@ static const char *process_regexp(header_entry *hdr, const char *value,
         remainder = value + pmatch[0].rm_eo;
     }
     else { /* recurse to edit multiple matches if applicable */
-        remainder = process_regexp(hdr, value + pmatch[0].rm_eo, pool);
+        remainder = process_regexp(hdr, value + pmatch[0].rm_eo, r);
         if (remainder == NULL)
             return NULL;
         diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
     }
-    ret = apr_palloc(pool, strlen(value) + 1 + diffsz);
+    ret = apr_palloc(r->pool, strlen(value) + 1 + diffsz);
     memcpy(ret, value, pmatch[0].rm_so);
     strcpy(ret + pmatch[0].rm_so, subs);
     strcat(ret, remainder);
@@ -648,7 +652,7 @@ static int echo_header(echo_do *v, const char *key, const char *val)
 static int edit_header(void *v, const char *key, const char *val)
 {
     edit_do *ed = (edit_do *)v;
-    const char *repl = process_regexp(ed->hdr, val, ed->p);
+    const char *repl = process_regexp(ed->hdr, val, ed->r);
     if (repl == NULL)
         return 0;
 
@@ -781,7 +785,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
         case hdr_edit:
         case hdr_edit_r:
             if (!strcasecmp(hdr->header, "Content-Type") && r->content_type) {
-                const char *repl = process_regexp(hdr, r->content_type, r->pool);
+                const char *repl = process_regexp(hdr, r->content_type, r);
                 if (repl == NULL)
                     return 0;
                 ap_set_content_type(r, repl);
@@ -789,7 +793,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
             if (apr_table_get(headers, hdr->header)) {
                 edit_do ed;
 
-                ed.p = r->pool;
+                ed.r = r;
                 ed.hdr = hdr;
                 ed.t = apr_table_make(r->pool, 5);
                 if (!apr_table_do(edit_header, (void *) &ed, headers,