summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2010-04-04 17:17:24 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2010-04-04 17:17:24 +0000
commit69f02e926f746b31500f46572d606fdc482ff0cb (patch)
tree438e52c0db585579cb75afcb0e3d59c9a777b4cb
parent487d4c3ae384fafded41ee0b4203bd82f5268b57 (diff)
downloadnetsurf-69f02e926f746b31500f46572d606fdc482ff0cb.tar.gz
netsurf-69f02e926f746b31500f46572d606fdc482ff0cb.tar.bz2
Make the high-level cache drop contents of unacceptable type on the floor.
svn path=/trunk/netsurf/; revision=10238
-rw-r--r--content/hlcache.c78
-rw-r--r--content/hlcache.h22
-rw-r--r--css/css.c4
-rw-r--r--desktop/browser.c3
-rw-r--r--desktop/searchweb.c11
-rw-r--r--render/favicon.c33
-rw-r--r--render/html.c11
7 files changed, 123 insertions, 39 deletions
diff --git a/content/hlcache.c b/content/hlcache.c
index 05a416b0b..298fe8151 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -26,7 +26,9 @@
#include "content/content.h"
#include "content/hlcache.h"
+#include "utils/http.h"
#include "utils/log.h"
+#include "utils/messages.h"
#include "utils/url.h"
typedef struct hlcache_entry hlcache_entry;
@@ -38,6 +40,8 @@ struct hlcache_retrieval_ctx {
hlcache_handle *handle; /**< High-level handle for object */
+ const content_type *accepted_types; /**< Accepted types, or NULL */
+
hlcache_child_context child; /**< Child context */
};
@@ -62,6 +66,8 @@ static hlcache_entry *hlcache_content_list;
static nserror hlcache_llcache_callback(llcache_handle *handle,
const llcache_event *event, void *pw);
+static bool hlcache_type_is_acceptable(llcache_handle *llcache,
+ const content_type *accepted_types);
static nserror hlcache_find_content(hlcache_retrieval_ctx *ctx);
static void hlcache_content_callback(struct content *c,
content_msg msg, union content_msg_data data, void *pw);
@@ -74,7 +80,8 @@ static void hlcache_content_callback(struct content *c,
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
const char *referer, llcache_post_data *post,
hlcache_handle_callback cb, void *pw,
- hlcache_child_context *child, hlcache_handle **result)
+ hlcache_child_context *child,
+ const content_type *accepted_types, hlcache_handle **result)
{
hlcache_retrieval_ctx *ctx;
nserror error;
@@ -97,6 +104,8 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
ctx->child.quirks = child->quirks;
}
+ ctx->accepted_types = accepted_types;
+
ctx->handle->cb = cb;
ctx->handle->pw = pw;
@@ -218,9 +227,26 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
switch (event->type) {
case LLCACHE_EVENT_HAD_HEADERS:
- error = hlcache_find_content(ctx);
- if (error != NSERROR_OK)
- return error;
+ if (hlcache_type_is_acceptable(handle, ctx->accepted_types)) {
+ error = hlcache_find_content(ctx);
+ if (error != NSERROR_OK)
+ return error;
+ } else {
+ /* Unacceptable type: abort fetch and report error */
+ llcache_handle_abort(handle);
+ llcache_handle_release(handle);
+
+ if (ctx->handle->cb != NULL) {
+ hlcache_event hlevent;
+
+ hlevent.type = CONTENT_MSG_ERROR;
+ hlevent.data.error = messages_get("BadType");
+
+ ctx->handle->cb(ctx->handle, &hlevent,
+ ctx->handle->pw);
+ }
+ }
+
/* No longer require retrieval context */
free(ctx);
break;
@@ -247,6 +273,50 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
}
/**
+ * Determine if the type of a low-level cache object is acceptable
+ *
+ * \param llcache Low-level cache object to consider
+ * \param accepted_types Array of acceptable types, or NULL for any
+ * \return True if the type is acceptable, false otherwise
+ */
+bool hlcache_type_is_acceptable(llcache_handle *llcache,
+ const content_type *accepted_types)
+{
+ const char *content_type_header;
+ char *mime_type;
+ http_parameter *params;
+ content_type type;
+ nserror error;
+
+ if (accepted_types == NULL)
+ return true;
+
+ content_type_header =
+ llcache_handle_get_header(llcache, "Content-Type");
+ if (content_type_header == NULL)
+ content_type_header = "text/plain";
+
+ error = http_parse_content_type(content_type_header, &mime_type,
+ &params);
+ if (error != NSERROR_OK)
+ return false;
+
+ type = content_lookup(mime_type);
+
+ free(mime_type);
+ http_parameter_list_destroy(params);
+
+ while (*accepted_types != CONTENT_UNKNOWN) {
+ if (*accepted_types == type)
+ break;
+
+ accepted_types++;
+ }
+
+ return *accepted_types == type;
+}
+
+/**
* Find a content for the high-level cache handle
*
* \param ctx High-level cache retrieval context
diff --git a/content/hlcache.h b/content/hlcache.h
index 5ef42a301..1208b15c4 100644
--- a/content/hlcache.h
+++ b/content/hlcache.h
@@ -56,20 +56,23 @@ typedef nserror (*hlcache_handle_callback)(hlcache_handle *handle,
/**
* Retrieve a high-level cache handle for an object
*
- * \param url URL of the object to retrieve handle for
- * \param flags Object retrieval flags
- * \param referer Referring URL, or NULL if none
- * \param post POST data, or NULL for a GET request
- * \param cb Callback to handle object events
- * \param pw Pointer to client-specific data for callback
- * \param child Child retrieval context, or NULL for top-level content
- * \param result Pointer to location to recieve cache handle
+ * \param url URL of the object to retrieve handle for
+ * \param flags Object retrieval flags
+ * \param referer Referring URL, or NULL if none
+ * \param post POST data, or NULL for a GET request
+ * \param cb Callback to handle object events
+ * \param pw Pointer to client-specific data for callback
+ * \param child Child retrieval context, or NULL for top-level content
+ * \param accepted_types Array of acceptable content types, or NULL for any
+ * \param result Pointer to location to recieve cache handle
* \return NSERROR_OK on success, appropriate error otherwise
*
* Child contents are keyed on the tuple < URL, quirks >.
* The quirks field is ignored for child contents whose behaviour is not
* affected by quirks mode.
*
+ * The \a accepted_types array must be terminated with CONTENT_UNKNOWN
+ *
* \todo The above rules should be encoded in the handler_map.
*
* \todo Is there any way to sensibly reduce the number of parameters here?
@@ -77,7 +80,8 @@ typedef nserror (*hlcache_handle_callback)(hlcache_handle *handle,
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
const char *referer, llcache_post_data *post,
hlcache_handle_callback cb, void *pw,
- hlcache_child_context *child, hlcache_handle **result);
+ hlcache_child_context *child,
+ const content_type *accepted_types, hlcache_handle **result);
/**
* Release a high-level cache handle
diff --git a/css/css.c b/css/css.c
index ef38d76aa..1bbbfe608 100644
--- a/css/css.c
+++ b/css/css.c
@@ -200,6 +200,7 @@ bool nscss_convert(struct content *c)
*/
css_error nscss_convert_css_data(struct content_css_data *c)
{
+ static const content_type accept[] = { CONTENT_CSS, CONTENT_UNKNOWN };
const char *referer;
uint32_t i = 0;
css_error error;
@@ -252,7 +253,8 @@ css_error nscss_convert_css_data(struct content_css_data *c)
c->imports[c->import_count].media = media;
nerror = hlcache_handle_retrieve(lwc_string_data(uri),
0, referer, NULL, nscss_import, c,
- &child, &c->imports[c->import_count++].c);
+ &child, accept,
+ &c->imports[c->import_count++].c);
if (error != NSERROR_OK) {
return CSS_NOMEM;
}
diff --git a/desktop/browser.c b/desktop/browser.c
index 70d6b8cf4..e1b071fdb 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -409,7 +409,8 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
error = hlcache_handle_retrieve(url2, 0, referer,
fetch_is_post ? &post : NULL,
browser_window_callback, bw,
- parent != NULL ? &child : NULL, &c);
+ parent != NULL ? &child : NULL,
+ NULL, &c);
if (error == NSERROR_NO_FETCH_HANDLER) {
gui_launch_url(url2);
free(url2);
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index aa993b6a8..89f86ed93 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -206,6 +206,12 @@ char *search_web_get_url(const char *encsearchterm)
void search_web_retrieve_ico(bool localdefault)
{
+ static const content_type accept[] = {
+#ifdef WITH_BMP
+ CONTENT_ICO,
+#endif
+ CONTENT_UNKNOWN
+ };
char *url;
nserror error;
@@ -230,7 +236,8 @@ void search_web_retrieve_ico(bool localdefault)
}
error = hlcache_handle_retrieve(url, 0, NULL, NULL,
- search_web_ico_callback, NULL, NULL, &search_ico);
+ search_web_ico_callback, NULL, NULL, accept,
+ &search_ico);
if (error != NSERROR_OK)
search_ico = NULL;
@@ -269,6 +276,8 @@ nserror search_web_ico_callback(hlcache_handle *ico,
} else
#endif
{
+ hlcache_handle_release(ico);
+ search_ico = NULL;
search_web_retrieve_ico(true);
}
break;
diff --git a/render/favicon.c b/render/favicon.c
index 06ff0b94f..d1eaaacdd 100644
--- a/render/favicon.c
+++ b/render/favicon.c
@@ -148,6 +148,18 @@ char *favicon_get_icon_ref(struct content *c, xmlNode *html)
bool favicon_get_icon(struct content *c, xmlNode *html)
{
+ static const content_type permitted_types[] = {
+#ifdef WITH_BMP
+ CONTENT_ICO,
+#endif
+#if defined(WITH_MNG) || defined(WITH_PNG)
+ CONTENT_PNG,
+#endif
+#ifdef WITH_GIF
+ CONTENT_GIF,
+#endif
+ CONTENT_UNKNOWN
+ };
char *url;
nserror error;
@@ -157,7 +169,7 @@ bool favicon_get_icon(struct content *c, xmlNode *html)
error = hlcache_handle_retrieve(url, LLCACHE_RETRIEVE_NO_ERROR_PAGES,
content__get_url(c), NULL, favicon_callback, c, NULL,
- &c->data.html.favicon);
+ permitted_types, &c->data.html.favicon);
free(url);
@@ -171,29 +183,12 @@ bool favicon_get_icon(struct content *c, xmlNode *html)
nserror favicon_callback(hlcache_handle *icon,
const hlcache_event *event, void *pw)
{
- static const content_type permitted_types[] = {
-#ifdef WITH_BMP
- CONTENT_ICO,
-#endif
-#if defined(WITH_MNG) || defined(WITH_PNG)
- CONTENT_PNG,
-#endif
-#ifdef WITH_GIF
- CONTENT_GIF,
-#endif
- CONTENT_UNKNOWN
- };
struct content *c = pw;
- const content_type *type;
switch (event->type) {
case CONTENT_MSG_LOADING:
/* check that the favicon is really a correct image type */
- for (type = permitted_types; *type != CONTENT_UNKNOWN; type++)
- if (content_get_type(icon) == *type)
- break;
-
- if (*type == CONTENT_UNKNOWN) {
+ if (content_get_type(icon) == CONTENT_UNKNOWN) {
union content_msg_data msg_data;
LOG(("%s is not a favicon", content_get_url(icon)));
diff --git a/render/html.c b/render/html.c
index 2ead62fc3..f50146d95 100644
--- a/render/html.c
+++ b/render/html.c
@@ -783,6 +783,7 @@ bool html_meta_refresh(struct content *c, xmlNode *head)
bool html_find_stylesheets(struct content *c, xmlNode *html)
{
+ static const content_type accept[] = { CONTENT_CSS, CONTENT_UNKNOWN };
xmlNode *node;
char *rel, *type, *media, *href, *url, *url2;
unsigned int i = STYLESHEET_START;
@@ -819,7 +820,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
ns_error = hlcache_handle_retrieve(default_stylesheet_url, 0,
content__get_url(c), NULL,
- html_convert_css_callback, c, &child,
+ html_convert_css_callback, c, &child, accept,
&c->data.html.stylesheets[
STYLESHEET_BASE].data.external);
if (ns_error != NSERROR_OK)
@@ -830,7 +831,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
if (c->data.html.quirks == BINDING_QUIRKS_MODE_FULL) {
ns_error = hlcache_handle_retrieve(quirks_stylesheet_url, 0,
content__get_url(c), NULL,
- html_convert_css_callback, c, &child,
+ html_convert_css_callback, c, &child, accept,
&c->data.html.stylesheets[
STYLESHEET_QUIRKS].data.external);
if (ns_error != NSERROR_OK)
@@ -842,7 +843,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
if (option_block_ads) {
ns_error = hlcache_handle_retrieve(adblock_stylesheet_url, 0,
content__get_url(c), NULL,
- html_convert_css_callback, c, &child,
+ html_convert_css_callback, c, &child, accept,
&c->data.html.stylesheets[
STYLESHEET_ADBLOCK].data.external);
if (ns_error != NSERROR_OK)
@@ -951,6 +952,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
ns_error = hlcache_handle_retrieve(url2, 0,
content__get_url(c), NULL,
html_convert_css_callback, c, &child,
+ accept,
&c->data.html.stylesheets[i].
data.external);
@@ -1246,7 +1248,7 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
}
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
- html_object_callback, c, &child,
+ html_object_callback, c, &child, permitted_types,
&c_fetch);
/* No longer need normalized url */
@@ -1313,6 +1315,7 @@ bool html_replace_object(struct content *c, unsigned int i, const char *url)
/* initialise fetch */
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
html_object_callback, c, &child,
+ c->data.html.object[i].permitted_types,
&c_fetch);
free(url2);