From: Jim Jagielski Date: Wed, 25 Aug 2010 14:12:46 +0000 (+0000) Subject: *) mod_headers: support global replace in Header Edit X-Git-Tag: 2.2.17~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40a137bad5e484384ecfaf1d687837da412c7735;p=thirdparty%2Fapache%2Fhttpd.git *) mod_headers: support global replace in Header Edit PR 46594 (not 47066 as incorrectly recorded in change log) trunk: http://svn.eu.apache.org/viewvc?view=revision&revision=894036 http://svn.apache.org/viewvc?view=revision&revision=966059 2.2.x: http://people.apache.org/~niq/patches/46594.patch (newly updated to fold in r966059) +1: niq, rpluem, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@989122 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index ad84056e62c..cd347a8f28a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.17 + *) mod_headers: Enable multi-match-and-replace edit option + PR 46594 [Nick Kew] + *) mod_log_config: Make ${cookie}C correctly match whole cookie names instead of substrings. PR 28037. [Dan Franklin , Stefan Fritsch] diff --git a/STATUS b/STATUS index cf505635dfe..6901a53662a 100644 --- a/STATUS +++ b/STATUS @@ -87,14 +87,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) mod_headers: support global replace in Header Edit - PR 46594 (not 47066 as incorrectly recorded in change log) - trunk: http://svn.eu.apache.org/viewvc?view=revision&revision=894036 - http://svn.apache.org/viewvc?view=revision&revision=966059 - 2.2.x: http://people.apache.org/~niq/patches/46594.patch - (newly updated to fold in r966059) - +1: niq, rpluem, jim - * Core: fix symlinks ownership tests PR 36783 Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=632947 diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index b65fbfd0771..65050b45a18 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -94,7 +94,8 @@ typedef enum { 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; /* @@ -364,6 +365,7 @@ static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s /* 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; } @@ -413,11 +415,13 @@ static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd, 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"; } @@ -558,6 +562,7 @@ static const char *process_regexp(header_entry *hdr, const char *value, 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)) { @@ -566,10 +571,17 @@ static const char *process_regexp(header_entry *hdr, const char *value, } 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); + } ret = apr_palloc(pool, strlen(value) + 1 + diffsz); memcpy(ret, value, pmatch[0].rm_so); strcpy(ret + pmatch[0].rm_so, subs); - strcat(ret, value + pmatch[0].rm_eo); + strcat(ret, remainder); return ret; } @@ -695,6 +707,7 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers, echo_header, (void *) &v, r->headers_in, NULL); break; case hdr_edit: + case hdr_edit_r: if (apr_table_get(headers, hdr->header)) { edit_do ed;