From: Bill Stoddard Date: Fri, 1 Jun 2001 02:58:44 +0000 (+0000) Subject: Add the 'echo' option to mod_headers Header directive. Use the new option X-Git-Tag: 2.0.19~158 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18ce869320f81faa5ad21e35c694465903b52cf8;p=thirdparty%2Fapache%2Fhttpd.git Add the 'echo' option to mod_headers Header directive. Use the new option like this: Header echo regex If a header received on a request matches regex, it is copied to the response headers. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89250 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index d9a8a5e7bf2..c87747b9740 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -122,7 +122,8 @@ typedef enum { hdr_add = 'a', /* add header (could mean multiple hdrs) */ hdr_set = 's', /* set (replace old value) */ hdr_append = 'm', /* append (merge into any old value) */ - hdr_unset = 'u' /* unset header */ + hdr_unset = 'u', /* unset header */ + hdr_echo = 'e' /* echo headers from request to response */ } hdr_actions; typedef enum { @@ -134,8 +135,15 @@ typedef struct { hdr_actions action; char *header; const char *value; + regex_t *regex; } header_entry; +/* echo_do is used only with Header echo */ +typedef struct { + request_rec *r; + header_entry *hdr; +} echo_do; + /* * headers_conf is our per-module configuration. This is used as both * a per-dir and per-server config @@ -203,13 +211,29 @@ static const char *header_inout_cmd(hdr_inout inout, cmd_parms *cmd, void *indir new->action = hdr_append; else if (!strcasecmp(action, "unset")) new->action = hdr_unset; + else if (!strcasecmp(action, "echo")) + new->action = hdr_echo; else - return "first argument must be add, set, append or unset."; + return "first argument must be add, set, append, unset or echo."; if (new->action == hdr_unset) { if (value) return "header unset takes two arguments"; } + else if (new->action == hdr_echo) { + regex_t *regex; + if (value) + return "Header echo takes two arguments"; + else if (inout != hdr_out) + return "Header echo only valid on Header directive"; + else { + regex = ap_pregcomp(cmd->pool, hdr, REG_EXTENDED | REG_NOSUB); + if (regex == NULL) { + return "Header echo regex could not be compiled"; + } + } + new->regex = regex; + } else if (!value) return "header requires three arguments"; @@ -238,11 +262,23 @@ static const char *request_header_cmd(cmd_parms *cmd, void *indirconf, return header_inout_cmd(hdr_in, cmd, indirconf, action, inhdr, value); } +static int echo_header(echo_do *v, const char *key, const char *val) +{ + /* If the input header (key) matches the regex, echo it intact to + * r->headers_out. + */ + if (!ap_regexec(v->hdr->regex, key, 0, NULL, 0)) { + apr_table_addn(v->r->headers_out, key, val); + } + + return 0; +} -static void do_headers_fixup(apr_table_t *headers, +static void do_headers_fixup(request_rec *r, hdr_inout inout, apr_array_header_t *fixup) { int i; + apr_table_t *headers = (hdr_in == inout) ? r->headers_in : r->headers_out; for (i = 0; i < fixup->nelts; ++i) { header_entry *hdr = &((header_entry *) (fixup->elts))[i]; @@ -259,6 +295,15 @@ static void do_headers_fixup(apr_table_t *headers, case hdr_unset: apr_table_unset(headers, hdr->header); break; + case hdr_echo: + { + echo_do v; + v.r = r; + v.hdr = hdr; + apr_table_do((int (*) (void *, const char *, const char *)) + echo_header, (void *) &v, r->headers_in, NULL); + break; + } } } } @@ -287,8 +332,8 @@ static apr_status_t ap_headers_output_filter(ap_filter_t *f, "headers: ap_headers_output_filter()"); /* do the fixup */ - do_headers_fixup(f->r->headers_out, serverconf->fixup_out); - do_headers_fixup(f->r->headers_out, dirconf->fixup_out); + do_headers_fixup(f->r, hdr_out, serverconf->fixup_out); + do_headers_fixup(f->r, hdr_out, dirconf->fixup_out); /* remove ourselves from the filter chain */ ap_remove_output_filter(f); @@ -306,8 +351,8 @@ static apr_status_t ap_headers_fixup(request_rec *r) /* do the fixup */ if (serverconf->fixup_in->nelts || dirconf->fixup_in->nelts) { - do_headers_fixup(r->headers_in, serverconf->fixup_in); - do_headers_fixup(r->headers_in, dirconf->fixup_in); + do_headers_fixup(r, hdr_in, serverconf->fixup_in); + do_headers_fixup(r, hdr_in, dirconf->fixup_in); } return DECLINED;