You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ruediger Pluem <rp...@apache.org> on 2009/12/27 10:49:17 UTC

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

On 27.12.2009 01:05, niq@apache.org wrote:
> Author: niq
> Date: Sun Dec 27 00:05:12 2009
> New Revision: 894036
> 
> URL: http://svn.apache.org/viewvc?rev=894036&view=rev
> Log:
> mod_headers: Enable multi-match-and-replace edit option
> PR 47066
> 
> 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=894036&r1=894035&r2=894036&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/CHANGES [utf-8] (original)
> +++ httpd/httpd/trunk/CHANGES [utf-8] Sun Dec 27 00:05:12 2009
> @@ -36,6 +36,9 @@
>    *) mod_headers: align Header Edit with Header Set when used on Content-Type
>       PR 48422 [Cyril Bonté <cyril.bonte free.fr>, Nick Kew>]
>  
> +  *) mod_headers: Enable multi-match-and-replace edit option
> +     PR 47066 [Nick Kew]
> +
>  Changes with Apache 2.3.4
>  
>    *) Replace AcceptMutex, LockFile, RewriteLock, SSLMutex, SSLStaplingMutex,
> 
> 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=894036&r1=894035&r2=894036&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/docs/manual/mod/mod_headers.xml (original)
> +++ httpd/httpd/trunk/docs/manual/mod/mod_headers.xml Sun Dec 27 00:05:12 2009
> @@ -193,7 +193,7 @@
>  <directivesynopsis>
>  <name>RequestHeader</name>
>  <description>Configure HTTP request headers</description>
> -<syntax>RequestHeader add|append|edit|merge|set|unset <var>header</var>
> +<syntax>RequestHeader add|append|edit|edit*|merge|set|unset <var>header</var>
>  [<var>value</var>] [<var>replacement</var>] [early|env=[!]<var>variable</var>]</syntax>
>  <contextlist><context>server config</context><context>virtual host</context>
>  <context>directory</context><context>.htaccess</context></contextlist>
> @@ -223,11 +223,16 @@
>      values.</dd>
>  
>      <dt><code>edit</code></dt>
> +    <dt><code>edit*</code></dt>
>      <dd>If this request header exists, its value is transformed according
>      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.</dd>
> +    is a replacement string, which may contain backreferences.
> +    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
> +    than once.</dd>
>  
>      <dt><code>merge</code></dt>
>      <dd>The response header is appended to any existing header of
> 
> Modified: httpd/httpd/trunk/modules/metadata/mod_headers.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_headers.c?rev=894036&r1=894035&r2=894036&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/metadata/mod_headers.c (original)
> +++ httpd/httpd/trunk/modules/metadata/mod_headers.c Sun Dec 27 00:05:12 2009
> @@ -95,7 +95,8 @@
>      hdr_merge = 'g',            /* merge (merge, but avoid duplicates) */
>      hdr_unset = 'u',            /* unset header */
>      hdr_echo = 'e',             /* echo headers from request to response */
> -    hdr_edit = 'r'              /* change value by regexp */
> +    hdr_edit = 'r',             /* change value by regexp, match once */
> +    hdr_edit_r = 'R'            /* change value by regexp, everymatch */
>  } hdr_actions;
>  
>  /*
> @@ -366,6 +367,7 @@
>      /* 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) {
>          return NULL;
>      }
> @@ -416,11 +418,13 @@
>          new->action = hdr_echo;
>      else if (!strcasecmp(action, "edit"))
>          new->action = hdr_edit;
> +    else if (!strcasecmp(action, "edit*"))
> +        new->action = hdr_edit_r;
>      else
>          return "first argument must be 'add', 'set', 'append', 'merge', "
> -               "'unset', 'echo', or 'edit'.";
> +               "'unset', 'echo', 'edit', or 'edit*'.";
>  
> -    if (new->action == hdr_edit) {
> +    if (new->action == hdr_edit || new->action == hdr_edit_r) {
>          if (subs == NULL) {
>              return "Header edit requires a match and a substitution";
>          }
> @@ -566,6 +570,7 @@
>      unsigned int nmatch = 10;
>      ap_regmatch_t pmatch[10];
>      const char *subs;
> +    const char *remainder;
>      char *ret;
>      int diffsz;
>      if (ap_regexec(hdr->regex, value, nmatch, pmatch, 0)) {
> @@ -574,6 +579,13 @@
>      }
>      subs = ap_pregsub(pool, hdr->subs, value, nmatch, pmatch);
>      diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
> +    if (hdr->action == hdr_edit) {
> +        remainder = value + pmatch[0].rm_eo;
> +    }
> +    else { /* recurse to edit multiple matches if applicable */
> +        remainder = process_regexp(hdr, value + pmatch[0].rm_eo, pool);
> +        diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
> +    }

Hm. Shouldn't we use remainder in the later code?

>      ret = apr_palloc(pool, strlen(value) + 1 + diffsz);
>      memcpy(ret, value, pmatch[0].rm_so);
>      strcpy(ret + pmatch[0].rm_so, subs);

Regards

Rüdiger