summaryrefslogtreecommitdiff
path: root/content/fetchcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'content/fetchcache.c')
-rw-r--r--content/fetchcache.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/content/fetchcache.c b/content/fetchcache.c
index e11c6a765..b6b17a618 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -730,7 +730,9 @@ void fetchcache_notmodified(struct content *c, const void *data)
/* No cached content, so unconditionally refetch */
struct content_user *u;
const char *ref = fetch_get_referer(c->fetch);
+ const char *parent = fetch_get_parent_url(c->fetch);
char *referer = NULL;
+ char *parent_url = NULL;
if (ref) {
referer = strdup(ref);
@@ -744,6 +746,19 @@ void fetchcache_notmodified(struct content *c, const void *data)
}
}
+ if (parent) {
+ parent_url = strdup(parent);
+ if (!parent_url) {
+ c->type = CONTENT_UNKNOWN;
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR,
+ msg_data);
+ free(referer);
+ return;
+ }
+ }
+
fetch_abort(c->fetch);
c->fetch = 0;
@@ -754,9 +769,10 @@ void fetchcache_notmodified(struct content *c, const void *data)
for (u = c->user_list->next; u; u = u->next) {
fetchcache_go(c, referer, u->callback, u->p1, u->p2,
c->width, c->height, 0, 0,
- false, ref ? referer : c->url);
+ false, parent_url);
}
+ free(parent_url);
free(referer);
}
}
@@ -769,9 +785,10 @@ void fetchcache_redirect(struct content *c, const void *data,
unsigned long size)
{
char *url, *url1;
- char *referer;
+ char *referer, *parent_url;
long http_code = fetch_http_code(c->fetch);
const char *ref = fetch_get_referer(c->fetch);
+ const char *parent = fetch_get_parent_url(c->fetch);
union content_msg_data msg_data;
url_func_result result;
@@ -783,8 +800,15 @@ void fetchcache_redirect(struct content *c, const void *data,
/* 304 is handled by fetch_notmodified() */
assert(http_code != 304);
- /* Clone referer -- original is destroyed in fetch_abort() */
+ /* Extract fetch details */
+ http_code = fetch_http_code(c->fetch);
+ ref = fetch_get_referer(c->fetch);
+ parent = fetch_get_parent_url(c->fetch);
+
+ /* Clone referer and parent url
+ * originals are destroyed in fetch_abort() */
referer = ref ? strdup(ref) : NULL;
+ parent_url = parent ? strdup(parent) : NULL;
/* set the status to ERROR so that this content is
* destroyed in content_clean() */
@@ -803,6 +827,18 @@ void fetchcache_redirect(struct content *c, const void *data,
return;
}
+ /* Ensure parent url cloning succeeded
+ * _must_ be after content invalidation */
+ if (parent && !parent_url) {
+ LOG(("Failed cloning parent url"));
+
+ msg_data.error = messages_get("BadRedirect");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+
+ free(referer);
+ return;
+ }
+
/** \todo 300, 305, 307
* More specifically:
* + 300 needs to serve up the fetch body to the user
@@ -823,6 +859,7 @@ void fetchcache_redirect(struct content *c, const void *data,
msg_data.error = messages_get("BadRedirect");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ free(parent_url);
free(referer);
return;
}
@@ -835,6 +872,7 @@ void fetchcache_redirect(struct content *c, const void *data,
msg_data.error = messages_get("BadRedirect");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ free(parent_url);
free(referer);
return;
}
@@ -848,6 +886,7 @@ void fetchcache_redirect(struct content *c, const void *data,
msg_data.error = messages_get("BadRedirect");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ free(parent_url);
free(referer);
return;
}
@@ -860,6 +899,7 @@ void fetchcache_redirect(struct content *c, const void *data,
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
free(url1);
+ free(parent_url);
free(referer);
return;
}
@@ -892,6 +932,7 @@ void fetchcache_redirect(struct content *c, const void *data,
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
free(url);
+ free(parent_url);
free(referer);
return;
}
@@ -905,11 +946,12 @@ 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, referer ? referer : c->url);
+ false, parent_url);
}
/* Clean up */
free(url);
+ free(parent_url);
free(referer);
}