[balsa] Handle cid: URLs
- From: Peter Bloomfield <PeterB src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [balsa] Handle cid: URLs
- Date: Sun, 27 Dec 2009 01:24:05 +0000 (UTC)
commit d1822c339602973c645894e5e2eadcab94326805
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Sat Dec 26 20:23:23 2009 -0500
Handle cid: URLs
ChangeLog | 10 +++-
libbalsa/html.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 141 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1bc2ed4..5de718e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,17 @@
2009-12-26 Peter Bloomfield
- * libbalsa/message.h: add tempdir member; new methods.
+ * libbalsa/html.c (lbh_filter_src), (libbalsa_html_new),
+ (libbalsa_html_url_requested): implement two ways of handling
+ cid: URLs in WebKitwebView.
+
+2009-12-26 Peter Bloomfield
+
+ * libbalsa/message.h: add tempdir member and new methods.
* libbalsa/message.c (libbalsa_message_finalize),
(libbalsa_message_get_part_by_id),
(libbalsa_message_save_parts_by_id),
(libbalsa_message_has_cid_part), (libbalsa_message_get_tempdir):
- implement them.
+ implement and use them.
2009-12-26 Peter Bloomfield
diff --git a/libbalsa/html.c b/libbalsa/html.c
index ecbe65b..8b599c2 100644
--- a/libbalsa/html.c
+++ b/libbalsa/html.c
@@ -77,6 +77,7 @@
*/
#include <webkit/webkit.h>
+#include "mime-stream-shared.h"
typedef struct {
WebKitWebView *web_view;
@@ -205,6 +206,110 @@ 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;
@@ -220,13 +325,15 @@ GtkWidget *
libbalsa_html_new(const gchar * text,
size_t len,
const gchar * charset,
- gpointer message,
+ gpointer msg,
LibBalsaHtmlCallback hover_cb,
LibBalsaHtmlCallback clicked_cb)
{
+ LibBalsaMessage *message = LIBBALSA_MESSAGE(msg);
GtkWidget *widget;
WebKitWebView *web_view;
LibBalsaWebKitInfo *info;
+ gchar *save_me = NULL;
widget = webkit_web_view_new();
@@ -236,9 +343,11 @@ libbalsa_html_new(const gchar * text,
g_object_weak_ref(G_OBJECT(web_view), (GWeakNotify) g_free, info);
g_object_set(webkit_web_view_get_settings(web_view),
- "auto-load-images", FALSE,
"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)
@@ -267,8 +376,24 @@ libbalsa_html_new(const gchar * text,
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;
}
@@ -797,24 +922,27 @@ static gboolean
libbalsa_html_url_requested(GtkWidget * html, const gchar * url,
gpointer stream, LibBalsaMessage * msg)
{
+ LibBalsaMessageBody *body;
GMimeStream *mime_stream;
if (strncmp(url, "cid:", 4)) {
/* printf("non-local URL request ignored: %s\n", url); */
return FALSE;
}
- if ((mime_stream =
+ if ((body =
libbalsa_message_get_part_by_id(msg, url + 4)) == NULL) {
gchar *s = g_strconcat("<", url + 4, ">", NULL);
if (s == NULL)
return FALSE;
- mime_stream = libbalsa_message_get_part_by_id(msg, s);
+ body = libbalsa_message_get_part_by_id(msg, s);
g_free(s);
- if (mime_stream == NULL)
+ if (body == NULL)
return FALSE;
}
+ if (!(mime_stream = libbalsa_message_body_get_stream(body, NULL)))
+ return FALSE;
libbalsa_mailbox_lock_store(msg->mailbox);
g_mime_stream_reset(mime_stream);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]