summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/fetch.c13
-rw-r--r--content/fetch.h1
-rw-r--r--content/fetchcache.c22
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);
}
}