From 33a492a130f6b501c821d62dc3aae0e72cc945dd Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Thu, 21 Mar 2002 11:38:03 +0000 Subject: [PATCH] Fixed the previous multiple-cookie fix in the proxy. Cookies are broken in that they contain dates which in turn contain commas - so merging and then unmerging them breaks Set-Cookie headers. Sigh. PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@94082 13f79535-47bb-0310-9956-ffa450edef68 --- src/CHANGES | 6 ++++++ src/modules/proxy/proxy_http.c | 4 ---- src/modules/proxy/proxy_util.c | 38 ++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/CHANGES b/src/CHANGES index f7c7a855975..07065beb8b6 100644 --- a/src/CHANGES +++ b/src/CHANGES @@ -1,4 +1,10 @@ Changes with Apache 1.3.24 + + *) Fixed the previous multiple-cookie fix in the proxy. Cookies + are broken in that they contain dates which in turn contain + commas - so merging and then unmerging them breaks Set-Cookie + headers. Sigh. [Graham Leggett] + *) Add ap_uuencode to the httpd.exp exports file used by the AIX linker. [Bill Stoddard] diff --git a/src/modules/proxy/proxy_http.c b/src/modules/proxy/proxy_http.c index b6dbd2ab53f..5a06a61b30a 100644 --- a/src/modules/proxy/proxy_http.c +++ b/src/modules/proxy/proxy_http.c @@ -539,10 +539,6 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, r->content_type = ap_table_get (r->headers_out, "Content-Type"); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Content-Type: %s", r->content_type); - /* 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"); - /* finally output the headers to the client */ ap_send_http_header(r); diff --git a/src/modules/proxy/proxy_util.c b/src/modules/proxy/proxy_util.c index fd07153651f..0863019dd7b 100644 --- a/src/modules/proxy/proxy_util.c +++ b/src/modules/proxy/proxy_util.c @@ -426,8 +426,11 @@ static int proxy_getline(char *s, int n, BUFF *in, int fold) * Reads headers from a buffer and returns an array of headers. * Returns NULL on file error * This routine tries to deal with too long lines and continuation lines. - * @@@: XXX: FIXME: currently the headers are passed thru un-merged. - * Is that okay, or should they be collapsed where possible? + * + * Note: Currently the headers are passed through unmerged. This has to be + * done so that headers which react badly to merging (such as Set-Cookie + * headers, which contain commas within the date field) do not get stuffed + * up. */ table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f) { @@ -475,8 +478,8 @@ table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f) for (end = &value[strlen(value)-1]; end > value && ap_isspace(*end); --end) *end = '\0'; - /* make sure we merge so as not to destroy duplicated headers */ - ap_table_merge(resp_hdrs, buffer, value); + /* make sure we add so as not to destroy duplicated headers */ + ap_table_add(resp_hdrs, buffer, value); /* the header was too long; at the least we should skip extra data */ if (len >= size - 1) { @@ -1447,6 +1450,20 @@ void ap_proxy_clear_connection(pool *p, table *headers) /* overlay one table on another * keys in base will be replaced by keys in overlay + * + * Note: this has to be done in a special way, due + * to some nastiness when it comes to having multiple + * headers in the overlay table. First, we remove all + * the headers in the base table that are found in the + * overlay table, then we simply concatenate the + * tables together. + * + * The base and overlay tables need not be in the same + * pool (and probably won't be). + * + * If the base table is changed in any way through + * being overlayed with the overlay table, this + * function returns a 1. */ int ap_proxy_table_replace(table *base, table *overlay) { @@ -1454,11 +1471,20 @@ int ap_proxy_table_replace(table *base, table *overlay) int i, q = 0; const char *val; + /* remove overlay's keys from base */ for (i = 0; i < overlay->a.nelts; ++i) { val = ap_table_get(base, elts[i].key); - if (!val || strcmp(val, elts[i].val)) + if (!val || strcmp(val, elts[i].val)) { q = 1; - ap_table_set(base, elts[i].key, elts[i].val); + } + if (val) { + ap_table_unset(base, elts[i].key); + } + } + + /* add overlay to base */ + for (i = 0; i < overlay->a.nelts; ++i) { + ap_table_add(base, elts[i].key, elts[i].val); } return q; -- 2.47.2