On 27.12.2009 01:05, n...@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