This has been discussed before(*), but I never got around
to patching it in SVN.

(1) ProxyPassReverse is documented as working inside <Location>
(2) ... but ProxyPassReverse is implemented on the *server* config.
So, although it is syntactically correct within <Location> due to a hack, it doesn't actually work there beyond the trivial case.
It loses the merge_dir_config, and instead collects all <Location>s
in a single array without any means of distinguishing them.

I attach two patches: one for trunk, the other for 2.0.
The 2.0 patch is in production at my Client, and combines a patch
I made for them in January (i.e. well-tested:-) with the
long-standing patch for Bug 10722 at issues.apache.org.

If noone objects I'll commit the Trunk patch and propose the
2.0 patch for backport.

(*) http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2

--
Nick Kew
Index: mod_proxy_http.c
===================================================================
--- mod_proxy_http.c    (revision 231170)
+++ mod_proxy_http.c    (working copy)
@@ -968,7 +968,7 @@
     return APR_SUCCESS;
 }
 
-static void process_proxy_header(request_rec* r, proxy_server_conf* c,
+static void process_proxy_header(request_rec* r, proxy_dir_conf* c,
                       const char* key, const char* value)
 {
     static const char* date_hdrs[]
@@ -1021,7 +1021,9 @@
     int saw_headers = 0;
     void *sconf = r->server->module_config;
     proxy_server_conf *psc;
+    proxy_dir_conf *dconf;
 
+    dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
     psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
 
     r->headers_out = apr_table_make(r->pool, 20);
@@ -1096,7 +1098,7 @@
          * Modify headers requiring canonicalisation and/or affected
          * by ProxyPassReverse and family with process_proxy_header
          */
-        process_proxy_header(r, psc, buffer, value) ;
+        process_proxy_header(r, dconf, buffer, value) ;
         saw_headers = 1;
 
         /* the header was too long; at the least we should skip extra data */
Index: mod_proxy.c
===================================================================
--- mod_proxy.c (revision 231170)
+++ mod_proxy.c (working copy)
@@ -788,11 +788,6 @@
     ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *));
     ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
     ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->cookie_path_str = apr_strmatch_precompile(p, "path=", 0);
-    ps->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0);
     ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
     ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry));
     ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int));
@@ -832,13 +827,6 @@
     ps->proxies = apr_array_append(p, base->proxies, overrides->proxies);
     ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy);
     ps->aliases = apr_array_append(p, base->aliases, overrides->aliases);
-    ps->raliases = apr_array_append(p, base->raliases, overrides->raliases);
-    ps->cookie_paths
-        = apr_array_append(p, base->cookie_paths, overrides->cookie_paths);
-    ps->cookie_domains
-        = apr_array_append(p, base->cookie_domains, overrides->cookie_domains);
-    ps->cookie_path_str = base->cookie_path_str;
-    ps->cookie_domain_str = base->cookie_domain_str;
     ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies);
     ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn);
     ps->allowed_connect_ports = apr_array_append(p, 
base->allowed_connect_ports, overrides->allowed_connect_ports);
@@ -869,6 +857,13 @@
 
     /* Filled in by proxysection, when applicable */
 
+    /* Put these in the dir config so they work inside <Location> */
+    new->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_path_str = apr_strmatch_precompile(p, "path=", 0);
+    new->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0);
+
     return (void *) new;
 }
 
@@ -880,6 +875,15 @@
     new->p = add->p;
     new->p_is_fnmatch = add->p_is_fnmatch;
     new->r = add->r;
+
+    /* Put these in the dir config so they work inside <Location> */
+    new->raliases = apr_array_append(p, base->raliases, overrides->raliases);
+    new->cookie_paths
+        = apr_array_append(p, base->cookie_paths, overrides->cookie_paths);
+    new->cookie_domains
+        = apr_array_append(p, base->cookie_domains, overrides->cookie_domains);
+    new->cookie_path_str = base->cookie_path_str;
+    new->cookie_domain_str = base->cookie_domain_str;
     return new;
 }
 
@@ -1042,14 +1046,11 @@
 }
 
 static const char *
-    add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r)
+    add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f, const char *r)
 {
-    server_rec *s = cmd->server;
-    proxy_server_conf *conf;
+    proxy_dir_conf *conf = dconf;
     struct proxy_alias *new;
 
-    conf = (proxy_server_conf *)ap_get_module_config(s->module_config, 
-                                                     &proxy_module);
     if (r!=NULL && cmd->path == NULL ) {
         new = apr_array_push(conf->raliases);
         new->fake = f;
@@ -1068,14 +1069,11 @@
     return NULL;
 }
 static const char*
-    cookie_path(cmd_parms *cmd, void *dummy, const char *f, const char *r)
+    cookie_path(cmd_parms *cmd, void *dconf, const char *f, const char *r)
 {
-    server_rec *s = cmd->server;
-    proxy_server_conf *conf;
+    proxy_dir_conf *conf = dconf;
     struct proxy_alias *new;
 
-    conf = (proxy_server_conf *)ap_get_module_config(s->module_config,
-                                                     &proxy_module);
     new = apr_array_push(conf->cookie_paths);
     new->fake = f;
     new->real = r;
@@ -1083,14 +1081,11 @@
     return NULL;
 }
 static const char*
-    cookie_domain(cmd_parms *cmd, void *dummy, const char *f, const char *r)
+    cookie_domain(cmd_parms *cmd, void *dconf, const char *f, const char *r)
 {
-    server_rec *s = cmd->server;
-    proxy_server_conf *conf;
+    proxy_dir_conf *conf = dconf;
     struct proxy_alias *new;
 
-    conf = (proxy_server_conf *)ap_get_module_config(s->module_config,
-                                                     &proxy_module);
     new = apr_array_push(conf->cookie_domains);
     new->fake = f;
     new->real = r;
Index: mod_proxy.h
===================================================================
--- mod_proxy.h (revision 231170)
+++ mod_proxy.h (working copy)
@@ -125,7 +125,6 @@
     apr_array_header_t *proxies;
     apr_array_header_t *sec_proxy;
     apr_array_header_t *aliases;
-    apr_array_header_t *raliases;
     apr_array_header_t *noproxies;
     apr_array_header_t *dirconn;
     apr_array_header_t *allowed_connect_ports;
@@ -173,10 +172,6 @@
  * the strmatch_patterns are really a const just to have a
  * case-independent strstr.
  */
-    apr_array_header_t* cookie_paths;
-    apr_array_header_t* cookie_domains;
-    const apr_strmatch_pattern* cookie_path_str;
-    const apr_strmatch_pattern* cookie_domain_str;
     enum {
         status_off,
         status_on,
@@ -191,6 +186,19 @@
     const char *p;            /* The path */
     int         p_is_fnmatch; /* Is this path an fnmatch candidate? */
     ap_regex_t  *r;            /* Is this a regex? */
+
+/* ProxyPassReverse and friends are documented as working inside
+ * <Location>.  But in fact they never have done in the case of
+ * more than one <Location>, because the server_conf can't see it.
+ * We need to move them to the per-dir config.
+ * Discussed in February:
+ * http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2
+ */
+    apr_array_header_t *raliases;
+    apr_array_header_t* cookie_paths;
+    apr_array_header_t* cookie_domains;
+    const apr_strmatch_pattern* cookie_path_str;
+    const apr_strmatch_pattern* cookie_domain_str;
 } proxy_dir_conf;
 
 typedef struct {
--- dist/mod_proxy.c    2005-08-05 10:26:01.000000000 +0100
+++ patched/mod_proxy.c 2005-08-06 20:52:09.846068216 +0100
@@ -439,7 +439,6 @@
     ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *));
     ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
     ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
-    ps->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
     ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
     ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry));
     ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int));
@@ -474,7 +473,6 @@
     ps->proxies = apr_array_append(p, base->proxies, overrides->proxies);
     ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy);
     ps->aliases = apr_array_append(p, base->aliases, overrides->aliases);
-    ps->raliases = apr_array_append(p, base->raliases, overrides->raliases);
     ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies);
     ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn);
     ps->allowed_connect_ports = apr_array_append(p, 
base->allowed_connect_ports, overrides->allowed_connect_ports);
@@ -500,6 +498,11 @@
 
     /* Filled in by proxysection, when applicable */
 
+    new->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
+    new->cookie_path_str = apr_strmatch_precompile(p, "path=", 0) ;
+    new->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0) ;
     return (void *) new;
 }
 
@@ -507,10 +510,18 @@
 {
     proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, 
sizeof(proxy_dir_conf));
     proxy_dir_conf *add = (proxy_dir_conf *) addv;
+    proxy_dir_conf *base = (proxy_dir_conf *) basev;
 
     new->p = add->p;
     new->p_is_fnmatch = add->p_is_fnmatch;
     new->r = add->r;
+    new->raliases = apr_array_append(p, base->raliases, add->raliases);
+    new->cookie_paths = apr_array_append(p, base->cookie_paths,
+                                        add->cookie_paths);
+    new->cookie_domains = apr_array_append(p, base->cookie_domains,
+                                          add->cookie_domains);
+    new->cookie_path_str = base->cookie_path_str;
+    new->cookie_domain_str = base->cookie_domain_str;
     return new;
 }
 
@@ -617,12 +628,9 @@
 static const char *
     add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r)
 {
-    server_rec *s = cmd->server;
-    proxy_server_conf *conf;
+    proxy_dir_conf *conf = dummy;
     struct proxy_alias *new;
 
-    conf = (proxy_server_conf *)ap_get_module_config(s->module_config, 
-                                                     &proxy_module);
     if (r!=NULL && cmd->path == NULL ) {
         new = apr_array_push(conf->raliases);
         new->fake = f;
@@ -640,6 +648,29 @@
 
     return NULL;
 }
+static const char*
+    cookie_path(cmd_parms *cmd, void *dummy, const char *f, const char *r)
+{
+    proxy_dir_conf *conf = dummy;
+    struct proxy_alias *new;
+
+    new = apr_array_push(conf->cookie_paths) ;
+    new->fake = f;
+    new->real = r;
+    return NULL ;
+}
+static const char*
+    cookie_domain(cmd_parms *cmd, void *dummy, const char *f, const char *r)
+{
+    proxy_dir_conf *conf = dummy;
+    struct proxy_alias *new;
+
+    new = apr_array_push(conf->cookie_domains) ;
+    new->fake = f;
+    new->real = r;
+    return NULL ;
+}
+
 
 static const char *
     set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
@@ -1031,6 +1062,10 @@
      "This overrides the server timeout"),
     AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF,
      "How to handle bad header line in response: IsError | Ignore | 
StartBody"),
+    AP_INIT_TAKE2("ProxyPassReverseCookiePath", cookie_path, NULL,
+      RSRC_CONF|ACCESS_CONF, "Path rewrite rule for proxying cookies") ,
+    AP_INIT_TAKE2("ProxyPassReverseCookieDomain", cookie_domain, NULL,
+      RSRC_CONF|ACCESS_CONF, "Domain rewrite rule for proxying cookies") ,
  
     {NULL}
 };
--- dist/mod_proxy.h    2005-08-05 10:26:01.000000000 +0100
+++ patched/mod_proxy.h 2005-08-06 20:46:27.467117728 +0100
@@ -51,6 +51,7 @@
 #include "apr_uri.h"
 #include "apr_date.h"
 #include "apr_fnmatch.h"
+#include "apr_strmatch.h"
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
 
@@ -119,7 +120,6 @@
     apr_array_header_t *proxies;
     apr_array_header_t *sec_proxy;
     apr_array_header_t *aliases;
-    apr_array_header_t *raliases;
     apr_array_header_t *noproxies;
     apr_array_header_t *dirconn;
     apr_array_header_t *allowed_connect_ports;
@@ -166,6 +166,16 @@
     const char *p;            /* The path */
     int         p_is_fnmatch; /* Is this path an fnmatch candidate? */
     regex_t    *r;            /* Is this a regex? */
+    apr_array_header_t *raliases;
+
+/* new stuff on the end maximises binary back-compatibility.
+   the strmatch_patterns are really a const just to have a
+   case-independent strstr.
+ */
+  apr_array_header_t* cookie_paths ;
+  apr_array_header_t* cookie_domains ;
+  const apr_strmatch_pattern* cookie_path_str ;
+  const apr_strmatch_pattern* cookie_domain_str ;
 } proxy_dir_conf;
 
 typedef struct {
--- dist/proxy_http.c   2005-08-05 10:26:20.000000000 +0100
+++ patched/proxy_http.c        2005-08-06 20:56:06.363112160 +0100
@@ -19,6 +19,7 @@
 #include "mod_proxy.h"
 
 module AP_MODULE_DECLARE_DATA proxy_http_module;
+module AP_MODULE_DECLARE_DATA proxy_module;
 
 int ap_proxy_http_canon(request_rec *r, char *url);
 int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf,
@@ -110,7 +111,7 @@
     return OK;
 }
  
-static const char *ap_proxy_location_reverse_map(request_rec *r, 
proxy_server_conf *conf, const char *url)
+static const char *ap_proxy_location_reverse_map(request_rec *r, 
proxy_dir_conf *conf, const char *url)
 {
     struct proxy_alias *ent;
     int i, l1, l2;
@@ -130,6 +131,98 @@
     }
     return url;
 }
+/* cookies are a bit trickier to match: we've got two substrings to worry
+ * about, and we can't just find them with strstr 'cos of case.  Regexp
+ * matching would be an easy fix, but for better consistency with all the
+ * other matches we'll refrain and use apr_strmatch to find path=/domain=
+ * and stick to plain strings for the config values.
+ */
+static const char *proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf 
*conf, const char *str)
+{
+    struct proxy_alias *ent;
+    size_t len = strlen(str);
+    const char* newpath = NULL ;
+    const char* newdomain = NULL ;
+    const char* pathp ;
+    const char* domainp ;
+    const char* pathe ;
+    const char* domaine ;
+    size_t l1, l2, i, poffs = 0, doffs = 0 ;
+    int ddiff = 0 ;
+    int pdiff = 0 ;
+    char* ret ;
+    
+/* find the match and replacement, but save replacing until we've done
+   both path and domain so we know the new strlen
+*/
+    if (pathp = apr_strmatch(conf->cookie_path_str, str, len), pathp) {
+        pathp += 5 ;
+        poffs = pathp - str ;
+        pathe = ap_strchr((char*)pathp, ';') ;
+        l1 = pathe ? (pathe-pathp) : strlen(pathp) ;
+        pathe = pathp + l1 ;
+        ent = (struct proxy_alias *)conf->cookie_paths->elts;
+        for (i = 0; i < conf->cookie_paths->nelts; i++) {
+            l2 = strlen(ent[i].fake);
+            if (l1 >= l2 && strncmp(ent[i].fake, pathp, l2) == 0) {
+                newpath = ent[i].real ;
+                pdiff = strlen(newpath) - l1 ;
+                break ;
+            }
+        }
+    }
+    if (domainp = apr_strmatch(conf->cookie_domain_str, str, len), domainp) {
+        domainp += 7 ;
+        doffs = domainp - str ;
+        domaine = ap_strchr((char*)domainp, ';') ;
+        l1 = domaine ? (domaine-domainp) : strlen(domainp) ;
+        domaine = domainp + l1 ;
+        ent = (struct proxy_alias *)conf->cookie_domains->elts;
+        for (i = 0; i < conf->cookie_domains->nelts; i++) {
+            l2 = strlen(ent[i].fake);
+            if (l1 >= l2 && strncmp(ent[i].fake, domainp, l2) == 0) {
+                newdomain = ent[i].real ;
+                ddiff = strlen(newdomain) - l1 ;
+                break ;
+            }
+        }
+    }
+    if (newpath) {
+        ret = apr_palloc(r->pool, len+pdiff+ddiff+1) ;
+        l1 = strlen(newpath) ;
+        if ( newdomain ) {
+            l2 = strlen(newdomain) ;
+            if (doffs > poffs) {
+                memcpy(ret, str, poffs) ;
+                memcpy(ret+poffs, newpath, l1) ;
+                memcpy(ret+poffs+l1, pathe, domainp-pathe) ;
+                memcpy(ret+doffs+pdiff, newdomain, l2) ;
+                strcpy(ret+doffs+pdiff+l2, domaine) ;
+            } else {
+                memcpy(ret, str, doffs) ;
+                memcpy(ret+doffs, newdomain, l2) ;
+                memcpy(ret+doffs+l2, domaine, pathp-domaine) ;
+                memcpy(ret+poffs+ddiff, newpath, l1) ;
+                strcpy(ret+poffs+ddiff+l1, pathe) ;
+            }
+        } else {
+            memcpy(ret, str, poffs) ;
+            memcpy(ret+poffs, newpath, l1) ;
+            strcpy(ret+poffs+l1, pathe) ;
+        }
+    } else {
+        if ( newdomain ) {
+            ret = apr_palloc(r->pool, len+pdiff+ddiff+1) ;
+            l2 = strlen(newdomain) ;
+            memcpy(ret, str, doffs) ;
+            memcpy(ret+doffs, newdomain, l2) ;
+            strcpy(ret+doffs+l2, domaine) ;
+        } else {
+            ret = (char*) str ;        /* no change */
+        }
+    }
+    return ret ;
+}
 
 /* Clear all connection-based headers from the incoming headers table */
 static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers)
@@ -659,6 +752,44 @@
     return APR_SUCCESS;
 }
 
+typedef struct {
+  request_rec* r ;
+  proxy_dir_conf* c ;
+} hdr_rec ;
+static int process_proxy_header(void* CTX, const char* key, const char* value)
+{
+    hdr_rec* ctx = CTX ;
+    static const char* date_hdrs[]
+        = { "Date", "Expires", "Last-Modified", NULL } ;
+    static const struct {
+        const char* name ;
+        const char* (*func)(request_rec*, proxy_dir_conf*, const char*) ;
+    } transform_hdrs[] = {
+        { "Location", ap_proxy_location_reverse_map } ,
+        { "Content-Location", ap_proxy_location_reverse_map } ,
+        { "URI", ap_proxy_location_reverse_map } ,
+        { "Set-Cookie", proxy_cookie_reverse_map } ,
+        { NULL, NULL }
+    } ;
+    int i ;
+    for ( i = 0 ; date_hdrs[i] ; ++i ) {
+        if ( !strcasecmp(date_hdrs[i], key) ) {
+            apr_table_add(ctx->r->headers_out, key,
+                ap_proxy_date_canon(ctx->r->pool, value)) ;
+            return 1 ;
+        }
+    }
+    for ( i = 0 ; transform_hdrs[i].name ; ++i ) {
+        if ( !strcasecmp(transform_hdrs[i].name, key) ) {
+            apr_table_add(ctx->r->headers_out, key,
+                (*transform_hdrs[i].func)(ctx->r, ctx->c, value)) ;
+            return 2 ;
+       }
+    }
+    apr_table_add(ctx->r->headers_out, key, value) ;
+    return 3 ;
+}
+
 static
 apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
                                             proxy_http_conn_t *p_conn,
@@ -667,17 +798,23 @@
                                             proxy_server_conf *conf,
                                             apr_bucket_brigade *bb,
                                             char *server_portstr) {
+    apr_table_t* backend_headers ;
     conn_rec *c = r->connection;
     char buffer[HUGE_STRING_LEN];
     char keepchar;
     request_rec *rp;
     apr_bucket *e;
     int len, backasswards;
+    proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+               &proxy_module) ;
     int received_continue = 1; /* flag to indicate if we should
                                 * loop over response parsing logic
                                 * in the case that the origin told us
                                 * to HTTP_CONTINUE
                                 */
+    hdr_rec hdrctx ;
+    hdrctx.r = r ;
+    hdrctx.c = dconf ;
 
     /* Get response from the remote server, and pass it up the
      * filter chain
@@ -749,9 +886,9 @@
             /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped 
headers*/
             /* Also, take care with headers with multiple occurences. */
 
-            r->headers_out = ap_proxy_read_headers(r, rp, buffer,
-                                                   sizeof(buffer), origin);
-            if (r->headers_out == NULL) {
+            backend_headers = ap_proxy_read_headers(r, rp, buffer,
+                                                    sizeof(buffer), origin);
+            if (backend_headers == NULL) {
                 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
                              r->server, "proxy: bad HTTP/%d.%d header "
                              "returned by %s (%s)", major, minor, r->uri,
@@ -762,7 +899,7 @@
                  * are in a bad position here.. so force everything we send out
                  * to have nothing to do with the incoming packet
                  */
-                r->headers_out = apr_table_make(r->pool,1);
+                backend_headers = apr_table_make(r->pool,1);
                 r->status = HTTP_BAD_GATEWAY;
                 r->status_line = "bad gateway";
                 return r->status;
@@ -770,11 +907,11 @@
             } else {
                 /* strip connection listed hop-by-hop headers from response */
                 const char *buf;
-                p_conn->close += ap_proxy_liststr(apr_table_get(r->headers_out,
+                p_conn->close += 
ap_proxy_liststr(apr_table_get(backend_headers,
                                                                 "Connection"),
                                                   "close");
-                ap_proxy_clear_connection(p, r->headers_out);
-                if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
+                ap_proxy_clear_connection(p, backend_headers);
+                if ((buf = apr_table_get(backend_headers, "Content-Type"))) {
                     ap_set_content_type(r, apr_pstrdup(p, buf));
                 }            
                 ap_proxy_pre_http_request(origin,rp);
@@ -783,7 +920,7 @@
             /* handle Via header in response */
             if (conf->viaopt != via_off && conf->viaopt != via_block) {
                 /* create a "Via:" response header entry and merge it */
-                apr_table_mergen(r->headers_out, "Via",
+                apr_table_mergen(backend_headers, "Via",
                                  (conf->viaopt == via_full)
                                      ? apr_psprintf(p, "%d.%d %s%s (%s)",
                                            HTTP_VERSION_MAJOR(r->proto_num),
@@ -819,41 +956,17 @@
                          "proxy: HTTP: received 100 CONTINUE");
         }
 
-        /* we must accept 3 kinds of date, but generate only 1 kind of date */
-        {
-            const char *buf;
-            if ((buf = apr_table_get(r->headers_out, "Date")) != NULL) {
-                apr_table_set(r->headers_out, "Date",
-                              ap_proxy_date_canon(p, buf));
-            }
-            if ((buf = apr_table_get(r->headers_out, "Expires")) != NULL) {
-                apr_table_set(r->headers_out, "Expires",
-                              ap_proxy_date_canon(p, buf));
-            }
-            if ((buf = apr_table_get(r->headers_out, "Last-Modified")) != 
NULL) {
-                apr_table_set(r->headers_out, "Last-Modified",
-                              ap_proxy_date_canon(p, buf));
-            }
-        }
-
-        /* munge the Location and URI response headers according to
-         * ProxyPassReverse
-         */
-        {
-            const char *buf;
-            if ((buf = apr_table_get(r->headers_out, "Location")) != NULL) {
-                apr_table_set(r->headers_out, "Location",
-                              ap_proxy_location_reverse_map(r, conf, buf));
-            }
-            if ((buf = apr_table_get(r->headers_out, "Content-Location")) != 
NULL) {
-                apr_table_set(r->headers_out, "Content-Location",
-                              ap_proxy_location_reverse_map(r, conf, buf));
-            }
-            if ((buf = apr_table_get(r->headers_out, "URI")) != NULL) {
-                apr_table_set(r->headers_out, "URI",
-                              ap_proxy_location_reverse_map(r, conf, buf));
-            }
+/* transcribe backend headers to headers_out, rewriting any that need it.
+ * The old method based on if ( apr_table_get(...) ) fails against
+ * duplicated headers, so we copy-and-transcribe by the entry instead.
+ */
+        if ( r->headers_out ) {
+            apr_table_clear(r->headers_out) ;
+        } else {
+            r->headers_out = apr_table_make(r->pool, 10) ;
         }
+        apr_table_do(process_proxy_header, &hdrctx, backend_headers, NULL) ;
+        apr_table_clear(backend_headers) ;
 
         if ((r->status == 401) && (conf->error_override != 0)) {
             const char *buf;

Reply via email to