summaryrefslogtreecommitdiff
path: root/content/fetchcache.c
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2009-12-17 23:55:02 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2009-12-17 23:55:02 +0000
commit355799ce0bbb078237dfc1ae9874bbc5342acbc4 (patch)
tree7ca980c01c0d4d1d55a3b7b15418c95c5618afae /content/fetchcache.c
parent4346b2b62b940182575e6612e46234355afa083c (diff)
downloadnetsurf-355799ce0bbb078237dfc1ae9874bbc5342acbc4.tar.gz
netsurf-355799ce0bbb078237dfc1ae9874bbc5342acbc4.tar.bz2
Merge branches/MarkieB/gtkmain to trunk.
svn path=/trunk/netsurf/; revision=9729
Diffstat (limited to 'content/fetchcache.c')
-rw-r--r--content/fetchcache.c127
1 files changed, 90 insertions, 37 deletions
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 8643cc1a2..87732d49e 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -38,6 +38,8 @@
#include "content/content.h"
#include "content/fetchcache.h"
#include "content/fetch.h"
+#include "desktop/options.h"
+#include "desktop/searchweb.h"
#include "content/urldb.h"
#include "utils/log.h"
#include "utils/messages.h"
@@ -49,17 +51,23 @@
static char error_page[1000];
static regex_t re_content_type;
static void fetchcache_callback(fetch_msg msg, void *p, const void *data,
- unsigned long size);
+ unsigned long size, fetch_error_code errorcode);
static char *fetchcache_parse_type(const char *s, char **params[]);
static void fetchcache_parse_header(struct content *c, const char *data,
size_t size);
-static void fetchcache_error_page(struct content *c, const char *error);
+static void fetchcache_error_page(struct content *c, const char *error,
+ fetch_error_code errorcode);
+static void fetchcache_search_redirect(struct content *c, const char *error);
static void fetchcache_cache_update(struct content *c);
static void fetchcache_cache_clone(struct content *c,
const struct cache_data *data);
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_redirect_common(struct content *c, bool verifiable,
+ const char *url, const char *referer,
+ struct content *parent);
+
static void fetchcache_auth(struct content *c, const char *realm);
@@ -276,7 +284,8 @@ void fetchcache_go(struct content *content, const char *referer,
callback(CONTENT_MSG_ERROR,
content, p1, p2, msg_data);
} else {
- fetchcache_error_page(content, error_message);
+ fetchcache_error_page(content, error_message,
+ FETCH_ERROR_NO_ERROR);
}
return;
@@ -366,7 +375,8 @@ void fetchcache_go(struct content *content, const char *referer,
content_broadcast(content, CONTENT_MSG_ERROR,
msg_data);
} else {
- fetchcache_error_page(content, error_message);
+ fetchcache_error_page(content, error_message,
+ FETCH_ERROR_NO_ERROR);
}
}
@@ -405,7 +415,7 @@ void fetchcache_go(struct content *content, const char *referer,
*/
void fetchcache_callback(fetch_msg msg, void *p, const void *data,
- unsigned long size)
+ unsigned long size, fetch_error_code errorcode)
{
bool res;
struct content *c = p;
@@ -506,7 +516,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const void *data,
msg_data);
} else {
content_reset(c);
- fetchcache_error_page(c, data);
+ fetchcache_error_page(c, data, errorcode);
}
break;
@@ -721,17 +731,29 @@ void fetchcache_parse_header(struct content *c, const char *data,
/**
- * Generate an error page.
- *
+ * Generate an error page. Optionally redirect to web search provider
* \param c empty content to generate the page in
* \param error message to display
*/
-void fetchcache_error_page(struct content *c, const char *error)
+void fetchcache_error_page(struct content *c, const char *error,
+ fetch_error_code errorcode)
{
const char *params[] = { 0 };
int length;
-
+ char *host;
+
+ if (option_search_url_bar) {
+ if (url_host(c->url, &host) != URL_FUNC_OK) {
+ warn_user(messages_get("NoMemory"), 0);
+ } else if ((strcasecmp(host, search_web_provider_host())
+ != 0) && (errorcode ==
+ FETCH_ERROR_COULDNT_RESOLVE_HOST)) {
+ fetchcache_search_redirect(c, error);
+ free(host);
+ return;
+ }
+ }
if ((length = snprintf(error_page, sizeof(error_page),
messages_get("ErrorPage"), error)) < 0)
length = 0;
@@ -746,6 +768,27 @@ void fetchcache_error_page(struct content *c, const char *error)
c->fresh = false;
}
+void fetchcache_search_redirect(struct content *c, const char *error)
+{
+ char *redirurl, *temp;
+
+ /* clear http:// plus trailing / from url, it is already escaped */
+ temp = strdup(c->url + SLEN("http://"));
+ if (temp == NULL) {
+ warn_user(messages_get("NoMemory"), 0);
+ return;
+ }
+ temp[strlen(temp)-1] = '\0';
+ redirurl = search_web_get_url(temp);
+ if (redirurl == NULL) {
+ warn_user(messages_get("NoMemory"), 0);
+ return;
+ }
+
+ fetchcache_redirect_common(c, false, redirurl, NULL, c);
+ free(redirurl);
+ return;
+}
/**
* Update a content's cache state
@@ -930,7 +973,6 @@ void fetchcache_redirect(struct content *c, const void *data,
long http_code;
const char *ref;
struct content *parent;
- bool can_fetch;
bool parent_was_verifiable;
union content_msg_data msg_data;
url_func_result result;
@@ -1056,32 +1098,50 @@ void fetchcache_redirect(struct content *c, const void *data,
}
free(scheme);
-
- /* Determine if we've got a fetch handler for this url */
- can_fetch = fetch_can_fetch(url);
+ fetchcache_redirect_common(c, parent_was_verifiable, url, referer, parent);
+ free(url);
+ free(referer);
+}
+
+/**
+ * common logic from fetchcache_redirect() / fetchcache_search_redirect()
+ * \param c the content param from the original function
+ * \param verifiable parent_was_verifiable [false for search_redirect]
+ * \param url the url being considered; caller retains ownership
+ * \param referer referer [ / NULL particularly for search_redirect]
+ * \param parent parent content [ / c for search_redirect]
+ */
+void fetchcache_redirect_common(struct content *c, bool verifiable,
+ const char *url, const char *referer, struct content *parent)
+{
+ union content_msg_data msg_data;
+ bool can_fetch;
+ /* check there's a fetch handler */
+ can_fetch = fetch_can_fetch(url);
+
/* Process users of this content */
while (c->user_list->next) {
intptr_t p1, p2;
void (*callback)(content_msg msg,
- struct content *c, intptr_t p1,
- intptr_t p2,
- union content_msg_data data);
+ struct content *c, intptr_t p1,
+ intptr_t p2,
+ union content_msg_data data);
struct content *replacement;
-
+
p1 = c->user_list->next->p1;
p2 = c->user_list->next->p2;
callback = c->user_list->next->callback;
-
+
/* If we can't fetch this url, attempt to launch it */
if (!can_fetch) {
msg_data.launch_url = url;
callback(CONTENT_MSG_LAUNCH, c, p1, p2, msg_data);
}
-
+
/* Remove user */
content_remove_user(c, callback, p1, p2);
-
+
if (can_fetch) {
/* Get replacement content -- HTTP GET request */
@@ -1101,37 +1161,29 @@ void fetchcache_redirect(struct content *c, const void *data,
*/
replacement = fetchcache(url, callback, p1, p2,
c->width, c->height, c->no_error_pages,
- NULL, NULL, parent_was_verifiable,
+ NULL, NULL, verifiable,
c->download);
if (!replacement) {
msg_data.error = messages_get("BadRedirect");
content_broadcast(c, CONTENT_MSG_ERROR,
msg_data);
-
- free(url);
- free(referer);
return;
- }
-
+ }
/* Set replacement's redirect count to 1 greater
* than ours */
replacement->redirect_count = c->redirect_count + 1;
-
+
/* Notify user that content has changed */
msg_data.new_url = url;
callback(CONTENT_MSG_NEWPTR, replacement,
- p1, p2, msg_data);
-
+ p1, p2, msg_data);
+
/* Start fetching the replacement content */
fetchcache_go(replacement, referer, callback, p1, p2,
- c->width, c->height, NULL, NULL,
- parent_was_verifiable, parent);
+ c->width, c->height, NULL, NULL,
+ verifiable, parent);
}
}
-
- /* Clean up */
- free(url);
- free(referer);
}
/**
@@ -1218,7 +1270,8 @@ void fetchcache_auth(struct content *c, const char *realm)
msg_data.error = error_message;
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
} else {
- fetchcache_error_page(c, error_message);
+ fetchcache_error_page(c, error_message,
+ FETCH_ERROR_URL);
}
}