[balsa] Use "resource-request-starting" signal to handle cid: requests
- From: Peter Bloomfield <PeterB src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [balsa] Use "resource-request-starting" signal to handle cid: requests
- Date: Tue, 29 Dec 2009 18:22:57 +0000 (UTC)
commit 3c17e23f39581c6609d3510050939abdbaf4255b
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Tue Dec 29 13:21:02 2009 -0500
Use "resource-request-starting" signal to handle cid: requests
libbalsa/html.c | 194 ++++++++++++++-----------------------------------------
1 files changed, 48 insertions(+), 146 deletions(-)
---
diff --git a/libbalsa/html.c b/libbalsa/html.c
index 8b599c2..b755364 100644
--- a/libbalsa/html.c
+++ b/libbalsa/html.c
@@ -1,7 +1,7 @@
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/* Balsa E-Mail Client
*
- * Copyright (C) 1997-2003 Stuart Parmenter and others,
+ * Copyright (C) 1997-2009 Stuart Parmenter and others,
* See the file AUTHORS for a list.
*
* This program is free software; you can redistribute it and/or modify
@@ -54,30 +54,9 @@
/*
* Experimental support for WebKit.
- *
- * Issues as of WebKit 1.0.3:
- *
- * (a) no mechanism for satisfying "cid:" requests;
- * (b) no assurance that remote servers named in "src=" attributes
- * will not be contacted.
- *
- * GtkHtml-{2,3} resolve both issues with the "url-requested" or
- * "request-url" signal; WebKit does not have one. We turn off its
- * "auto-load-images" setting, which seems to mean that <img src="...">
- * tags are ignored. However, that is apparently intended to save
- * bandwidth rather than to protect privacy. The WebView attempts to
- * contact the server named in <frame src="...">, but we detect it
- * because of the new frame, and block it; whether "src=" attributes on
- * other tags are followed is unknown.
- *
- * We do disable scripts, so the server in a <script src="..."> should
- * not be contacted.
- *
- * https://bugs.webkit.org/show_bug.cgi?id=17147 discusses these issues.
*/
#include <webkit/webkit.h>
-#include "mime-stream-shared.h"
typedef struct {
WebKitWebView *web_view;
@@ -90,6 +69,11 @@ typedef struct {
#endif /* !WEBKIT_CHECK_VERSION(1, 12, 0) */
} LibBalsaWebKitInfo;
+/*
+ * Callback for the "hovering-over-link" signal
+ *
+ * Pass the URI to the handler set by the caller
+ */
static void
lbh_hovering_over_link_cb(GtkWidget * web_view,
const gchar * title,
@@ -119,6 +103,13 @@ lbh_size_request_cb(GtkWidget * widget,
}
#endif /* !WEBKIT_CHECK_VERSION(1, 12, 0) */
+/*
+ * Callback for the "navigation-policy-decision-requested" signal
+ *
+ * If the reason is that the user clicked on a link, pass the URI to to
+ * the handler set by the caller; slightly complicated by links that
+ * are supposed to open in their own windows.
+ */
static gboolean
lbh_navigation_policy_decision_requested_cb(WebKitWebView * web_view,
WebKitWebFrame * frame,
@@ -157,6 +148,39 @@ lbh_navigation_policy_decision_requested_cb(WebKitWebView * web_view
}
/*
+ * Callback for the "resource-request-starting" signal
+ *
+ * Here we get to disallow all requests involving remote servers, and to
+ * handle cid: requests by replacing them with file: requests.
+ */
+static void
+lbh_resource_request_starting_cb(WebKitWebView * web_view,
+ WebKitWebFrame * frame,
+ WebKitWebResource * resource,
+ WebKitNetworkRequest * request,
+ WebKitNetworkResponse * response,
+ gpointer data)
+{
+ const gchar *uri = webkit_network_request_get_uri(request);
+
+ if (g_ascii_strncasecmp(uri, "cid:", 4)) {
+ /* Not a "cid:" request: disable loading. */
+ webkit_network_request_set_uri(request, "about:blank");
+ } else {
+ LibBalsaMessage *message = data;
+ LibBalsaMessageBody *body;
+
+ /* Replace "cid:" request with a "file:" request. */
+ if ((body = libbalsa_message_get_part_by_id(message, uri + 4))
+ && libbalsa_message_body_save_temporary(body, NULL)) {
+ gchar *file_uri = g_strconcat("file://", body->temp_filename, NULL);
+ webkit_network_request_set_uri(request, file_uri);
+ g_free(file_uri);
+ }
+ }
+}
+
+/*
* To handle a clicked link that is supposed to open in a new window
* (specifically, has the attribute 'target="_blank"'), we must allow
* WebKit to open one, but we destroy it after it has emitted the
@@ -206,110 +230,6 @@ lbh_create_web_view_cb(WebKitWebView * web_view,
return WEBKIT_WEB_VIEW(widget);
}
-static gchar *
-lbh_filter_src(const gchar *text, LibBalsaMessage * message)
-{
- GString *string = g_string_sized_new(strlen(text));
- const gchar *start, *left;
-
- start = text;
- while ((left = strchr(start, '<'))) {
- const gchar *right;
-
- if (!(right = strchr(left, '>')))
- break;
-
- for (left++; left < right - 5; left++)
- if (!g_ascii_strncasecmp(left, "src=\"", 5))
- break;
- if (left >= right - 5) {
- g_string_append_len(string, start, right - start);
- start = right;
- continue;
- }
- left = left + 5;
-
- g_string_append_len(string, start, left - start);
- start = left;
-
- if (!g_ascii_strncasecmp(start, "cid:", 4)) {
-#ifdef WEBKITWEBVIEW_ALLOWS_FILE_URIS
- /* replace with a file URI: */
- g_string_append(string, "file://");
- g_string_append(string, libbalsa_message_get_tempdir(message));
- if (string->str[string->len - 1] != G_DIR_SEPARATOR)
- g_string_append_c(string, G_DIR_SEPARATOR);
- start += 4; /* skip over "cid:" */
-#else /* WEBKITWEBVIEW_ALLOWS_FILE_URIS */
- /* replace with a data URI: */
- const gchar *dquote;
- gchar *content_id;
- LibBalsaMessageBody *body;
- gchar *mime_type;
- GMimeStream *stream;
- GError *err = NULL;
- GMimeStream *stream_filter;
- GMimeFilter *filter;
- GMimeStream *stream_mem;
- GByteArray *byte_array;
-
- if (!(dquote = strchr(start, '"')))
- break;
-
- start += 4; /* skip over "cid:" */
- content_id = g_strndup(start, dquote - start);
- body = libbalsa_message_get_part_by_id(message, content_id);
- g_free(content_id);
- if (!body)
- break;
-
- mime_type = libbalsa_message_body_get_mime_type(body);
- g_string_append_printf(string, "data:%s;base64,\n", mime_type);
- g_free(mime_type);
-
- stream = libbalsa_message_body_get_stream(body, &err);
- if (err) {
- g_message("%s: %s", __func__, err->message);
- g_error_free(err);
- break;
- }
-
- stream_filter = g_mime_stream_filter_new(stream);
- filter = g_mime_filter_basic_new(GMIME_CONTENT_ENCODING_BASE64, TRUE);
- g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), filter);
- g_object_unref(filter);
-
- stream_mem = g_mime_stream_mem_new();
- libbalsa_mime_stream_shared_lock(stream);
- g_mime_stream_reset(stream);
- g_mime_stream_write_to_stream(stream_filter, stream_mem);
- libbalsa_mime_stream_shared_unlock(stream);
- g_object_unref(stream);
- g_object_unref(stream_filter);
-
- byte_array = g_mime_stream_mem_get_byte_array(GMIME_STREAM_MEM(stream_mem));
- g_mime_stream_mem_set_owner(GMIME_STREAM_MEM(stream_mem), FALSE);
- g_object_unref(stream_mem);
-
- g_string_append_len(string, (gchar *) byte_array->data, byte_array->len);
-#if GLIB_CHECK_VERSION(2, 22, 0)
- g_byte_array_unref(byte_array);
-#else /* GLIB_CHECK_VERSION(2, 22, 0) */
- g_byte_array_free(byte_array, TRUE);
-#endif /* GLIB_CHECK_VERSION(2, 22, 0) */
-
- start = dquote;
-#endif /* WEBKITWEBVIEW_ALLOWS_FILE_URIS */
- } else {
- /* break all other URIs: */
- g_string_append(string, "null");
- }
- }
- g_string_append(string, start);
-
- return g_string_free(string, FALSE);
-}
-
/* Create a new WebKitWebView widget:
* text the HTML source;
* len length of text;
@@ -333,7 +253,6 @@ libbalsa_html_new(const gchar * text,
GtkWidget *widget;
WebKitWebView *web_view;
LibBalsaWebKitInfo *info;
- gchar *save_me = NULL;
widget = webkit_web_view_new();
@@ -345,9 +264,6 @@ libbalsa_html_new(const gchar * text,
g_object_set(webkit_web_view_get_settings(web_view),
"enable-scripts", FALSE,
"enable-plugins", FALSE,
-#ifdef WEBKITWEBVIEW_ALLOWS_FILE_URIS
- "enable-universal-access-from-file-uris", TRUE,
-#endif /* WEBKITWEBVIEW_ALLOWS_FILE_URIS */
NULL);
#if !WEBKIT_CHECK_VERSION(1, 12, 0)
@@ -370,30 +286,16 @@ libbalsa_html_new(const gchar * text,
g_signal_connect(web_view, "navigation-policy-decision-requested",
G_CALLBACK
(lbh_navigation_policy_decision_requested_cb), info);
+ g_signal_connect(web_view, "resource-request-starting",
+ G_CALLBACK(lbh_resource_request_starting_cb), message);
g_signal_connect(web_view, "create-web-view",
G_CALLBACK(lbh_create_web_view_cb), info);
g_signal_connect(web_view, "load-progress-changed",
G_CALLBACK(gtk_widget_queue_resize), NULL);
-#ifdef WEBKITWEBVIEW_ALLOWS_FILE_URIS
- if (libbalsa_message_save_parts_by_id(message, NULL))
- text = save_me = lbh_filter_src(text, message);
- else
- g_object_set(webkit_web_view_get_settings(web_view),
- "auto-load-images", FALSE,
- NULL);
-#else /* WEBKITWEBVIEW_ALLOWS_FILE_URIS */
- if (libbalsa_message_has_cid_part(message))
- text = save_me = lbh_filter_src(text, message);
- else
- g_object_set(webkit_web_view_get_settings(web_view),
- "auto-load-images", FALSE,
- NULL);
-#endif /* WEBKITWEBVIEW_ALLOWS_FILE_URIS */
webkit_web_view_load_string(web_view, text, "text/html", charset,
NULL);
- g_free(save_me);
return widget;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]