]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Add the 'echo' option to mod_headers Header directive. Use the new option
authorBill Stoddard <stoddard@apache.org>
Fri, 1 Jun 2001 02:58:44 +0000 (02:58 +0000)
committerBill Stoddard <stoddard@apache.org>
Fri, 1 Jun 2001 02:58:44 +0000 (02:58 +0000)
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

modules/metadata/mod_headers.c

index d9a8a5e7bf298f3eacddc3d7a5fac833fec64412..c87747b97400cd20ff92a1293ff39b5cdade362d 100644 (file)
@@ -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;