single Set-Cookie header. Set-Cookie and Set-Cookie2 headers
are now unmerged in the http proxy before being sent to the
client.
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.
PR:
Obtained from:
Submitted by:
Reviewed by:
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93527
13f79535-47bb-0310-9956-
ffa450edef68
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]
+
*) Add the server-limit and thread-limit values to the scoreboard
for the sake of third-party applications.
[Adam Sussman <myddryn@vishnu.vidya.com>]
/* 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);
}
}
}
+ /* 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 */
if (backasswards) {
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) {
}
}
}
+
+/* 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);
+}