Hi all,

This patch is the v2.0 port of the fix applied to v1.3 to stop
duplicated headers in a response from going missing.

Regards,
Graham
-- 
-----------------------------------------
[EMAIL PROTECTED]                "There's a moon
                                        over Bourbon Street
                                                tonight..."
diff -r -U 3 /home/minfrin/src/apache/pristine/httpd-2.0/CHANGES httpd-2.0/CHANGES
--- /home/minfrin/src/apache/pristine/httpd-2.0/CHANGES Tue Feb 19 23:44:41 2002
+++ httpd-2.0/CHANGES   Wed Feb 20 23:30:26 2002
@@ -1,4 +1,16 @@
 Changes with Apache 2.0.33-dev
+
+  *) Some browsers ignore cookies that have been merged into a
+     single Set-Cookie header. Set-Cookie and Set-Cookie2 headers
+     are now unmerged in the http proxy before being sent to the
+     client. [Graham Leggett]
+
+  *) Fix a problem with proxy where each entry of a duplicated
+     header such as Set-Cookie would overwrite and obliterate the
+     previous value of the header, resulting in multiple header
+     values (like cookies) going missing.
+     [Graham Leggett, Joshua Slive]
+
   *) Win32: Fix bug in mod_status with displaying "Restart Time"
      and "Server uptime".
      [Bill Stoddard]
diff -r -U 3 /home/minfrin/src/apache/pristine/httpd-2.0/modules/proxy/proxy_http.c 
httpd-2.0/modules/proxy/proxy_http.c
--- /home/minfrin/src/apache/pristine/httpd-2.0/modules/proxy/proxy_http.c      Mon 
Feb 11 22:30:13 2002
+++ httpd-2.0/modules/proxy/proxy_http.c        Wed Feb 20 23:04:55 2002
@@ -569,21 +569,21 @@
         /* Add X-Forwarded-For: so that the upstream has a chance to
          * determine, where the original request came from.
          */
-        apr_table_setn(r->headers_in, "X-Forwarded-For",
+        apr_table_mergen(r->headers_in, "X-Forwarded-For",
                        r->connection->remote_ip);
 
         /* Add X-Forwarded-Host: so that upstream knows what the
          * original request hostname was.
          */
         if ((buf = apr_table_get(r->headers_in, "Host"))) {
-            apr_table_setn(r->headers_in, "X-Forwarded-Host", buf);
+            apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf);
         }
 
         /* Add X-Forwarded-Server: so that upstream knows what the
          * name of this proxy server is (if there are more than one)
          * XXX: This duplicates Via: - do we strictly need it?
          */
-        apr_table_setn(r->headers_in, "X-Forwarded-Server",
+        apr_table_mergen(r->headers_in, "X-Forwarded-Server",
                        r->server->server_hostname);
     }
 
@@ -824,6 +824,10 @@
                               ap_proxy_location_reverse_map(r, conf, buf));
             }
         }
+
+        /* cookies are special: they must not be merged (stupid browsers) */
+        ap_proxy_table_unmerge(r->pool, r->headers_out, "Set-Cookie");
+        ap_proxy_table_unmerge(r->pool, r->headers_out, "Set-Cookie2");
 
         r->sent_bodyct = 1;
         /* Is it an HTTP/0.9 response? If so, send the extra data */
diff -r -U 3 /home/minfrin/src/apache/pristine/httpd-2.0/modules/proxy/proxy_util.c 
httpd-2.0/modules/proxy/proxy_util.c
--- /home/minfrin/src/apache/pristine/httpd-2.0/modules/proxy/proxy_util.c      Sun 
Feb  3 17:48:28 2002
+++ httpd-2.0/modules/proxy/proxy_util.c        Wed Feb 20 23:10:45 2002
@@ -439,7 +439,8 @@
        for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
            *end = '\0';
 
-        apr_table_add(headers_out, buffer, value);
+        /* make sure we merge so as not to destroy duplicated headers */
+        apr_table_merge(headers_out, buffer, value);
 
        /* the header was too long; at the least we should skip extra data */
        if (len >= size - 1) { 
@@ -1070,4 +1071,33 @@
             f = f->next;
         }
     }
+}
+
+/* unmerge an element in the table */
+void ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key)
+{
+    apr_off_t offset = 0;
+    apr_off_t count = 0;
+    char *value = NULL;
+
+    /* get the value to unmerge */
+    const char *initial = apr_table_get(t, key);
+    if (!initial) {
+        return;
+    }
+    value = apr_pstrdup(p, initial);
+
+    /* remove the value from the headers */
+    apr_table_unset(t, key);
+
+    /* find each comma */
+    while (value[count]) {
+        if (value[count] == ',') {
+            value[count] = 0;
+            apr_table_add(t, key, value + offset);
+            offset = count + 1;
+        }
+        count++;
+    }
+    apr_table_add(t, key, value + offset);
 }

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to