From 79b4cee9d3bff266e0272204eff15ebe506f6661 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 16 Feb 2009 20:24:54 +0000 Subject: Make redirects behave as a NOP wrt the verifiability of fetches. Apparently, the interweb depends on this. svn path=/trunk/netsurf/; revision=6542 --- content/fetch.c | 13 +++++++++++++ content/fetch.h | 1 + content/fetchcache.c | 22 ++++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/content/fetch.c b/content/fetch.c index 779e1f12d..a421f621a 100644 --- a/content/fetch.c +++ b/content/fetch.c @@ -585,6 +585,19 @@ const char *fetch_get_parent_url(struct fetch *fetch) return fetch->verifiable ? fetch->url : fetch->parent_fetch_url; } +/** + * Determine if a fetch was verifiable + * + * \param fetch Fetch to consider + * \return Verifiable status of fetch + */ +bool fetch_get_verifiable(struct fetch *fetch) +{ + assert(fetch); + + return fetch->verifiable; +} + void fetch_send_callback(fetch_msg msg, struct fetch *fetch, const void *data, unsigned long size) diff --git a/content/fetch.h b/content/fetch.h index 6bf83636d..a91e75662 100644 --- a/content/fetch.h +++ b/content/fetch.h @@ -85,6 +85,7 @@ void fetch_change_callback(struct fetch *fetch, long fetch_http_code(struct fetch *fetch); const char *fetch_get_referer(struct fetch *fetch); const char *fetch_get_parent_url(struct fetch *fetch); +bool fetch_get_verifiable(struct fetch *fetch); /* API for fetchers themselves */ diff --git a/content/fetchcache.c b/content/fetchcache.c index 36e6a289f..51875e138 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -937,6 +937,7 @@ void fetchcache_redirect(struct content *c, const void *data, const char *ref; const char *parent; bool can_fetch; + bool parent_was_verifiable; union content_msg_data msg_data; url_func_result result; @@ -948,6 +949,7 @@ void fetchcache_redirect(struct content *c, const void *data, http_code = fetch_http_code(c->fetch); ref = fetch_get_referer(c->fetch); parent = fetch_get_parent_url(c->fetch); + parent_was_verifiable = fetch_get_verifiable(c->fetch); /* Ensure a redirect happened */ assert(300 <= http_code && http_code <= 399); @@ -1083,9 +1085,25 @@ void fetchcache_redirect(struct content *c, const void *data, if (can_fetch) { /* Get replacement content -- HTTP GET request */ + + /* A note about fetch verifiability: according to + * both RFC2109 and 2965, redirects result in an + * unverifiable fetch and thus cookies must be handled + * differently. Unfortunately, however, other browsers + * do not adhere to this rule and just process cookies + * as per normal in this case. Websites have come to + * depend upon this "feature", so we must do something + * which approximates the appropriate behaviour. + * + * Therefore, a redirected fetch will preserve the + * verifiability of the origin fetch. Thus, fetches + * for embedded objects will remain unverifiable, + * as expected. + */ replacement = fetchcache(url, callback, p1, p2, c->width, c->height, c->no_error_pages, - NULL, NULL, false, c->download); + NULL, NULL, parent_was_verifiable, + c->download); if (!replacement) { msg_data.error = messages_get("BadRedirect"); content_broadcast(c, CONTENT_MSG_ERROR, @@ -1109,7 +1127,7 @@ void fetchcache_redirect(struct content *c, const void *data, /* Start fetching the replacement content */ fetchcache_go(replacement, referer, callback, p1, p2, c->width, c->height, NULL, NULL, - false, parent_url); + parent_was_verifiable, parent_url); } } -- cgit v1.2.3