summaryrefslogtreecommitdiff
path: root/content/fetchcache.c
diff options
context:
space:
mode:
authorJohn Tytgat <joty@netsurf-browser.org>2009-08-04 23:02:23 +0000
committerJohn Tytgat <joty@netsurf-browser.org>2009-08-04 23:02:23 +0000
commit2261b616f61e6701b381d6e363e14431f321f843 (patch)
treef80512b595b5a9dbc84e25102270b23a724bd103 /content/fetchcache.c
parent83acae8e1f41b59e32700944b996ae1e4509c07b (diff)
downloadnetsurf-2261b616f61e6701b381d6e363e14431f321f843.tar.gz
netsurf-2261b616f61e6701b381d6e363e14431f321f843.tar.bz2
- content/urldb.c(auth_data): Removed;
(prot_space_data): Added, it lives linked in the leaf host_part struct and together with its scheme and port (which defins canonical root url) and realm this defines a protection space. (path_data): Removed auth_data field and replaced by a prot_space_data pointer. (host_part::prot_space): Added linked list of protection space data structs. (urldb_get_auth_details): Given an URL fetch fetches its auth. (urldb_set_auth_details): Creates or updates the contents of a protection space to which given URL belongs. (urldb_destroy_host_tree): Delete protection data space structures using urldb_destroy_prot_space. (urldb_destroy_prot_space): Added. - content/urldb.h(urldb_get_auth_details): Added realm parameter. - content/fetchers/fetch_curl.c(fetch_curl_set_options): Update urldb_get_auth_details call (we don't know realm at this point). - content/fetchcache.c(fetchcache_callback, fetchcache_auth): At FETCH_AUTH, use realm to determine if we really don't know auth data and if so, refetch content. - content/content.h(struct content): Add content::tried_with_auth. - content/content.c(content_create): Initialize content::tried_with_auth. - riscos/401login.c(ro_gui_401login_open): Show known authentication data in dialogue so user can see what was wrong with it and correct it. Solves bug #2830829. svn path=/trunk/netsurf/; revision=9045
Diffstat (limited to 'content/fetchcache.c')
-rw-r--r--content/fetchcache.c98
1 files changed, 90 insertions, 8 deletions
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 71e39e4fa..3c43e1f60 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -1,5 +1,6 @@
/*
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
+ * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -37,6 +38,7 @@
#include "content/content.h"
#include "content/fetchcache.h"
#include "content/fetch.h"
+#include "content/urldb.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/talloc.h"
@@ -58,6 +60,7 @@ static void fetchcache_cache_clone(struct content *c,
static void fetchcache_notmodified(struct content *c, const void *data);
static void fetchcache_redirect(struct content *c, const void *data,
unsigned long size);
+static void fetchcache_auth(struct content *c, const char *realm);
/**
@@ -516,14 +519,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const void *data,
break;
case FETCH_AUTH:
- /* data -> string containing the Realm */
- LOG(("FETCH_AUTH, '%s'", (const char *)data));
- c->fetch = 0;
- msg_data.auth_realm = data;
- content_broadcast(c, CONTENT_MSG_AUTH, msg_data);
- /* set the status to ERROR so that the content is
- * destroyed in content_clean() */
- c->status = CONTENT_STATUS_ERROR;
+ fetchcache_auth(c, data);
break;
case FETCH_CERT_ERR:
@@ -1136,6 +1132,92 @@ void fetchcache_redirect(struct content *c, const void *data,
free(referer);
}
+/**
+ * Authentication callback handler
+ */
+
+void fetchcache_auth(struct content *c, const char *realm)
+{
+ char *referer;
+ const char *ref;
+ const char *auth;
+ struct content *parent;
+ bool parent_was_verifiable;
+ union content_msg_data msg_data;
+ char *headers = NULL;
+
+ /* Preconditions */
+ assert(c && realm);
+ assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
+
+ /* Extract fetch details */
+ ref = fetch_get_referer(c->fetch);
+ parent = fetch_get_parent(c->fetch);
+ parent_was_verifiable = fetch_get_verifiable(c->fetch);
+
+ /* Clone referer -- original is destroyed in fetch_abort() */
+ referer = ref ? strdup(ref) : NULL;
+
+ fetch_abort(c->fetch);
+ c->fetch = NULL;
+
+ /* Ensure that referer cloning succeeded
+ * _must_ be after content invalidation */
+ if (ref && !referer) {
+ LOG(("Failed cloning referer"));
+
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.error = messages_get("BadRedirect");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+
+ return;
+ }
+
+ /* Now, see if we've got some auth details */
+ auth = urldb_get_auth_details(c->url, realm);
+
+ if (auth == NULL || c->tried_with_auth) {
+ /* No authentication details or we tried what we had, so ask
+ * our client for them. */
+ c->tried_with_auth = false; /* Allow rety. */
+
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.auth_realm = realm;
+ content_broadcast(c, CONTENT_MSG_AUTH, msg_data);
+
+ return;
+ }
+ /* Flag we're retry fetching with auth data. Will be used to detect
+ * wrong auth data so that we can ask our client for better auth. */
+ c->tried_with_auth = true;
+
+ /* We have authentication details. Fetch with them. */
+ /** \todo all the useful things like headers, POST. */
+ c->fetch = fetch_start(c->url, referer,
+ fetchcache_callback, c,
+ c->no_error_pages,
+ NULL, NULL, parent_was_verifiable,
+ parent, &headers);
+ if (c->fetch == NULL) {
+ char error_message[500];
+
+ LOG(("warning: fetch_start failed"));
+ snprintf(error_message, sizeof error_message,
+ messages_get("InvalidURL"),
+ c->url);
+ if (c->no_error_pages) {
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.error = error_message;
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ } else {
+ fetchcache_error_page(c, error_message);
+ }
+ }
+
+ /* Clean up */
+ free(referer);
+}
+
#ifdef TEST
#include <unistd.h>