From 8e3511032180ed63206102f836c06a620dc6b0c2 Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Sat, 14 Sep 2013 15:29:04 +0000 Subject: [PATCH] mod_headers: Add 'Header SetIfEmpty header-name val' to only set a header if it's not already there (can't do this with Edit) trunk patch: http://svn.apache.org/1496338 Submitted by: covener Reviewed by: jim, humbedooh git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1523270 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 7 ------- docs/manual/mod/mod_headers.xml | 8 ++++++++ modules/metadata/mod_headers.c | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 803581396e..7beaef82a0 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.7 + *) mod_headers: Add 'setifempty' command to Header and RequestHeader. + [Eric Covener] + *) mod_logio: new format-specifier %C (combined) which is the sum of received and sent byte counts. PR54015 [Christophe Jaillet] diff --git a/STATUS b/STATUS index 1a2a5e5164..4cd4395dba 100644 --- a/STATUS +++ b/STATUS @@ -97,13 +97,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - - * mod_headers: Add 'Header SetIfEmpty header-name val' to only set - a header if it's not already there (can't do this with Edit) - trunk patch: http://svn.apache.org/1496338 - 2.4.x patch: trunk works - +1: covener, jim, humbedooh - * mod_headers: Add 'Header note header-name note-name' to copy a headers value into a note (so a CGI/Proxy header can be deleted and logged) trunk patch: http://svn.apache.org/r1520908 diff --git a/docs/manual/mod/mod_headers.xml b/docs/manual/mod/mod_headers.xml index 528e7f2d0d..774cadc4f6 100644 --- a/docs/manual/mod/mod_headers.xml +++ b/docs/manual/mod/mod_headers.xml @@ -248,6 +248,10 @@ Header merge Cache-Control no-store env=NO_STORE
set
The request header is set, replacing any previous header with this name
+ +
setifempty
+
The request header is set, but only if there is no previous header + with this name
unset
The request header of this name is removed, if it exists. If @@ -388,6 +392,10 @@ Header merge Cache-Control no-store env=NO_STORE
The response header is set, replacing any previous header with this name. The value may be a format string.
+
setifempty
+
The request header is set, but only if there is no previous header + with this name
+
unset
The response header of this name is removed, if it exists. If there are multiple headers of the same name, all will be diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index 9ce2fdec67..6c03e71839 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -96,7 +96,8 @@ typedef enum { hdr_unset = 'u', /* unset header */ hdr_echo = 'e', /* echo headers from request to response */ hdr_edit = 'r', /* change value by regexp, match once */ - hdr_edit_r = 'R' /* change value by regexp, everymatch */ + hdr_edit_r = 'R', /* change value by regexp, everymatch */ + hdr_setifempty = 'i' /* set value if header not already present*/ } hdr_actions; /* @@ -431,6 +432,8 @@ static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd, if (!strcasecmp(action, "set")) new->action = hdr_set; + else if (!strcasecmp(action, "setifempty")) + new->action = hdr_setifempty; else if (!strcasecmp(action, "add")) new->action = hdr_add; else if (!strcasecmp(action, "append")) @@ -446,7 +449,7 @@ static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd, else if (!strcasecmp(action, "edit*")) new->action = hdr_edit_r; else - return "first argument must be 'add', 'set', 'append', 'merge', " + return "first argument must be 'add', 'set', 'setifempty', 'append', 'merge', " "'unset', 'echo', 'edit', or 'edit*'."; if (new->action == hdr_edit || new->action == hdr_edit_r) { @@ -755,6 +758,14 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers, } apr_table_setn(headers, hdr->header, process_tags(hdr, r)); break; + case hdr_setifempty: + if (NULL == apr_table_get(headers, hdr->header)) { + if (!strcasecmp(hdr->header, "Content-Type")) { + ap_set_content_type(r, process_tags(hdr, r)); + } + apr_table_setn(headers, hdr->header, process_tags(hdr, r)); + } + break; case hdr_unset: apr_table_unset(headers, hdr->header); break; -- 2.40.0