[evolution/wip/webkit2] Use former SoupRequest descendants again
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Use former SoupRequest descendants again
- Date: Thu, 24 Mar 2016 17:51:12 +0000 (UTC)
commit 07d1d97e49a9bc486b22f26a3f7d47e8b1c16c71
Author: Milan Crha <mcrha redhat com>
Date: Thu Mar 24 18:50:00 2016 +0100
Use former SoupRequest descendants again
This also fixed contact photo preview in the Contacts view.
e-util/Makefile.am | 2 +
e-util/e-content-request.c | 188 ++++++++++
e-util/e-content-request.h | 93 +++++
e-util/e-file-request.c | 222 +++++--------
e-util/e-file-request.h | 11 +-
e-util/e-misc-utils.c | 16 +
e-util/e-misc-utils.h | 3 +
e-util/e-stock-request.c | 266 +++++++--------
e-util/e-stock-request.h | 11 +-
e-util/e-util.h | 1 +
e-util/e-web-view.c | 292 +++++-----------
e-util/e-web-view.h | 5 +
mail/Makefile.am | 2 +
mail/e-cid-request.c | 140 ++++++++
mail/e-cid-request.h | 62 ++++
mail/e-http-request.c | 319 ++++++------------
mail/e-http-request.h | 12 +-
mail/e-mail-display.c | 829 +------------------------------------------
mail/e-mail-request.c | 455 +++++++++++--------------
mail/e-mail-request.h | 11 +-
shell/main.c | 1 +
21 files changed, 1143 insertions(+), 1798 deletions(-)
---
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index cd49da4..161ef22 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -174,6 +174,7 @@ evolution_util_include_HEADERS = \
e-config.h \
e-conflict-search-selector.h \
e-contact-store.h \
+ e-content-request.h \
e-data-capture.h \
e-dateedit.h \
e-datetime-format.h \
@@ -449,6 +450,7 @@ libevolution_util_la_SOURCES = \
e-config.c \
e-conflict-search-selector.c \
e-contact-store.c \
+ e-content-request.c \
e-data-capture.c \
e-dateedit.c \
e-datetime-format.c \
diff --git a/e-util/e-content-request.c b/e-util/e-content-request.c
new file mode 100644
index 0000000..9448d44
--- /dev/null
+++ b/e-util/e-content-request.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include "e-content-request.h"
+
+G_DEFINE_INTERFACE (EContentRequest, e_content_request, G_TYPE_OBJECT)
+
+static void
+e_content_request_default_init (EContentRequestInterface *iface)
+{
+}
+
+gboolean
+e_content_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
+{
+ EContentRequestInterface *iface;
+
+ g_return_val_if_fail (E_IS_CONTENT_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ iface = E_CONTENT_REQUEST_GET_INTERFACE (request);
+ g_return_val_if_fail (iface != NULL, FALSE);
+ g_return_val_if_fail (iface->can_process_uri != NULL, FALSE);
+
+ return iface->can_process_uri (request, uri);
+}
+
+gboolean
+e_content_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EContentRequestInterface *iface;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (E_IS_CONTENT_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (G_IS_OBJECT (requester), FALSE);
+ g_return_val_if_fail (out_stream != NULL, FALSE);
+ g_return_val_if_fail (out_stream_length != NULL, FALSE);
+ g_return_val_if_fail (out_mime_type != NULL, FALSE);
+
+ iface = E_CONTENT_REQUEST_GET_INTERFACE (request);
+ g_return_val_if_fail (iface != NULL, FALSE);
+ g_return_val_if_fail (iface->process_sync != NULL, FALSE);
+
+ if (!iface->process_sync (request, uri, requester, out_stream, out_stream_length, out_mime_type,
cancellable, &local_error)) {
+ if (!local_error)
+ local_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, g_strerror
(ENOENT));
+
+ g_propagate_error (error, local_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct _ThreadData
+{
+ gchar *uri;
+ GObject *requester;
+ GInputStream *out_stream;
+ gint64 out_stream_length;
+ gchar *out_mime_type;
+} ThreadData;
+
+static void
+thread_data_free (gpointer ptr)
+{
+ ThreadData *td = ptr;
+
+ if (td) {
+ g_clear_object (&td->out_stream);
+ g_clear_object (&td->requester);
+ g_free (td->uri);
+ g_free (td->out_mime_type);
+ g_free (td);
+ }
+}
+
+static void
+content_request_process_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ ThreadData *td = task_data;
+ GError *local_error = NULL;
+
+ g_return_if_fail (E_IS_CONTENT_REQUEST (source_object));
+ g_return_if_fail (td != NULL);
+
+ if (!e_content_request_process_sync (E_CONTENT_REQUEST (source_object),
+ td->uri, td->requester, &td->out_stream, &td->out_stream_length, &td->out_mime_type,
+ cancellable, &local_error)) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_boolean (task, TRUE);
+ }
+}
+
+void
+e_content_request_process (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ ThreadData *td;
+
+ g_return_if_fail (E_IS_CONTENT_REQUEST (request));
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (G_IS_OBJECT (requester));
+
+ td = g_new0 (ThreadData, 1);
+ td->uri = g_strdup (uri);
+ td->requester = g_object_ref (requester);
+
+ task = g_task_new (request, cancellable, callback, user_data);
+ g_task_set_task_data (task, td, thread_data_free);
+ g_task_run_in_thread (task, content_request_process_thread);
+ g_object_unref (task);
+}
+
+gboolean
+e_content_request_process_finish (EContentRequest *request,
+ GAsyncResult *result,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GError **error)
+{
+ ThreadData *td;
+
+ g_return_val_if_fail (g_task_is_valid (result, request), FALSE);
+ g_return_val_if_fail (E_IS_CONTENT_REQUEST (request), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+ g_return_val_if_fail (out_stream != NULL, FALSE);
+ g_return_val_if_fail (out_stream_length != NULL, FALSE);
+ g_return_val_if_fail (out_mime_type != NULL, FALSE);
+
+ td = g_task_get_task_data (G_TASK (result));
+ g_return_val_if_fail (td != NULL, FALSE);
+
+ if (!g_task_propagate_boolean (G_TASK (result), error))
+ return FALSE;
+
+ *out_stream = td->out_stream;
+ *out_stream_length = td->out_stream_length;
+ *out_mime_type = td->out_mime_type;
+
+ td->out_stream = NULL;
+ td->out_mime_type = NULL;
+
+ return TRUE;
+}
diff --git a/e-util/e-content-request.h b/e-util/e-content-request.h
new file mode 100644
index 0000000..7df94c4
--- /dev/null
+++ b/e-util/e-content-request.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_CONTENT_REQUEST_H
+#define E_CONTENT_REQUEST_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CONTENT_REQUEST \
+ (e_content_request_get_type ())
+#define E_CONTENT_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTENT_REQUEST, EContentRequest))
+#define E_CONTENT_REQUEST_INTERFACE(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTENT_REQUEST, EContentRequestInterface))
+#define E_IS_CONTENT_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTENT_REQUEST))
+#define E_IS_CONTENT_REQUEST_INTERFACE(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTENT_REQUEST))
+#define E_CONTENT_REQUEST_GET_INTERFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE \
+ ((obj), E_TYPE_CONTENT_REQUEST, EContentRequestInterface))
+
+G_BEGIN_DECLS
+
+typedef struct _EContentRequest EContentRequest;
+typedef struct _EContentRequestInterface EContentRequestInterface;
+
+struct _EContentRequestInterface {
+ GTypeInterface parent_interface;
+
+ gboolean (* can_process_uri) (EContentRequest *request,
+ const gchar *uri);
+ gboolean (* process_sync) (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error);
+};
+
+GType e_content_request_get_type (void);
+gboolean e_content_request_can_process_uri (EContentRequest *request,
+ const gchar *uri);
+gboolean e_content_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error);
+void e_content_request_process (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_content_request_process_finish (EContentRequest *request,
+ GAsyncResult *result,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_CONTENT_REQUEST_H */
diff --git a/e-util/e-file-request.c b/e-util/e-file-request.c
index f6b4ac2..8cdb18a 100644
--- a/e-util/e-file-request.c
+++ b/e-util/e-file-request.c
@@ -15,178 +15,124 @@
*
*/
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
-#include "e-file-request.h"
+#include <stdio.h>
+#include <string.h>
#include <libsoup/soup.h>
-#include <stdio.h>
-#include <string.h>
+#include "e-file-request.h"
#define d(x)
-#define E_FILE_REQUEST_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_FILE_REQUEST, EFileRequestPrivate))
-
struct _EFileRequestPrivate {
- gchar *content_type;
- gint content_length;
+ gint dummy;
};
-G_DEFINE_TYPE (EFileRequest, e_file_request, SOUP_TYPE_REQUEST)
-
-static void
-handle_file_request (GSimpleAsyncResult *res,
- GObject *object,
- GCancellable *cancellable)
-{
- EFileRequest *request = E_FILE_REQUEST (object);
- SoupURI *uri;
- GInputStream *stream;
- gchar *contents;
- gsize length;
-
- if (g_cancellable_is_cancelled (cancellable))
- return;
-
- uri = soup_request_get_uri (SOUP_REQUEST (request));
-
- if (g_file_get_contents (uri->path, &contents, &length, NULL)) {
+static void e_file_request_content_request_init (EContentRequestInterface *iface);
- request->priv->content_type =
- g_content_type_guess (uri->path, NULL, 0, NULL);
- request->priv->content_length = length;
-
- stream = g_memory_input_stream_new_from_data (
- contents, length, (GDestroyNotify) g_free);
- g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
- }
-}
-
-static void
-file_request_finalize (GObject *object)
-{
- EFileRequest *request = E_FILE_REQUEST (object);
-
- if (request->priv->content_type) {
- g_free (request->priv->content_type);
- request->priv->content_type = NULL;
- }
-
- G_OBJECT_CLASS (e_file_request_parent_class)->finalize (object);
-}
+G_DEFINE_TYPE_WITH_CODE (EFileRequest, e_file_request, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (E_TYPE_CONTENT_REQUEST, e_file_request_content_request_init))
static gboolean
-file_request_check_uri (SoupRequest *request,
- SoupURI *uri,
- GError **error)
-{
- return (strcmp (uri->scheme, "evo-file") == 0);
-}
-
-static void
-file_request_send_async (SoupRequest *request,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_file_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
{
- GSimpleAsyncResult *simple;
-
- d (
- SoupURI *soup_uri = soup_request_get_uri (request);
- gchar *uri = soup_uri_to_string (soup_uri, FALSE);
- printf ("received request for %s\n", uri);
- g_free (uri);
- );
-
- /* WebKit won't allow us to load data through local file:// protocol
- * when using "remote" mail:// protocol, so we have evo-file://
- * which WebKit thinks it's remote, but in fact it behaves like
- * oridnary file:// */
-
- simple = g_simple_async_result_new (
- G_OBJECT (request), callback, user_data,
- file_request_send_async);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- g_simple_async_result_run_in_thread (
- simple, handle_file_request,
- G_PRIORITY_DEFAULT, cancellable);
+ g_return_val_if_fail (E_IS_FILE_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
- g_object_unref (simple);
+ return g_ascii_strncasecmp (uri, "evo-file:", 9) == 0;
}
-static GInputStream *
-file_request_send_finish (SoupRequest *request,
- GAsyncResult *result,
- GError **error)
+static gboolean
+e_file_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- GSimpleAsyncResult *simple;
- GInputStream *stream;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- stream = g_simple_async_result_get_op_res_gpointer (simple);
-
- /* Reset the stream before passing it back to webkit */
- if (stream && G_IS_SEEKABLE (stream))
- g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
-
- if (!stream) /* We must always return something */
- stream = g_memory_input_stream_new ();
- else
- g_object_ref (stream);
-
- return stream;
-}
+ GFile *file;
+ GFileInputStream *file_input_stream;
+ GFileInfo *info;
+ goffset total_size;
+ SoupURI *suri;
+
+ g_return_val_if_fail (E_IS_FILE_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ suri = soup_uri_new (uri);
+ g_return_val_if_fail (suri != NULL, FALSE);
+
+ file = g_file_new_for_path (suri->path);
+ file_input_stream = g_file_read (file, cancellable, error);
+
+ if (file_input_stream) {
+ total_size = -1;
+ info = g_file_input_stream_query_info (file_input_stream, G_FILE_ATTRIBUTE_STANDARD_SIZE,
cancellable, NULL);
+ if (info) {
+ if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
+ total_size = g_file_info_get_size (info);
+ g_object_unref (info);
+ }
+
+ if (total_size == -1) {
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
G_FILE_QUERY_INFO_NONE, cancellable, NULL);
+ if (info) {
+ if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
+ total_size = g_file_info_get_size (info);
+ g_object_unref (info);
+ }
+ }
+ } else {
+ total_size = -1;
+ }
-static goffset
-file_request_get_content_length (SoupRequest *request)
-{
- EFileRequest *efr = E_FILE_REQUEST (request);
+ if (file_input_stream) {
+ *out_stream = G_INPUT_STREAM (file_input_stream);
+ *out_stream_length = (gint64) total_size;
+ *out_mime_type = g_content_type_guess (suri->path, NULL, 0, NULL);
+ } else {
+ *out_stream = NULL;
+ *out_stream_length = (gint64) total_size;
+ *out_mime_type = NULL;
+ }
- d (printf ("Content-Length: %d bytes\n", efr->priv->content_length));
+ g_object_unref (file);
+ soup_uri_free (suri);
- return efr->priv->content_length;
+ return file_input_stream != NULL;
}
-static const gchar *
-file_request_get_content_type (SoupRequest *request)
+static void
+e_file_request_content_request_init (EContentRequestInterface *iface)
{
- EFileRequest *efr = E_FILE_REQUEST (request);
-
- d (printf ("Content-Type: %s\n", efr->priv->content_type));
-
- return efr->priv->content_type;
+ iface->can_process_uri = e_file_request_can_process_uri;
+ iface->process_sync = e_file_request_process_sync;
}
-static const gchar *data_schemes[] = { "evo-file", NULL };
-
static void
e_file_request_class_init (EFileRequestClass *class)
{
- GObjectClass *object_class;
- SoupRequestClass *request_class;
-
g_type_class_add_private (class, sizeof (EFileRequestPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = file_request_finalize;
-
- request_class = SOUP_REQUEST_CLASS (class);
- request_class->schemes = data_schemes;
- request_class->send_async = file_request_send_async;
- request_class->send_finish = file_request_send_finish;
- request_class->get_content_type = file_request_get_content_type;
- request_class->get_content_length = file_request_get_content_length;
- request_class->check_uri = file_request_check_uri;
}
static void
e_file_request_init (EFileRequest *request)
{
- request->priv = E_FILE_REQUEST_GET_PRIVATE (request);
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, E_TYPE_FILE_REQUEST, EFileRequestPrivate);
}
+EContentRequest *
+e_file_request_new (void)
+{
+ return g_object_new (E_TYPE_FILE_REQUEST, NULL);
+}
diff --git a/e-util/e-file-request.h b/e-util/e-file-request.h
index ab46c9a..706309d 100644
--- a/e-util/e-file-request.h
+++ b/e-util/e-file-request.h
@@ -22,10 +22,7 @@
#ifndef E_FILE_REQUEST_H
#define E_FILE_REQUEST_H
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include <libsoup/soup.h>
-#include <libsoup/soup-request.h>
+#include <e-util/e-content-request.h>
/* Standard GObject macros */
#define E_TYPE_FILE_REQUEST \
@@ -53,15 +50,17 @@ typedef struct _EFileRequestClass EFileRequestClass;
typedef struct _EFileRequestPrivate EFileRequestPrivate;
struct _EFileRequest {
- SoupRequest parent;
+ GObject parent;
EFileRequestPrivate *priv;
};
struct _EFileRequestClass {
- SoupRequestClass parent;
+ GObjectClass parent;
};
GType e_file_request_get_type (void) G_GNUC_CONST;
+EContentRequest *
+ e_file_request_new (void);
G_END_DECLS
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index e9bbcfe..c985ccc 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -3326,3 +3326,19 @@ e_util_set_entry_issue_hint (GtkWidget *entry,
gtk_entry_set_icon_tooltip_text (eentry, GTK_ENTRY_ICON_SECONDARY, NULL);
}
}
+
+static GThread *main_thread = NULL;
+
+void
+e_util_init_main_thread (GThread *thread)
+{
+ g_return_if_fail (main_thread == NULL);
+
+ main_thread = thread ? thread : g_thread_self ();
+}
+
+gboolean
+e_util_is_main_thread (GThread *thread)
+{
+ return thread ? thread == main_thread : g_thread_self () == main_thread;
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index 931fa37..cb78a72 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -287,6 +287,9 @@ void e_util_set_entry_issue_hint (GtkWidget *entry,
guint e_util_normalize_font_size (GtkWidget *widget,
gdouble font_size);
+void e_util_init_main_thread (GThread *thread);
+gboolean e_util_is_main_thread (GThread *thread);
+
G_END_DECLS
#endif /* E_MISC_UTILS_H */
diff --git a/e-util/e-stock-request.c b/e-util/e-stock-request.c
index 5d70fa3..f170909 100644
--- a/e-util/e-stock-request.c
+++ b/e-util/e-stock-request.c
@@ -15,56 +15,87 @@
*
*/
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include "e-stock-request.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdlib.h>
+#include <string.h>
+
#include <gtk/gtk.h>
#include <libsoup/soup.h>
-#include <string.h>
+#include <libedataserver/libedataserver.h>
-#define E_STOCK_REQUEST_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_STOCK_REQUEST, EStockRequestPrivate))
+#include "e-misc-utils.h"
+#include "e-stock-request.h"
struct _EStockRequestPrivate {
- gchar *content_type;
- gint content_length;
+ gint dummy;
};
-static const gchar *data_schemes[] = { "gtk-stock", NULL };
+static void e_stock_request_content_request_init (EContentRequestInterface *iface);
-G_DEFINE_TYPE (EStockRequest, e_stock_request, SOUP_TYPE_REQUEST)
+G_DEFINE_TYPE_WITH_CODE (EStockRequest, e_stock_request, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (E_TYPE_CONTENT_REQUEST, e_stock_request_content_request_init))
static gboolean
-handle_stock_request_idle_cb (gpointer user_data)
+e_stock_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
{
- EStockRequestPrivate *priv;
- GSimpleAsyncResult *simple;
- GObject *object;
- SoupURI *uri;
+ g_return_val_if_fail (E_IS_STOCK_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ return g_ascii_strncasecmp (uri, "gtk-stock:", 10) == 0;
+}
+
+typedef struct _StockIdleData
+{
+ EContentRequest *request;
+ const gchar *uri;
+ GObject *requester;
+ GInputStream **out_stream;
+ gint64 *out_stream_length;
+ gchar **out_mime_type;
+ GCancellable *cancellable;
+ GError **error;
+
+ gboolean success;
+ EFlag *flag;
+} StockIdleData;
+
+static gboolean
+process_stock_request_idle_cb (gpointer user_data)
+{
+ StockIdleData *sid = user_data;
+ SoupURI *suri;
GHashTable *query = NULL;
GtkStyleContext *context;
GtkWidgetPath *path;
GtkIconSet *icon_set;
gssize size = GTK_ICON_SIZE_BUTTON;
gchar *a_size;
- gchar *buffer = NULL;
+ gchar *buffer = NULL, *mime_type = NULL;
gsize buff_len = 0;
GError *local_error = NULL;
- simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ g_return_val_if_fail (sid != NULL, FALSE);
+ g_return_val_if_fail (E_IS_STOCK_REQUEST (sid->request), FALSE);
+ g_return_val_if_fail (sid->uri != NULL, FALSE);
+ g_return_val_if_fail (sid->flag != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (sid->cancellable, sid->error)) {
+ sid->success = FALSE;
+ e_flag_set (sid->flag);
- /* This returns a new reference. */
- object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
+ return FALSE;
+ }
- priv = E_STOCK_REQUEST_GET_PRIVATE (object);
+ suri = soup_uri_new (sid->uri);
+ g_return_val_if_fail (suri != NULL, FALSE);
- uri = soup_request_get_uri (SOUP_REQUEST (object));
- if (uri->query != NULL)
- query = soup_form_decode (uri->query);
+ if (suri->query != NULL)
+ query = soup_form_decode (suri->query);
if (query != NULL) {
a_size = g_hash_table_lookup (query, "size");
@@ -81,7 +112,7 @@ handle_stock_request_idle_cb (gpointer user_data)
gtk_style_context_set_path (context, path);
gtk_widget_path_free (path);
- icon_set = gtk_style_context_lookup_icon_set (context, uri->host);
+ icon_set = gtk_style_context_lookup_icon_set (context, suri->host);
if (icon_set != NULL) {
GdkPixbuf *pixbuf;
@@ -101,7 +132,7 @@ handle_stock_request_idle_cb (gpointer user_data)
icon_theme = gtk_icon_theme_get_default ();
icon_info = gtk_icon_theme_lookup_icon (
- icon_theme, uri->host, size,
+ icon_theme, suri->host, size,
GTK_ICON_LOOKUP_USE_BUILTIN);
/* Some icons can be missing in the theme */
@@ -113,9 +144,7 @@ handle_stock_request_idle_cb (gpointer user_data)
buffer = NULL;
buff_len = 0;
}
- priv->content_type =
- g_content_type_guess (filename, NULL, 0, NULL);
-
+ mime_type = g_content_type_guess (filename, NULL, 0, NULL);
} else {
GdkPixbuf *pixbuf;
@@ -137,148 +166,97 @@ handle_stock_request_idle_cb (gpointer user_data)
((buffer != NULL) && (local_error == NULL)) ||
((buffer == NULL) && (local_error != NULL)));
- if (priv->content_type == NULL)
- priv->content_type = g_strdup ("image/png");
- priv->content_length = buff_len;
+ if (!mime_type)
+ mime_type = g_strdup ("image/png");
if (buffer != NULL) {
- GInputStream *stream;
-
- stream = g_memory_input_stream_new_from_data (
- buffer, buff_len, (GDestroyNotify) g_free);
- g_simple_async_result_set_op_res_gpointer (
- simple, g_object_ref (stream),
- (GDestroyNotify) g_object_unref);
- g_object_unref (stream);
- }
-
- if (local_error != NULL)
- g_simple_async_result_take_error (simple, local_error);
-
- g_simple_async_result_complete_in_idle (simple);
+ *sid->out_stream = g_memory_input_stream_new_from_data (buffer, buff_len, g_free);;
+ *sid->out_stream_length = buff_len;
+ *sid->out_mime_type = mime_type;
- g_object_unref (context);
- g_object_unref (object);
+ sid->success = TRUE;
+ } else {
+ g_free (mime_type);
- return FALSE;
-}
+ if (local_error)
+ g_propagate_error (sid->error, local_error);
-static void
-stock_request_finalize (GObject *object)
-{
- EStockRequestPrivate *priv;
+ sid->success = FALSE;
+ }
- priv = E_STOCK_REQUEST_GET_PRIVATE (object);
+ g_object_unref (context);
- g_free (priv->content_type);
+ e_flag_set (sid->flag);
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_stock_request_parent_class)->finalize (object);
+ return FALSE;
}
static gboolean
-stock_request_check_uri (SoupRequest *request,
- SoupURI *uri,
- GError **error)
+e_stock_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- return (strcmp (uri->scheme, "gtk-stock") == 0);
-}
-
-static void
-stock_request_send_async (SoupRequest *request,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple;
-
- simple = g_simple_async_result_new (
- G_OBJECT (request), callback, user_data,
- stock_request_send_async);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- /* Need to run this operation in an idle callback rather
- * than a worker thread, since we're making all kinds of
- * GdkPixbuf/GTK+ calls. */
- g_idle_add_full (
- G_PRIORITY_HIGH_IDLE,
- handle_stock_request_idle_cb,
- g_object_ref (simple),
- (GDestroyNotify) g_object_unref);
-
- g_object_unref (simple);
-}
-
-static GInputStream *
-stock_request_send_finish (SoupRequest *request,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- GInputStream *stream;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- stream = g_simple_async_result_get_op_res_gpointer (simple);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- /* Reset the stream before passing it back to WebKit. */
- if (G_IS_SEEKABLE (stream))
- g_seekable_seek (
- G_SEEKABLE (stream), 0,
- G_SEEK_SET, NULL, NULL);
-
- if (stream != NULL)
- return g_object_ref (stream);
-
- return g_memory_input_stream_new ();
-}
-
-static goffset
-stock_request_get_content_length (SoupRequest *request)
-{
- EStockRequestPrivate *priv;
+ StockIdleData sid;
+
+ g_return_val_if_fail (E_IS_STOCK_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ sid.request = request;
+ sid.uri = uri;
+ sid.requester = requester;
+ sid.out_stream = out_stream;
+ sid.out_stream_length = out_stream_length;
+ sid.out_mime_type = out_mime_type;
+ sid.cancellable = cancellable;
+ sid.error = error;
+ sid.flag = e_flag_new ();
+ sid.success = FALSE;
+
+ if (e_util_is_main_thread (NULL)) {
+ process_stock_request_idle_cb (&sid);
+ } else {
+ /* Need to run this operation in an idle callback rather
+ * than a worker thread, since we're making all kinds of
+ * GdkPixbuf/GTK+ calls. */
+ g_idle_add_full (
+ G_PRIORITY_HIGH_IDLE,
+ process_stock_request_idle_cb,
+ &sid, NULL);
+
+ e_flag_wait (sid.flag);
+ }
- priv = E_STOCK_REQUEST_GET_PRIVATE (request);
+ e_flag_free (sid.flag);
- return priv->content_length;
+ return sid.success;
}
-static const gchar *
-stock_request_get_content_type (SoupRequest *request)
+static void
+e_stock_request_content_request_init (EContentRequestInterface *iface)
{
- EStockRequestPrivate *priv;
-
- priv = E_STOCK_REQUEST_GET_PRIVATE (request);
-
- return priv->content_type;
+ iface->can_process_uri = e_stock_request_can_process_uri;
+ iface->process_sync = e_stock_request_process_sync;
}
static void
e_stock_request_class_init (EStockRequestClass *class)
{
- GObjectClass *object_class;
- SoupRequestClass *request_class;
-
g_type_class_add_private (class, sizeof (EStockRequestPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = stock_request_finalize;
-
- request_class = SOUP_REQUEST_CLASS (class);
- request_class->schemes = data_schemes;
- request_class->check_uri = stock_request_check_uri;
- request_class->send_async = stock_request_send_async;
- request_class->send_finish = stock_request_send_finish;
- request_class->get_content_length = stock_request_get_content_length;
- request_class->get_content_type = stock_request_get_content_type;
}
static void
e_stock_request_init (EStockRequest *request)
{
- request->priv = E_STOCK_REQUEST_GET_PRIVATE (request);
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, E_TYPE_STOCK_REQUEST, EStockRequestPrivate);
}
+EContentRequest *
+e_stock_request_new (void)
+{
+ return g_object_new (E_TYPE_STOCK_REQUEST, NULL);
+}
diff --git a/e-util/e-stock-request.h b/e-util/e-stock-request.h
index be6222b..09800d0 100644
--- a/e-util/e-stock-request.h
+++ b/e-util/e-stock-request.h
@@ -22,10 +22,7 @@
#ifndef E_STOCK_REQUEST_H
#define E_STOCK_REQUEST_H
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include <libsoup/soup.h>
-#include <libsoup/soup-request.h>
+#include <e-util/e-content-request.h>
/* Standard GObject macros */
#define E_TYPE_STOCK_REQUEST \
@@ -53,15 +50,17 @@ typedef struct _EStockRequestClass EStockRequestClass;
typedef struct _EStockRequestPrivate EStockRequestPrivate;
struct _EStockRequest {
- SoupRequest parent;
+ GObject parent;
EStockRequestPrivate *priv;
};
struct _EStockRequestClass {
- SoupRequestClass parent;
+ GObjectClass parent;
};
GType e_stock_request_get_type (void) G_GNUC_CONST;
+EContentRequest *
+ e_stock_request_new (void);
G_END_DECLS
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 72230dc..209a0f1 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -86,6 +86,7 @@
#include <e-util/e-config.h>
#include <e-util/e-conflict-search-selector.h>
#include <e-util/e-contact-store.h>
+#include <e-util/e-content-request.h>
#include <e-util/e-data-capture.h>
#include <e-util/e-dateedit.h>
#include <e-util/e-datetime-format.h>
diff --git a/e-util/e-web-view.c b/e-util/e-web-view.c
index 1d8fa54..6efd68e 100644
--- a/e-util/e-web-view.c
+++ b/e-util/e-web-view.c
@@ -1000,13 +1000,93 @@ web_view_finalize (GObject *object)
G_OBJECT_CLASS (e_web_view_parent_class)->finalize (object);
}
+
+static void
+web_view_uri_request_done_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ WebKitURISchemeRequest *request = user_data;
+ GInputStream *stream = NULL;
+ gint64 stream_length = -1;
+ gchar *mime_type = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (E_IS_CONTENT_REQUEST (source_object));
+ g_return_if_fail (WEBKIT_IS_URI_SCHEME_REQUEST (request));
+
+ if (!e_content_request_process_finish (E_CONTENT_REQUEST (source_object),
+ result, &stream, &stream_length, &mime_type, &error)) {
+ webkit_uri_scheme_request_finish_error (request, error);
+ } else {
+ webkit_uri_scheme_request_finish (request, stream, stream_length, mime_type);
+
+ g_clear_object (&stream);
+ g_free (mime_type);
+ }
+
+ g_object_unref (request);
+}
+
+static void
+web_view_process_uri_request_cb (WebKitURISchemeRequest *request,
+ gpointer user_data)
+{
+ EContentRequest *content_request = user_data;
+ const gchar *uri;
+ GObject *requester;
+
+ g_return_if_fail (WEBKIT_IS_URI_SCHEME_REQUEST (request));
+ g_return_if_fail (E_IS_CONTENT_REQUEST (content_request));
+
+ uri = webkit_uri_scheme_request_get_uri (request);
+ requester = G_OBJECT (webkit_uri_scheme_request_get_web_view (request));
+
+ g_return_if_fail (e_content_request_can_process_uri (content_request, uri));
+
+ e_content_request_process (content_request, uri, requester, NULL,
+ web_view_uri_request_done_cb, g_object_ref (request));
+}
+
+/* 'scheme' is like "file", not "file:" */
+void
+e_web_view_register_content_request_for_scheme (EWebView *web_view,
+ const gchar *scheme,
+ EContentRequest *content_request)
+{
+ WebKitWebContext *web_context;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (E_IS_CONTENT_REQUEST (content_request));
+ g_return_if_fail (scheme != NULL);
+
+ web_context = webkit_web_view_get_context (WEBKIT_WEB_VIEW (web_view));
+
+ webkit_web_context_register_uri_scheme (web_context, scheme, web_view_process_uri_request_cb,
+ g_object_ref (content_request), g_object_unref);
+}
+
static void
web_view_initialize (WebKitWebView *web_view)
{
+ WebKitWebContext *web_context;
+ EContentRequest *content_request;
const gchar *id = "org.gnome.settings-daemon.plugins.xsettings";
GSettings *settings = NULL, *font_settings;
GSettingsSchema *settings_schema;
+ web_context = webkit_web_view_get_context (web_view);
+
+ webkit_web_context_set_cache_model (web_context, WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
+
+ content_request = e_file_request_new ();
+ e_web_view_register_content_request_for_scheme (E_WEB_VIEW (web_view), "evo-file", content_request);
+ g_object_unref (content_request);
+
+ content_request = e_stock_request_new ();
+ e_web_view_register_content_request_for_scheme (E_WEB_VIEW (web_view), "gtk-stock", content_request);
+ g_object_unref (content_request);
+
/* Optional schema */
settings_schema = g_settings_schema_source_lookup (
g_settings_schema_source_get_default (), id, FALSE);
@@ -1700,216 +1780,6 @@ e_web_view_test_change_and_update_fonts_cb (EWebView *web_view,
}
static void
-web_view_process_uri_scheme_finished_cb (EWebView *web_view,
- GAsyncResult *result,
- WebKitURISchemeRequest *request)
-{
- GError *error = NULL;
-
- if (!g_task_propagate_boolean (G_TASK (result), &error)) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_warning ("URI %s cannot be processed: %s",
- webkit_uri_scheme_request_get_uri (request),
- error ? error->message : "Unknown error");
- }
- g_object_unref (request);
- if (error)
- g_error_free (error);
- }
-}
-
-static void
-web_view_process_file_uri_scheme_request (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- gboolean ret_val = FALSE;
- const gchar *uri;
- gchar *content = NULL;
- gchar *content_type = NULL;
- gchar *filename = NULL;
- GInputStream *stream;
- gsize length = 0;
- GError *error = NULL;
- WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
-
- uri = webkit_uri_scheme_request_get_uri (request);
-
- filename = g_filename_from_uri (strstr (uri, "file"), NULL, &error);
- if (!filename)
- goto out;
-
- if (!g_file_get_contents (filename, &content, &length, &error))
- goto out;
-
- content_type = g_content_type_guess (filename, NULL, 0, NULL);
-
- stream = g_memory_input_stream_new_from_data (content, length, g_free);
-
- webkit_uri_scheme_request_finish (request, stream, length, content_type);
-
- ret_val = TRUE;
- out:
- g_free (content_type);
- g_free (content);
- g_free (filename);
-
- if (ret_val)
- g_object_unref (request);
-
- if (error)
- g_task_return_error (task, error);
- else
- g_task_return_boolean (task, ret_val);
-}
-
-static void
-web_view_file_uri_scheme_appeared_cb (WebKitURISchemeRequest *request)
-{
- EWebView *web_view;
- GTask *task;
-
- web_view = E_WEB_VIEW (webkit_uri_scheme_request_get_web_view (request));
-
- task = g_task_new (
- web_view, NULL,
- (GAsyncReadyCallback) web_view_process_uri_scheme_finished_cb,
- request);
-
- g_task_set_task_data (task, g_object_ref (request), NULL);
- g_task_run_in_thread (task, web_view_process_file_uri_scheme_request);
-
- g_object_unref (task);
-}
-
-static void
-web_view_gtk_stock_uri_scheme_appeared_cb (WebKitURISchemeRequest *request)
-{
- SoupURI *uri;
- GHashTable *query = NULL;
- GtkStyleContext *context;
- GtkWidgetPath *path;
- GtkIconSet *icon_set;
- gssize size = GTK_ICON_SIZE_BUTTON;
- gchar *a_size;
- gchar *buffer = NULL;
- gchar *content_type = NULL;
- gsize buff_len = 0;
- GError *local_error = NULL;
-
- uri = soup_uri_new (webkit_uri_scheme_request_get_uri (request));
-
- if (uri && uri->query)
- query = soup_form_decode (uri->query);
-
- if (query) {
- a_size = g_hash_table_lookup (query, "size");
- if (a_size != NULL)
- size = atoi (a_size);
- g_hash_table_destroy (query);
- }
-
- /* Try style context first */
- context = gtk_style_context_new ();
- path = gtk_widget_path_new ();
- gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
- gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
- gtk_style_context_set_path (context, path);
- gtk_widget_path_free (path);
-
- icon_set = gtk_style_context_lookup_icon_set (context, uri->host);
- if (icon_set != NULL) {
- GdkPixbuf *pixbuf;
-
- pixbuf = gtk_icon_set_render_icon_pixbuf (
- icon_set, context, size);
- gdk_pixbuf_save_to_buffer (
- pixbuf, &buffer, &buff_len,
- "png", &local_error, NULL);
- g_object_unref (pixbuf);
- /* Fallback to icon theme */
- } else {
- GtkIconTheme *icon_theme;
- GtkIconInfo *icon_info;
- const gchar *filename;
-
- icon_theme = gtk_icon_theme_get_default ();
-
- icon_info = gtk_icon_theme_lookup_icon (
- icon_theme, uri->host, size,
- GTK_ICON_LOOKUP_USE_BUILTIN);
-
- filename = gtk_icon_info_get_filename (icon_info);
- if (filename != NULL) {
- g_file_get_contents (
- filename, &buffer, &buff_len, &local_error);
- content_type =
- g_content_type_guess (filename, NULL, 0, NULL);
-
- } else {
- GdkPixbuf *pixbuf;
-
- pixbuf = gtk_icon_info_get_builtin_pixbuf (icon_info);
- if (pixbuf != NULL) {
- gdk_pixbuf_save_to_buffer (
- pixbuf, &buffer, &buff_len,
- "png", &local_error, NULL);
- g_object_unref (pixbuf);
- }
- }
-
- gtk_icon_info_free (icon_info);
- }
-
- /* Sanity check */
- g_return_if_fail (
- ((buffer != NULL) && (local_error == NULL)) ||
- ((buffer == NULL) && (local_error != NULL)));
-
- if (!content_type)
- content_type = g_strdup ("image/png");
-
- if (buffer != NULL) {
- GInputStream *stream;
-
- stream = g_memory_input_stream_new_from_data (
- buffer, buff_len, (GDestroyNotify) g_free);
-
- webkit_uri_scheme_request_finish (
- request, stream, buff_len, content_type);
-
- g_object_unref (stream);
- }
-
- g_object_unref (context);
- g_free (content_type);
-}
-
-static void
-web_view_initialize_web_context (void)
-{
- WebKitWebContext *web_context = webkit_web_context_get_default ();
-
- webkit_web_context_set_cache_model (
- web_context, WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "evo-file",
- (WebKitURISchemeRequestCallback) web_view_file_uri_scheme_appeared_cb,
- NULL,
- NULL);
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "gtk-stock",
- (WebKitURISchemeRequestCallback) web_view_gtk_stock_uri_scheme_appeared_cb,
- NULL,
- NULL);
-}
-
-static void
web_view_toplevel_event_after_cb (GtkWidget *widget,
GdkEvent *event,
EWebView *web_view)
@@ -1968,8 +1838,6 @@ e_web_view_class_init (EWebViewClass *class)
g_type_class_add_private (class, sizeof (EWebViewPrivate));
- web_view_initialize_web_context ();
-
object_class = G_OBJECT_CLASS (class);
object_class->constructor = web_view_constructor;
object_class->set_property = web_view_set_property;
diff --git a/e-util/e-web-view.h b/e-util/e-web-view.h
index fb54a90..0b7e4c4 100644
--- a/e-util/e-web-view.h
+++ b/e-util/e-web-view.h
@@ -30,6 +30,7 @@
#include <webkit2/webkit2.h>
#include <e-util/e-activity.h>
+#include <e-util/e-content-request.h>
/* Standard GObject macros */
#define E_TYPE_WEB_VIEW \
@@ -113,6 +114,10 @@ GtkWidget * e_web_view_new (void);
WebKitSettings *
e_web_view_get_default_webkit_settings
(void);
+void e_web_view_register_content_request_for_scheme
+ (EWebView *web_view,
+ const gchar *scheme,
+ EContentRequest *content_request);
void e_web_view_update_fonts_settings
(GSettings *font_settings,
GSettings *aliasing_settings,
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 06aa259..acf784f 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -52,6 +52,7 @@ libevolution_mail_la_CPPFLAGS = \
$(NULL)
mailinclude_HEADERS = \
+ e-cid-request.h \
e-http-request.h \
e-mail.h \
e-mail-account-manager.h \
@@ -135,6 +136,7 @@ mailinclude_HEADERS = \
message-list.h
libevolution_mail_la_SOURCES = \
+ e-cid-request.c \
e-http-request.c \
e-mail-account-manager.c \
e-mail-account-store.c \
diff --git a/mail/e-cid-request.c b/mail/e-cid-request.c
new file mode 100644
index 0000000..9d82398
--- /dev/null
+++ b/mail/e-cid-request.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "e-mail-display.h"
+#include "e-cid-request.h"
+
+struct _ECidRequestPrivate {
+ gint dummy;
+};
+
+static void e_cid_request_content_request_init (EContentRequestInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ECidRequest, e_cid_request, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (E_TYPE_CONTENT_REQUEST, e_cid_request_content_request_init))
+
+static gboolean
+e_cid_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
+{
+ g_return_val_if_fail (E_IS_CID_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ return g_ascii_strncasecmp (uri, "cid:", 4) == 0;
+}
+
+static gboolean
+e_cid_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EMailDisplay *display;
+ EMailPartList *part_list;
+ EMailPart *part;
+ const gchar *mime_type;
+ GByteArray *byte_array;
+ CamelStream *output_stream;
+ CamelDataWrapper *dw;
+ CamelMimePart *mime_part;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (E_IS_CID_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ if (!E_IS_MAIL_DISPLAY (requester))
+ return FALSE;
+
+ display = E_MAIL_DISPLAY (requester);
+
+ part_list = e_mail_display_get_part_list (display);
+ if (!part_list)
+ return FALSE;
+
+ part = e_mail_part_list_ref_part (part_list, uri);
+ if (!part)
+ return FALSE;
+
+ mime_type = e_mail_part_get_mime_type (part);
+ mime_part = e_mail_part_ref_mime_part (part);
+ dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
+
+ g_return_val_if_fail (dw != NULL, FALSE);
+
+ byte_array = g_byte_array_new ();
+ output_stream = camel_stream_mem_new ();
+
+ /* We retain ownership of the byte array. */
+ camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (output_stream), byte_array);
+
+ if (camel_data_wrapper_decode_to_stream_sync (dw, output_stream, cancellable, error)) {
+ GBytes *bytes;
+
+ bytes = g_byte_array_free_to_bytes (byte_array);
+
+ success = TRUE;
+
+ *out_stream = g_memory_input_stream_new_from_bytes (bytes);
+ *out_stream_length = g_bytes_get_size (bytes);
+ *out_mime_type = g_strdup (mime_type);
+
+ g_bytes_unref (bytes);
+ }
+
+ g_object_unref (mime_part);
+ g_object_unref (part);
+
+ return success;
+}
+
+static void
+e_cid_request_content_request_init (EContentRequestInterface *iface)
+{
+ iface->can_process_uri = e_cid_request_can_process_uri;
+ iface->process_sync = e_cid_request_process_sync;
+}
+
+static void
+e_cid_request_class_init (ECidRequestClass *class)
+{
+ g_type_class_add_private (class, sizeof (ECidRequestPrivate));
+}
+
+static void
+e_cid_request_init (ECidRequest *request)
+{
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, E_TYPE_CID_REQUEST, ECidRequestPrivate);
+}
+
+EContentRequest *
+e_cid_request_new (void)
+{
+ return g_object_new (E_TYPE_CID_REQUEST, NULL);
+}
diff --git a/mail/e-cid-request.h b/mail/e-cid-request.h
new file mode 100644
index 0000000..0ed6e4b
--- /dev/null
+++ b/mail/e-cid-request.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef E_CID_REQUEST_H
+#define E_CID_REQUEST_H
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CID_REQUEST \
+ (e_cid_request_get_type ())
+#define E_CID_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CID_REQUEST, ECidRequest))
+#define E_CID_REQUEST_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CID_REQUEST, ECidRequestClass))
+#define E_IS_CID_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CID_REQUEST))
+#define E_IS_CID_REQUEST_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CID_REQUEST))
+#define E_CID_REQUEST_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CID_REQUEST, ECidRequestClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECidRequest ECidRequest;
+typedef struct _ECidRequestClass ECidRequestClass;
+typedef struct _ECidRequestPrivate ECidRequestPrivate;
+
+struct _ECidRequest {
+ GObject parent;
+ ECidRequestPrivate *priv;
+};
+
+struct _ECidRequestClass {
+ GObjectClass parent;
+};
+
+GType e_cid_request_get_type (void) G_GNUC_CONST;
+EContentRequest *
+ e_cid_request_new (void);
+
+G_END_DECLS
+
+#endif /* E_CID_REQUEST_H */
diff --git a/mail/e-http-request.c b/mail/e-http-request.c
index 403a454..5af3de6 100644
--- a/mail/e-http-request.c
+++ b/mail/e-http-request.c
@@ -15,9 +15,10 @@
*
*/
-#include "e-http-request.h"
-
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <string.h>
#define LIBSOUP_USE_UNSTABLE_REQUEST_API
@@ -35,19 +36,29 @@
#include <shell/e-shell.h>
#include "e-mail-ui-session.h"
+#include "e-http-request.h"
#define d(x)
-#define E_HTTP_REQUEST_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_HTTP_REQUEST, EHTTPRequestPrivate))
-
struct _EHTTPRequestPrivate {
- gchar *content_type;
- gint content_length;
+ gint dummy;
};
-G_DEFINE_TYPE (EHTTPRequest, e_http_request, SOUP_TYPE_REQUEST)
+static void e_http_request_content_request_init (EContentRequestInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EHTTPRequest, e_http_request, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (E_TYPE_CONTENT_REQUEST, e_http_request_content_request_init))
+
+static gboolean
+e_http_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
+{
+ g_return_val_if_fail (E_IS_HTTP_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ return g_ascii_strncasecmp (uri, "evo-http:", 9) == 0 ||
+ g_ascii_strncasecmp (uri, "evo-https:", 10) == 0;
+}
static gssize
copy_stream_to_stream (GIOStream *file_io_stream,
@@ -162,16 +173,18 @@ http_request_cancelled_cb (GCancellable *cancellable,
soup_session_abort (session);
}
-static void
-handle_http_request (GSimpleAsyncResult *res,
- GObject *source_object,
- GCancellable *cancellable)
+static gboolean
+e_http_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- EHTTPRequestPrivate *priv;
SoupURI *soup_uri;
- SoupRequest *soup_request;
- SoupSession *soup_session;
- gchar *evo_uri, *uri;
+ gchar *evo_uri, *use_uri;
gchar *mail_uri = NULL;
GInputStream *stream;
gboolean force_load_images = FALSE;
@@ -183,15 +196,16 @@ handle_http_request (GSimpleAsyncResult *res,
CamelDataCache *cache;
GIOStream *cache_stream;
gint uri_len;
+ gboolean success = FALSE;
- if (g_cancellable_is_cancelled (cancellable))
- return;
+ g_return_val_if_fail (E_IS_HTTP_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
- priv = E_HTTP_REQUEST_GET_PRIVATE (source_object);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- soup_request = SOUP_REQUEST (source_object);
- soup_session = soup_request_get_session (soup_request);
- soup_uri = soup_request_get_uri (soup_request);
+ soup_uri = soup_uri_new (uri);
+ g_return_val_if_fail (soup_uri != NULL, FALSE);
/* Remove the __evo-mail query */
soup_query = soup_uri_get_query (soup_uri);
@@ -224,24 +238,26 @@ handle_http_request (GSimpleAsyncResult *res,
/* Remove the "evo-" prefix from scheme */
uri_len = (evo_uri != NULL) ? strlen (evo_uri) : 0;
- uri = NULL;
+ use_uri = NULL;
if (evo_uri != NULL && (uri_len > 5)) {
/* Remove trailing "?" if there is no URI query */
if (evo_uri[uri_len - 1] == '?') {
- uri = g_strndup (evo_uri + 4, uri_len - 5);
+ use_uri = g_strndup (evo_uri + 4, uri_len - 5);
} else {
- uri = g_strdup (evo_uri + 4);
+ use_uri = g_strdup (evo_uri + 4);
}
g_free (evo_uri);
}
- g_return_if_fail (uri && *uri);
+ g_return_val_if_fail (use_uri && *use_uri, FALSE);
+
+ *out_stream_length = -1;
/* Use MD5 hash of the URI as a filname of the resourec cache file.
* We were previously using the URI as a filename but the URI is
* sometimes too long for a filename. */
- uri_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
+ uri_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, use_uri, -1);
/* Open Evolution's cache */
user_cache_dir = e_get_user_cache_dir ();
@@ -256,17 +272,15 @@ handle_http_request (GSimpleAsyncResult *res,
stream = g_memory_input_stream_new ();
- len = copy_stream_to_stream (
- cache_stream,
- G_MEMORY_INPUT_STREAM (stream), cancellable);
- priv->content_length = len;
+ len = copy_stream_to_stream (cache_stream, G_MEMORY_INPUT_STREAM (stream), cancellable);
+ *out_stream_length = len;
g_object_unref (cache_stream);
/* When succesfully read some data from cache then
* get mimetype and return the stream to WebKit.
* Otherwise try to fetch the resource again from the network. */
- if ((len != -1) && (priv->content_length > 0)) {
+ if (len != -1 && *out_stream_length > 0) {
GFile *file;
GFileInfo *info;
gchar *path;
@@ -279,13 +293,12 @@ handle_http_request (GSimpleAsyncResult *res,
0, cancellable, NULL);
if (info) {
- priv->content_type = g_strdup (
- g_file_info_get_content_type (info));
+ *out_mime_type = g_strdup (g_file_info_get_content_type (info));
d (
printf ("'%s' found in cache (%d bytes, %s)\n",
- uri, priv->content_length,
- priv->content_type));
+ use_uri, (gint) *out_stream_length,
+ *out_mime_type));
}
g_clear_object (&info);
@@ -293,12 +306,12 @@ handle_http_request (GSimpleAsyncResult *res,
g_free (path);
/* Set result and quit the thread */
- g_simple_async_result_set_op_res_gpointer (
- res, stream, g_object_unref);
+ *out_stream = stream;
+ success = TRUE;
goto cleanup;
} else {
- d (printf ("Failed to load '%s' from cache.\n", uri));
+ d (printf ("Failed to load '%s' from cache.\n", use_uri));
g_object_unref (stream);
}
}
@@ -332,7 +345,6 @@ handle_http_request (GSimpleAsyncResult *res,
CamelInternetAddress *addr;
CamelMimeMessage *message;
gboolean known_address = FALSE;
- GError *error = NULL;
shell_backend =
e_shell_get_backend_by_name (shell, "mail");
@@ -342,14 +354,13 @@ handle_http_request (GSimpleAsyncResult *res,
message = e_mail_part_list_get_message (part_list);
addr = camel_mime_message_get_from (message);
- e_mail_ui_session_check_known_address_sync (
+ if (!e_mail_ui_session_check_known_address_sync (
E_MAIL_UI_SESSION (session),
addr, FALSE, cancellable,
- &known_address, &error);
-
- if (error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_error_free (error);
+ &known_address, error)) {
+ g_object_unref (part_list);
+ g_free (decoded_uri);
+ goto cleanup;
}
if (known_address)
@@ -363,20 +374,19 @@ handle_http_request (GSimpleAsyncResult *res,
if ((image_policy == E_IMAGE_LOADING_POLICY_ALWAYS) ||
force_load_images) {
-
+ ESource *proxy_source;
SoupSession *temp_session;
SoupMessage *message;
GIOStream *cache_stream;
- GError *error;
GMainContext *context;
gulong cancelled_id = 0;
- if (g_cancellable_is_cancelled (cancellable))
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
goto cleanup;
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = soup_message_new (SOUP_METHOD_GET, use_uri);
if (!message) {
- g_debug ("%s: Skipping invalid URI '%s'", G_STRFUNC, uri);
+ g_debug ("%s: Skipping invalid URI '%s'", G_STRFUNC, use_uri);
goto cleanup;
}
@@ -386,12 +396,16 @@ handle_http_request (GSimpleAsyncResult *res,
temp_session = soup_session_new_with_options (
SOUP_SESSION_TIMEOUT, 90, NULL);
- e_binding_bind_property (
- soup_session, "proxy-resolver",
- temp_session, "proxy-resolver",
- G_BINDING_SYNC_CREATE);
+ proxy_source = e_source_registry_ref_builtin_proxy (e_shell_get_registry (shell));
+
+ g_object_set (
+ temp_session,
+ SOUP_SESSION_PROXY_RESOLVER,
+ G_PROXY_RESOLVER (proxy_source),
+ NULL);
+
+ g_object_unref (proxy_source);
- message = soup_message_new (SOUP_METHOD_GET, uri);
soup_message_headers_append (
message->request_headers,
"User-Agent", "Evolution/" VERSION);
@@ -405,7 +419,7 @@ handle_http_request (GSimpleAsyncResult *res,
g_cancellable_disconnect (cancellable, cancelled_id);
if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
- g_debug ("Failed to request %s (code %d)", uri, message->status_code);
+ g_debug ("Failed to request %s (code %d)", use_uri, message->status_code);
g_object_unref (message);
g_object_unref (temp_session);
g_main_context_unref (context);
@@ -413,55 +427,40 @@ handle_http_request (GSimpleAsyncResult *res,
}
/* Write the response body to cache */
- error = NULL;
cache_stream = camel_data_cache_add (
- cache, "http", uri_md5, &error);
- if (error != NULL) {
- g_warning (
- "Failed to create cache file for '%s': %s",
- uri, error->message);
- g_clear_error (&error);
- } else {
+ cache, "http", uri_md5, error);
+ if (cache_stream) {
GOutputStream *output_stream;
output_stream =
g_io_stream_get_output_stream (cache_stream);
- g_output_stream_write_all (
+ success = g_output_stream_write_all (
output_stream,
message->response_body->data,
message->response_body->length,
- NULL, cancellable, &error);
+ NULL, cancellable, error);
g_io_stream_close (cache_stream, NULL, NULL);
g_object_unref (cache_stream);
- if (error != NULL) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning (
- "Failed to write data to cache stream: %s",
- error->message);
- g_clear_error (&error);
- g_object_unref (message);
- g_object_unref (temp_session);
- g_main_context_unref (context);
- goto cleanup;
+ if (success) {
+ /* Send the response body to WebKit */
+ stream = g_memory_input_stream_new_from_data (
+ g_memdup (
+ message->response_body->data,
+ message->response_body->length),
+ message->response_body->length,
+ (GDestroyNotify) g_free);
+
+ *out_stream = stream;
+ *out_stream_length = message->response_body->length;
+ *out_mime_type = g_strdup (
+ soup_message_headers_get_content_type (
+ message->response_headers, NULL));
}
}
- /* Send the response body to WebKit */
- stream = g_memory_input_stream_new_from_data (
- g_memdup (
- message->response_body->data,
- message->response_body->length),
- message->response_body->length,
- (GDestroyNotify) g_free);
-
- priv->content_length = message->response_body->length;
- priv->content_type = g_strdup (
- soup_message_headers_get_content_type (
- message->response_headers, NULL));
-
g_object_unref (message);
g_object_unref (temp_session);
g_main_context_unref (context);
@@ -470,150 +469,42 @@ handle_http_request (GSimpleAsyncResult *res,
"Content-Type: %s\n"
"Content-Length: %d bytes\n"
"URI MD5: %s:\n",
- uri, priv->content_type,
- priv->content_length, uri_md5));
-
- g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
-
- goto cleanup;
+ use_uri, *out_mime_type ? *out_mime_type : "[null]",
+ (gint) *out_stream_length, uri_md5));
}
-cleanup:
+ cleanup:
g_clear_object (&cache);
- g_free (uri);
+ g_free (use_uri);
g_free (uri_md5);
g_free (mail_uri);
-}
-
-static void
-http_request_finalize (GObject *object)
-{
- EHTTPRequest *request = E_HTTP_REQUEST (object);
-
- if (request->priv->content_type) {
- g_free (request->priv->content_type);
- request->priv->content_type = NULL;
- }
-
- G_OBJECT_CLASS (e_http_request_parent_class)->finalize (object);
-}
+ soup_uri_free (soup_uri);
-static gboolean
-http_request_check_uri (SoupRequest *request,
- SoupURI *uri,
- GError **error)
-{
- return ((strcmp (uri->scheme, "evo-http") == 0) ||
- (strcmp (uri->scheme, "evo-https") == 0));
+ return success;
}
static void
-http_request_send_async (SoupRequest *request,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_http_request_content_request_init (EContentRequestInterface *iface)
{
- GSimpleAsyncResult *simple;
-
- d ({
- const gchar *soup_query;
- SoupURI *uri;
-
- uri = soup_request_get_uri (request);
- soup_query = soup_uri_get_query (uri);
-
- if (soup_query) {
- gchar *uri_str;
- GHashTable *query;
-
- query = soup_form_decode (soup_uri_get_query (uri));
- uri_str = soup_uri_to_string (uri, FALSE);
- printf ("received request for %s\n", uri_str);
- g_free (uri_str);
- g_hash_table_destroy (query);
- }
- });
-
- simple = g_simple_async_result_new (
- G_OBJECT (request), callback,
- user_data, http_request_send_async);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- e_util_run_simple_async_result_in_thread (
- simple, handle_http_request,
- cancellable);
-
- g_object_unref (simple);
+ iface->can_process_uri = e_http_request_can_process_uri;
+ iface->process_sync = e_http_request_process_sync;
}
-static GInputStream *
-http_request_send_finish (SoupRequest *request,
- GAsyncResult *result,
- GError **error)
-{
- GInputStream *stream;
-
- stream = g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (result));
-
- /* Reset the stream before passing it back to webkit */
- if (stream && G_IS_SEEKABLE (stream))
- g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
-
- if (!stream) /* We must always return something */
- stream = g_memory_input_stream_new ();
- else
- g_object_ref (stream);
-
- return stream;
-}
-
-static goffset
-http_request_get_content_length (SoupRequest *request)
-{
- EHTTPRequest *efr = E_HTTP_REQUEST (request);
-
- d (printf ("Content-Length: %d bytes\n", efr->priv->content_length));
- return efr->priv->content_length;
-}
-
-static const gchar *
-http_request_get_content_type (SoupRequest *request)
-{
- EHTTPRequest *efr = E_HTTP_REQUEST (request);
-
- d (printf ("Content-Type: %s\n", efr->priv->content_type));
-
- return efr->priv->content_type;
-}
-
-static const gchar *data_schemes[] = { "evo-http", "evo-https", NULL };
-
static void
e_http_request_class_init (EHTTPRequestClass *class)
{
- GObjectClass *object_class;
- SoupRequestClass *request_class;
-
g_type_class_add_private (class, sizeof (EHTTPRequestPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = http_request_finalize;
-
- request_class = SOUP_REQUEST_CLASS (class);
- request_class->schemes = data_schemes;
- request_class->send_async = http_request_send_async;
- request_class->send_finish = http_request_send_finish;
- request_class->get_content_type = http_request_get_content_type;
- request_class->get_content_length = http_request_get_content_length;
- request_class->check_uri = http_request_check_uri;
}
static void
e_http_request_init (EHTTPRequest *request)
{
- request->priv = E_HTTP_REQUEST_GET_PRIVATE (request);
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, E_TYPE_HTTP_REQUEST, EHTTPRequestPrivate);
}
+EContentRequest *
+e_http_request_new (void)
+{
+ return g_object_new (E_TYPE_HTTP_REQUEST, NULL);
+}
diff --git a/mail/e-http-request.h b/mail/e-http-request.h
index de4cb23..bdbf009 100644
--- a/mail/e-http-request.h
+++ b/mail/e-http-request.h
@@ -18,10 +18,7 @@
#ifndef E_HTTP_REQUEST_H
#define E_HTTP_REQUEST_H
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include <libsoup/soup.h>
-#include <libsoup/soup-request.h>
+#include <e-util/e-util.h>
/* Standard GObject macros */
#define E_TYPE_HTTP_REQUEST \
@@ -49,15 +46,18 @@ typedef struct _EHTTPRequestClass EHTTPRequestClass;
typedef struct _EHTTPRequestPrivate EHTTPRequestPrivate;
struct _EHTTPRequest {
- SoupRequest parent;
+ GObject parent;
EHTTPRequestPrivate *priv;
};
struct _EHTTPRequestClass {
- SoupRequestClass parent;
+ GObjectClass parent;
};
GType e_http_request_get_type (void) G_GNUC_CONST;
+EContentRequest *
+ e_http_request_new (void);
+
G_END_DECLS
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 4718775..b821887 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -34,6 +34,7 @@
#include <em-format/e-mail-part-attachment.h>
#include <em-format/e-mail-part-utils.h>
+#include "e-cid-request.h"
#include "e-http-request.h"
#include "e-mail-display-popup-extension.h"
#include "e-mail-notes.h"
@@ -1447,6 +1448,9 @@ mail_display_web_view_initialize (WebKitWebView *web_view)
static void
mail_display_constructed (GObject *object)
{
+ EContentRequest *content_request;
+ EWebView *web_view;
+
e_extensible_load_extensions (E_EXTENSIBLE (object));
/* Chain up to parent's constructed() method. */
@@ -1454,7 +1458,22 @@ mail_display_constructed (GObject *object)
mail_display_web_view_initialize (WEBKIT_WEB_VIEW (object));
- e_web_view_update_fonts (E_WEB_VIEW (object));
+ web_view = E_WEB_VIEW (object);
+
+ e_web_view_update_fonts (web_view);
+
+ content_request = e_http_request_new ();
+ e_web_view_register_content_request_for_scheme (web_view, "evo-http", content_request);
+ e_web_view_register_content_request_for_scheme (web_view, "evo-https", content_request);
+ g_object_unref (content_request);
+
+ content_request = e_mail_request_new ();
+ e_web_view_register_content_request_for_scheme (web_view, "mail", content_request);
+ g_object_unref (content_request);
+
+ content_request = e_cid_request_new ();
+ e_web_view_register_content_request_for_scheme (web_view, "cid", content_request);
+ g_object_unref (content_request);
}
static void
@@ -1735,812 +1754,6 @@ e_mail_display_test_change_and_update_fonts_cb (EMailDisplay *mail_display,
}
static void
-mail_display_process_uri_scheme_finished_cb (EMailDisplay *display,
- GAsyncResult *result,
- WebKitURISchemeRequest *request)
-{
- GError *error = NULL;
-
- if (!g_task_propagate_boolean (G_TASK (result), &error)) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_warning ("URI %s cannot be processed: %s",
- webkit_uri_scheme_request_get_uri (request),
- error ? error->message : "Unknown error");
- }
- g_object_unref (request);
- if (error)
- g_error_free (error);
- }
-}
-
-static void
-mail_display_cid_uri_scheme_appeared_cb (WebKitURISchemeRequest *request)
-{
- EMailDisplay *display;
- EMailPartList *part_list;
- EMailPart *part;
- GInputStream *stream;
- const gchar *uri;
- const gchar *mime_type;
- GByteArray *byte_array;
- CamelStream *output_stream;
- GCancellable *cancellable = NULL;
- CamelDataWrapper *dw;
- CamelMimePart *mime_part;
-
- display = E_MAIL_DISPLAY (webkit_uri_scheme_request_get_web_view (request));
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- part_list = e_mail_display_get_part_list (display);
- uri = webkit_uri_scheme_request_get_uri (request);
- part = e_mail_part_list_ref_part (part_list, uri);
- mime_type = e_mail_part_get_mime_type (part);
- mime_part = e_mail_part_ref_mime_part (part);
- dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
-
- g_return_if_fail (dw);
-
- byte_array = g_byte_array_new ();
- output_stream = camel_stream_mem_new ();
-
- /* We retain ownership of the byte array. */
- camel_stream_mem_set_byte_array (
- CAMEL_STREAM_MEM (output_stream), byte_array);
-
- camel_data_wrapper_decode_to_stream_sync (
- dw, output_stream, cancellable, NULL);
-
- stream = g_memory_input_stream_new_from_bytes (
- g_byte_array_free_to_bytes (byte_array));
-
- webkit_uri_scheme_request_finish (request, stream, -1, mime_type);
-
- g_object_unref (mime_part);
- g_object_unref (stream);
- g_object_unref (part);
-}
-
-static gssize
-copy_stream_to_stream (GIOStream *file_io_stream,
- GMemoryInputStream *output,
- GCancellable *cancellable)
-{
- GInputStream *input_stream;
- gchar *buff;
- gssize read_len = 0;
- gssize total_len = 0;
- const gsize buff_size = 4096;
-
- g_seekable_seek (
- G_SEEKABLE (file_io_stream), 0,
- G_SEEK_SET, cancellable, NULL);
-
- input_stream = g_io_stream_get_input_stream (file_io_stream);
-
- buff = g_malloc (buff_size);
- read_len = g_input_stream_read (
- input_stream, buff, buff_size, cancellable, NULL);
- while (read_len > 0) {
- g_memory_input_stream_add_data (
- output, buff, read_len, g_free);
-
- total_len += read_len;
-
- buff = g_malloc (buff_size);
- read_len = g_input_stream_read (
- input_stream, buff, buff_size, cancellable, NULL);
- }
-
- /* Free the last unused buffer */
- g_free (buff);
-
- return total_len;
-}
-
-static void
-redirect_handler (SoupMessage *msg,
- gpointer user_data)
-{
- if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
- SoupSession *soup_session = user_data;
- SoupURI *new_uri;
- const gchar *new_loc;
-
- new_loc = soup_message_headers_get_list (msg->response_headers, "Location");
- if (!new_loc)
- return;
-
- new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc);
- if (!new_uri) {
- soup_message_set_status_full (
- msg,
- SOUP_STATUS_MALFORMED,
- "Invalid Redirect URL");
- return;
- }
-
- soup_message_set_uri (msg, new_uri);
- soup_session_requeue_message (soup_session, msg);
-
- soup_uri_free (new_uri);
- }
-}
-
-static void
-send_and_handle_redirection (SoupSession *session,
- SoupMessage *message,
- gchar **new_location)
-{
- gchar *old_uri = NULL;
-
- g_return_if_fail (message != NULL);
-
- if (new_location) {
- old_uri = soup_uri_to_string (soup_message_get_uri (message), FALSE);
- }
-
- soup_message_set_flags (message, SOUP_MESSAGE_NO_REDIRECT);
- soup_message_add_header_handler (
- message, "got_body", "Location",
- G_CALLBACK (redirect_handler), session);
- soup_message_headers_append (message->request_headers, "Connection", "close");
- soup_session_send_message (session, message);
-
- if (new_location) {
- gchar *new_loc = soup_uri_to_string (soup_message_get_uri (message), FALSE);
-
- if (new_loc && old_uri && !g_str_equal (new_loc, old_uri)) {
- *new_location = new_loc;
- } else {
- g_free (new_loc);
- }
- }
-
- g_free (old_uri);
-}
-
-static void
-web_view_process_http_uri_scheme_request (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- SoupURI *soup_uri;
- gchar *evo_uri, *uri;
- gchar *mail_uri;
- const gchar *user_cache_dir;
- const gchar *content_type;
- GInputStream *stream = NULL;
- gboolean force_load_images = FALSE;
- gboolean ret_val = FALSE;
- EImageLoadingPolicy image_policy;
- gchar *uri_md5;
- EShell *shell;
- GSettings *settings;
- CamelDataCache *cache;
- GIOStream *cache_stream;
- GHashTable *query;
- gint uri_len;
- WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
-
- /* Remove the __evo-mail query */
- soup_uri = soup_uri_new (webkit_uri_scheme_request_get_uri (request));
-
- if (!soup_uri_get_query (soup_uri)) {
- g_task_return_boolean (task, FALSE);
- soup_uri_free (soup_uri);
- return;
- }
-
- query = soup_form_decode (soup_uri_get_query (soup_uri));
- mail_uri = g_hash_table_lookup (query, "__evo-mail");
- if (mail_uri)
- mail_uri = g_strdup (mail_uri);
-
- g_hash_table_remove (query, "__evo-mail");
-
- /* Remove __evo-load-images if present (and in such case set
- * force_load_images to TRUE) */
- force_load_images = g_hash_table_remove (query, "__evo-load-images");
-
- soup_uri_set_query_from_form (soup_uri, query);
- g_hash_table_unref (query);
-
- evo_uri = soup_uri_to_string (soup_uri, FALSE);
-
- if (camel_debug_start ("emformat:requests")) {
- printf ("%s: looking for '%s'\n", G_STRFUNC, evo_uri);
- camel_debug_end ();
- }
-
- /* Remove the "evo-" prefix from scheme */
- uri_len = strlen (evo_uri);
- uri = NULL;
- if (evo_uri && (uri_len > 5)) {
- /* Remove trailing "?" if there is no URI query */
- if (evo_uri[uri_len - 1] == '?') {
- uri = g_strndup (evo_uri + 4, uri_len - 5);
- } else {
- uri = g_strdup (evo_uri + 4);
- }
- g_free (evo_uri);
- }
-
- if (!uri || !*uri)
- goto cleanup;
-
- /* Use MD5 hash of the URI as a filname of the resourec cache file.
- * We were previously using the URI as a filename but the URI is
- * sometimes too long for a filename. */
- uri_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
-
- /* Open Evolution's cache */
- user_cache_dir = e_get_user_cache_dir ();
- cache = camel_data_cache_new (user_cache_dir, NULL);
- camel_data_cache_set_expire_age (cache, 24 * 60 * 60);
- camel_data_cache_set_expire_access (cache, 2 * 60 * 60);
-
- /* Found item in cache! */
- cache_stream = camel_data_cache_get (cache, "http", uri_md5, NULL);
- if (cache_stream)
- goto process;
-
- /* If the item is not in the cache and Evolution is in offline mode then
- * quit regardless any image loading policy */
- shell = e_shell_get_default ();
- if (!e_shell_get_online (shell)) {
- goto cleanup;
- }
-
- settings = e_util_ref_settings ("org.gnome.evolution.mail");
- image_policy = g_settings_get_enum (settings, "image-loading-policy");
- g_object_unref (settings);
-
- /* Item not found in cache, but image loading policy allows us to fetch
- * it from the interwebs */
- if (!force_load_images && mail_uri &&
- (image_policy == E_IMAGE_LOADING_POLICY_SOMETIMES)) {
- CamelObjectBag *registry;
- gchar *decoded_uri;
- EMailPartList *part_list;
-
- registry = e_mail_part_list_get_registry ();
- decoded_uri = soup_uri_decode (mail_uri);
-
- part_list = camel_object_bag_get (registry, decoded_uri);
- if (part_list) {
- EShellBackend *shell_backend;
- EMailBackend *backend;
- EMailSession *session;
- CamelInternetAddress *addr;
- CamelMimeMessage *message;
- gboolean known_address = FALSE;
- GError *error = NULL;
-
- shell_backend =
- e_shell_get_backend_by_name (shell, "mail");
- backend = E_MAIL_BACKEND (shell_backend);
- session = e_mail_backend_get_session (backend);
-
- message = e_mail_part_list_get_message (part_list);
- addr = camel_mime_message_get_from (message);
-
- e_mail_ui_session_check_known_address_sync (
- E_MAIL_UI_SESSION (session),
- addr, FALSE, cancellable,
- &known_address, &error);
-
- if (error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_error_free (error);
- }
-
- if (known_address)
- force_load_images = TRUE;
-
- g_object_unref (part_list);
- }
-
- g_free (decoded_uri);
- }
-
- if ((image_policy == E_IMAGE_LOADING_POLICY_ALWAYS) ||
- force_load_images) {
-
- SoupSession *temp_session;
- SoupMessage *message;
- GIOStream *cache_stream;
- GError *error;
- GMainContext *context;
-
- message = soup_message_new (SOUP_METHOD_GET, uri);
- if (!message) {
- g_debug ("%s: Skipping invalid URI '%s'", G_STRFUNC, uri);
- goto cleanup;
- }
-
- context = g_main_context_new ();
- g_main_context_push_thread_default (context);
-
- temp_session = soup_session_new_with_options (
- SOUP_SESSION_TIMEOUT, 90, NULL);
-#if 0
-/* FIXME WK2 */
- e_binding_bind_property (
- soup_session, "proxy-resolver",
- temp_session, "proxy-resolver",
- G_BINDING_SYNC_CREATE);
-
-#endif
- soup_message_headers_append (
- message->request_headers, "User-Agent", "Evolution/" VERSION);
-/* FIXME WK2
- send_and_handle_redirection (session, message, NULL);*/
- send_and_handle_redirection (temp_session, message, NULL);
-
- if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
- g_warning ("Failed to request %s (code %d)", uri, message->status_code);
- goto cleanup;
- }
-
- /* Write the response body to cache */
- error = NULL;
- cache_stream = camel_data_cache_add (cache, "http", uri_md5, &error);
- if (error != NULL) {
- g_warning (
- "Failed to create cache file for '%s': %s",
- uri, error->message);
- g_clear_error (&error);
- } else {
- GOutputStream *output_stream;
-
- output_stream =
- g_io_stream_get_output_stream (cache_stream);
-
- g_output_stream_write_all (
- output_stream,
- message->response_body->data,
- message->response_body->length,
- NULL, cancellable, &error);
-
- g_io_stream_close (cache_stream, NULL, NULL);
- g_object_unref (cache_stream);
-
- if (error != NULL) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning (
- "Failed to write data to cache stream: %s",
- error->message);
- g_clear_error (&error);
- g_object_unref (message);
- g_object_unref (temp_session);
- g_main_context_unref (context);
- goto cleanup;
- }
- }
-
- g_object_unref (message);
-/* FIXME WK2
- g_object_unref (session);*/
- g_object_unref (temp_session);
- }
-
- process:
- if (cache_stream) {
- gssize len;
-
- stream = g_memory_input_stream_new ();
-
- len = copy_stream_to_stream (
- cache_stream,
- G_MEMORY_INPUT_STREAM (stream), cancellable);
-
- g_io_stream_close (cache_stream, NULL, NULL);
- g_object_unref (cache_stream);
-
- /* When succesfully read some data from cache then
- * get mimetype and return the stream to WebKit.
- * Otherwise try to fetch the resource again from the network. */
- if (len > 0) {
- GFile *file;
- GFileInfo *info;
- gchar *path;
-
- path = camel_data_cache_get_filename (cache, "http", uri_md5);
- file = g_file_new_for_path (path);
-
- info = g_file_query_info (
- file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- 0, cancellable, NULL);
-
- content_type = g_file_info_get_content_type (info);
-
- /* FIXME WK2 */
- webkit_uri_scheme_request_finish (
- request, stream, len, content_type);
-
- ret_val = TRUE;
-
- g_object_unref (request);
- g_object_unref (stream);
-
- d (
- printf ("'%s' found in cache (%d bytes, %s)\n",
- uri, len, content_type));
-
- g_object_unref (info);
- g_object_unref (file);
- g_free (path);
- } else {
- d (printf ("Failed to load '%s' from cache.\n", uri));
- }
- }
- cleanup:
- if (cache)
- g_clear_object (&cache);
-
- if (soup_uri)
- soup_uri_free (soup_uri);
-
- g_free (uri);
- g_free (uri_md5);
- g_free (mail_uri);
-
- g_task_return_boolean (task, ret_val);
-}
-
-static void
-mail_display_http_uri_scheme_appeared_cb (WebKitURISchemeRequest *request)
-{
- EMailDisplay *display;
- GTask *task;
- GCancellable *cancellable;
-
- display = E_MAIL_DISPLAY (webkit_uri_scheme_request_get_web_view (request));
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- cancellable = g_cancellable_new ();
-
- task = g_task_new (
- display, cancellable,
- (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
- request);
-
- g_task_set_task_data (task, g_object_ref (request), NULL);
- g_task_run_in_thread (task, web_view_process_http_uri_scheme_request);
-
- g_object_unref (task);
- g_object_unref (cancellable);
-}
-
-static void
-mail_display_process_mail_uri_scheme_request (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- GInputStream *input_stream = NULL;
- EMailFormatter *formatter;
- EMailPartList *part_list;
- GOutputStream *output_stream;
- GHashTable *query;
- const gchar *val, *uri;
- const gchar *default_charset, *charset;
- SoupURI *soup_uri;
- EMailFormatterContext context = { 0 };
- EMailDisplay *display = E_MAIL_DISPLAY (source_object);
- WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
- GBytes *bytes;
-
- uri = webkit_uri_scheme_request_get_uri (request);
-
- part_list = display->priv->part_list;
-
- if (camel_debug_start ("emformat:requests")) {
- printf ("%s: found part-list %p for full_uri '%s'\n", G_STRFUNC, part_list, uri);
- camel_debug_end ();
- }
-
- if (!part_list) {
- g_task_return_boolean (task, FALSE);
- return;
- }
-
- soup_uri = soup_uri_new (uri);
- if (!soup_uri || !soup_uri->query) {
- if (soup_uri)
- soup_uri_free (soup_uri);
- g_task_return_boolean (task, FALSE);
- return;
- }
- query = soup_form_decode (soup_uri->query);
-
- val = g_hash_table_lookup (query, "headers_collapsed");
- if (val && atoi (val) == 1)
- context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSED;
-
- val = g_hash_table_lookup (query, "headers_collapsable");
- if (val && atoi (val) == 1)
- context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSABLE;
-
- val = g_hash_table_lookup (query, "mode");
- if (val)
- context.mode = atoi (val);
-
- default_charset = g_hash_table_lookup (query, "formatter_default_charset");
- charset = g_hash_table_lookup (query, "formatter_charset");
-
- context.part_list = g_object_ref (part_list);
- context.uri = g_strdup (uri);
-
- formatter = display->priv->formatter;
-
- if (default_charset && *default_charset != '\0')
- e_mail_formatter_set_default_charset (formatter, default_charset);
- if (charset && *charset != '\0')
- e_mail_formatter_set_charset (formatter, charset);
-
- output_stream = g_memory_output_stream_new_resizable ();
-
- val = g_hash_table_lookup (query, "part_id");
- if (val) {
- EMailPart *part;
- const gchar *mime_type;
- gchar *part_id;
-
- part_id = soup_uri_decode (val);
- part = e_mail_part_list_ref_part (part_list, part_id);
- if (!part) {
- if (camel_debug_start ("emformat:requests")) {
- printf ("%s: part with id '%s' not found\n", G_STRFUNC, val);
- camel_debug_end ();
- }
-
- g_free (part_id);
- goto no_part;
- }
- g_free (part_id);
-
- mime_type = g_hash_table_lookup (query, "mime_type");
-
- if (context.mode == E_MAIL_FORMATTER_MODE_SOURCE)
- mime_type = "application/vnd.evolution.source";
-
- if (context.mode == E_MAIL_FORMATTER_MODE_CID) {
- CamelDataWrapper *dw;
- CamelMimePart *mime_part;
-
- mime_part = e_mail_part_ref_mime_part (part);
- dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
- if (!dw)
- goto no_part;
-
- camel_data_wrapper_decode_to_output_stream_sync (
- dw, output_stream, cancellable, NULL);
-
- g_object_unref (mime_part);
- } else {
- if (!mime_type)
- mime_type = e_mail_part_get_mime_type (part);
-
- e_mail_formatter_format_as (
- formatter, &context, part,
- output_stream, mime_type,
- cancellable);
- }
-
- g_object_unref (part);
- } else {
- e_mail_formatter_format_sync (
- formatter, part_list, output_stream,
- context.flags, context.mode, cancellable);
- }
-
- no_part:
- g_clear_object (&context.part_list);
-
- g_output_stream_close (output_stream, NULL, NULL);
-
- bytes = g_memory_output_stream_steal_as_bytes (
- G_MEMORY_OUTPUT_STREAM (output_stream));
-
- if (g_bytes_get_size (bytes) == 0) {
- gchar *data;
-
- g_bytes_unref (bytes);
-
- data = g_strdup_printf (
- "<p align='center'>%s</p>",
- _("The message has no text content."));
-
- /* Takes ownership of the string. */
- bytes = g_bytes_new_take (
- data, strlen (data) + 1);
- }
-
- input_stream =
- g_memory_input_stream_new_from_bytes (bytes);
-
- webkit_uri_scheme_request_finish (request, input_stream, -1, "text/html; charset=UTF-8");
-
- g_object_unref (input_stream);
- g_object_unref (output_stream);
-
- if (query)
- g_hash_table_destroy (query);
-
- if (soup_uri)
- soup_uri_free (soup_uri);
-
- g_task_return_boolean (task, TRUE);
-}
-
-static GInputStream *
-get_empty_image_stream (void)
-{
- GdkPixbuf *pixbuf;
- gchar *buffer;
- gsize length;
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
- gdk_pixbuf_fill (pixbuf, 0x00000000); /* transparent black */
- gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &length, "png", NULL, NULL);
- g_object_unref (pixbuf);
-
- return g_memory_input_stream_new_from_data (buffer, length, g_free);
-}
-
-static void
-mail_display_process_contact_photo_uri_scheme_request (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- EShell *shell;
- EShellBackend *shell_backend;
- EMailBackend *mail_backend;
- EMailSession *mail_session;
- EPhotoCache *photo_cache;
- CamelInternetAddress *cia;
- GInputStream *stream = NULL;
- const gchar *uri;
- const gchar *email_address;
- const gchar *escaped_string;
- gchar *unescaped_string;
- GError *error = NULL;
- SoupURI *soup_uri;
- GHashTable *uri_query;
- WebKitURISchemeRequest *request = WEBKIT_URI_SCHEME_REQUEST (task_data);
-
- /* XXX Is this really the only way to obtain
- * the mail session instance from here? */
- shell = e_shell_get_default ();
- shell_backend = e_shell_get_backend_by_name (shell, "mail");
- mail_backend = E_MAIL_BACKEND (shell_backend);
- mail_session = e_mail_backend_get_session (mail_backend);
-
- photo_cache = e_mail_ui_session_get_photo_cache (
- E_MAIL_UI_SESSION (mail_session));
-
- uri = webkit_uri_scheme_request_get_uri (request);
-
- soup_uri = soup_uri_new (uri);
- if (!soup_uri || !soup_uri->query)
- goto exit;
-
- uri_query = soup_form_decode (soup_uri->query);
- escaped_string = g_hash_table_lookup (uri_query, "mailaddr");
- if (escaped_string == NULL || *escaped_string == '\0')
- goto exit;
-
- cia = camel_internet_address_new ();
-
- unescaped_string = g_uri_unescape_string (escaped_string, NULL);
- camel_address_decode (CAMEL_ADDRESS (cia), unescaped_string);
- g_free (unescaped_string);
-
- if (camel_internet_address_get (cia, 0, NULL, &email_address))
- e_photo_cache_get_photo_sync (
- photo_cache, email_address,
- cancellable, &stream, &error);
-
- g_object_unref (cia);
-
- /* Ignore cancellations. */
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_clear_error (&error);
- } else if (error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_clear_error (&error);
- }
-
-exit:
- if (!stream)
- stream = get_empty_image_stream ();
-
- webkit_uri_scheme_request_finish (request, stream, -1, "image/*");
-
- g_object_unref (request);
- g_object_unref (stream);
-
- if (uri_query)
- g_hash_table_destroy (uri_query);
-
- if (soup_uri)
- soup_uri_free (soup_uri);
-
- g_task_return_boolean (task, TRUE);
-}
-
-static void
-mail_display_mail_uri_scheme_appeared_cb (WebKitURISchemeRequest *request)
-{
- EMailDisplay *display;
- GTask *task;
- GCancellable *cancellable;
- const gchar *uri;
-
- display = E_MAIL_DISPLAY (webkit_uri_scheme_request_get_web_view (request));
-
- g_return_if_fail (E_IS_MAIL_DISPLAY (display));
-
- cancellable = g_cancellable_new ();
-
- uri = webkit_uri_scheme_request_get_uri (request);
-
- task = g_task_new (
- display, cancellable,
- (GAsyncReadyCallback) mail_display_process_uri_scheme_finished_cb,
- request);
-
- g_task_set_task_data (task, g_object_ref (request), NULL);
-
- if (g_ascii_strncasecmp (uri, "mail://contact-photo", 20) == 0)
- g_task_run_in_thread (task, mail_display_process_contact_photo_uri_scheme_request);
- else
- g_task_run_in_thread (task, mail_display_process_mail_uri_scheme_request);
-
- g_object_unref (task);
- g_object_unref (cancellable);
-}
-
-static void
-mail_display_initialize_web_context (void)
-{
- WebKitWebContext *web_context = webkit_web_context_get_default ();
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "evo-http",
- (WebKitURISchemeRequestCallback) mail_display_http_uri_scheme_appeared_cb,
- NULL,
- NULL);
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "evo-https",
- (WebKitURISchemeRequestCallback) mail_display_http_uri_scheme_appeared_cb,
- NULL,
- NULL);
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "mail",
- (WebKitURISchemeRequestCallback) mail_display_mail_uri_scheme_appeared_cb,
- NULL,
- NULL);
-
- webkit_web_context_register_uri_scheme (
- web_context,
- "cid",
- (WebKitURISchemeRequestCallback) mail_display_cid_uri_scheme_appeared_cb,
- NULL,
- NULL);
-}
-
-static void
e_mail_display_class_init (EMailDisplayClass *class)
{
GObjectClass *object_class;
@@ -2549,8 +1762,6 @@ e_mail_display_class_init (EMailDisplayClass *class)
g_type_class_add_private (class, sizeof (EMailDisplayPrivate));
- mail_display_initialize_web_context ();
-
object_class = G_OBJECT_CLASS (class);
object_class->constructed = mail_display_constructed;
object_class->set_property = mail_display_set_property;
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index 49e175a..a75710d 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -15,19 +15,15 @@
*
*/
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include "e-mail-request.h"
-#include "em-utils.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <libsoup/soup.h>
-#include <libsoup/soup-requester.h>
-#include <libsoup/soup-request-http.h>
-
-#include <webkit2/webkit2.h>
#include <glib/gi18n.h>
#include <camel/camel.h>
+#include <libedataserver/libedataserver.h>
#include "shell/e-shell.h"
@@ -35,82 +31,92 @@
#include "em-format/e-mail-formatter-utils.h"
#include "em-format/e-mail-formatter-print.h"
+#include "em-utils.h"
#include "e-mail-ui-session.h"
+#include "e-mail-request.h"
#define d(x)
-#define dd(x)
-
-#define E_MAIL_REQUEST_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_MAIL_REQUEST, EMailRequestPrivate))
struct _EMailRequestPrivate {
- GBytes *bytes;
- gchar *mime_type;
+ gint dummy;
+};
- GHashTable *uri_query;
- gchar *uri_base;
- gchar *full_uri;
+static void e_mail_request_content_request_init (EContentRequestInterface *iface);
- gboolean part_converted_to_utf8;
- gchar *ret_mime_type;
-};
+G_DEFINE_TYPE_WITH_CODE (EMailRequest, e_mail_request, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (E_TYPE_CONTENT_REQUEST, e_mail_request_content_request_init))
-static const gchar *data_schemes[] = { "mail", NULL };
+static gboolean
+e_mail_request_can_process_uri (EContentRequest *request,
+ const gchar *uri)
+{
+ g_return_val_if_fail (E_IS_MAIL_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
-G_DEFINE_TYPE (EMailRequest, e_mail_request, SOUP_TYPE_REQUEST)
+ return g_ascii_strncasecmp (uri, "mail:", 5) == 0;
+}
-static void
-handle_mail_request (GSimpleAsyncResult *simple,
- GObject *object,
- GCancellable *cancellable)
+static gboolean
+mail_request_process_mail_sync (EContentRequest *request,
+ SoupURI *suri,
+ GHashTable *uri_query,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- EMailRequest *request = E_MAIL_REQUEST (object);
EMailFormatter *formatter;
EMailPartList *part_list;
CamelObjectBag *registry;
- GInputStream *input_stream;
GOutputStream *output_stream;
+ GBytes *bytes;
+ gchar *tmp, *use_mime_type = NULL;
const gchar *val;
const gchar *default_charset, *charset;
+ gboolean part_converted_to_utf8 = FALSE;
EMailFormatterContext context = { 0 };
- if (g_cancellable_is_cancelled (cancellable))
- return;
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ tmp = g_strdup_printf ("%s://%s%s", suri->scheme, suri->host, suri->path);
registry = e_mail_part_list_get_registry ();
- part_list = camel_object_bag_get (registry, request->priv->uri_base);
+ part_list = camel_object_bag_get (registry, tmp);
+
+ g_free (tmp);
+
+ context.uri = soup_uri_to_string (suri, FALSE);
if (camel_debug_start ("emformat:requests")) {
- printf ("%s: found part-list %p for full_uri '%s'\n", G_STRFUNC, part_list,
request->priv->full_uri);
+ printf ("%s: found part-list %p for full_uri '%s'\n", G_STRFUNC, part_list, context.uri);
camel_debug_end ();
}
- if (!part_list)
- return;
+ if (!part_list) {
+ g_free (context.uri);
+ return FALSE;
+ }
- val = g_hash_table_lookup (
- request->priv->uri_query, "headers_collapsed");
+ val = g_hash_table_lookup (uri_query, "headers_collapsed");
if (val != NULL && atoi (val) == 1)
context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSED;
- val = g_hash_table_lookup (
- request->priv->uri_query, "headers_collapsable");
+ val = g_hash_table_lookup (uri_query, "headers_collapsable");
if (val != NULL && atoi (val) == 1)
context.flags |= E_MAIL_FORMATTER_HEADER_FLAG_COLLAPSABLE;
- val = g_hash_table_lookup (request->priv->uri_query, "mode");
+ val = g_hash_table_lookup (uri_query, "mode");
if (val != NULL)
context.mode = atoi (val);
- default_charset = g_hash_table_lookup (
- request->priv->uri_query, "formatter_default_charset");
- charset = g_hash_table_lookup (
- request->priv->uri_query, "formatter_charset");
+ default_charset = g_hash_table_lookup (uri_query, "formatter_default_charset");
+ charset = g_hash_table_lookup (uri_query, "formatter_charset");
context.part_list = g_object_ref (part_list);
- context.uri = request->priv->full_uri;
if (context.mode == E_MAIL_FORMATTER_MODE_PRINTING)
formatter = e_mail_formatter_print_new ();
@@ -124,7 +130,7 @@ handle_mail_request (GSimpleAsyncResult *simple,
output_stream = g_memory_output_stream_new_resizable ();
- val = g_hash_table_lookup (request->priv->uri_query, "part_id");
+ val = g_hash_table_lookup (uri_query, "part_id");
if (val != NULL) {
EMailPart *part;
const gchar *mime_type;
@@ -143,8 +149,7 @@ handle_mail_request (GSimpleAsyncResult *simple,
}
g_free (part_id);
- mime_type = g_hash_table_lookup (
- request->priv->uri_query, "mime_type");
+ mime_type = g_hash_table_lookup (uri_query, "mime_type");
if (context.mode == E_MAIL_FORMATTER_MODE_SOURCE)
mime_type = "application/vnd.evolution.source";
@@ -155,11 +160,10 @@ handle_mail_request (GSimpleAsyncResult *simple,
mime_part = e_mail_part_ref_mime_part (part);
dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
- g_return_if_fail (dw);
+ g_return_val_if_fail (dw != NULL, FALSE);
if (!mime_type) {
- g_free (request->priv->mime_type);
- request->priv->mime_type = camel_data_wrapper_get_mime_type (dw);
+ use_mime_type = camel_data_wrapper_get_mime_type (dw);
}
camel_data_wrapper_decode_to_output_stream_sync (
@@ -175,7 +179,7 @@ handle_mail_request (GSimpleAsyncResult *simple,
output_stream, mime_type,
cancellable);
- request->priv->part_converted_to_utf8 = e_mail_part_get_converted_to_utf8 (part);
+ part_converted_to_utf8 = e_mail_part_get_converted_to_utf8 (part);
}
g_object_unref (part);
@@ -191,61 +195,54 @@ handle_mail_request (GSimpleAsyncResult *simple,
g_output_stream_close (output_stream, NULL, NULL);
- if (request->priv->bytes != NULL)
- g_bytes_unref (request->priv->bytes);
-
- request->priv->bytes = g_memory_output_stream_steal_as_bytes (
- G_MEMORY_OUTPUT_STREAM (output_stream));
+ bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output_stream));
- if (g_bytes_get_size (request->priv->bytes) == 0) {
+ if (g_bytes_get_size (bytes) == 0) {
gchar *data;
- g_bytes_unref (request->priv->bytes);
+ g_bytes_unref (bytes);
data = g_strdup_printf (
"<p align='center'>%s</p>",
_("The message has no text content."));
/* Takes ownership of the string. */
- request->priv->bytes = g_bytes_new_take (
- data, strlen (data) + 1);
+ bytes = g_bytes_new_take (data, strlen (data) + 1);
}
- input_stream =
- g_memory_input_stream_new_from_bytes (request->priv->bytes);
+ if (!use_mime_type)
+ use_mime_type = g_strdup ("text/html");
- g_simple_async_result_set_op_res_gpointer (
- simple, g_object_ref (input_stream),
- (GDestroyNotify) g_object_unref);
+ if (part_converted_to_utf8 && g_strcmp0 (use_mime_type, "text/html") == 0) {
+ tmp = g_strconcat (use_mime_type, "; charset=\"UTF-8\"", NULL);
+ g_free (use_mime_type);
+ use_mime_type = tmp;
+ }
- g_object_unref (input_stream);
- g_object_unref (output_stream);
+ *out_stream = g_memory_input_stream_new_from_bytes (bytes);
+ *out_stream_length = g_bytes_get_size (bytes);
+ *out_mime_type = use_mime_type;
+ g_object_unref (output_stream);
g_object_unref (part_list);
g_object_unref (formatter);
-}
-
-static GInputStream *
-get_empty_image_stream (void)
-{
- GdkPixbuf *pixbuf;
- gchar *buffer;
- gsize length;
+ g_bytes_unref (bytes);
+ g_free (context.uri);
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
- gdk_pixbuf_fill (pixbuf, 0x00000000); /* transparent black */
- gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &length, "png", NULL, NULL);
- g_object_unref (pixbuf);
-
- return g_memory_input_stream_new_from_data (buffer, length, g_free);
+ return TRUE;
}
-static void
-handle_contact_photo_request (GSimpleAsyncResult *simple,
- GObject *object,
- GCancellable *cancellable)
+static gboolean
+mail_request_process_contact_photo_sync (EContentRequest *request,
+ SoupURI *suri,
+ GHashTable *uri_query,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- EMailRequest *request = E_MAIL_REQUEST (object);
EShell *shell;
EShellBackend *shell_backend;
EMailBackend *mail_backend;
@@ -256,227 +253,171 @@ handle_contact_photo_request (GSimpleAsyncResult *simple,
const gchar *email_address;
const gchar *escaped_string;
gchar *unescaped_string;
- GError *error = NULL;
+ gboolean success = FALSE;
- /* XXX Is this really the only way to obtain
- * the mail session instance from here? */
shell = e_shell_get_default ();
shell_backend = e_shell_get_backend_by_name (shell, "mail");
mail_backend = E_MAIL_BACKEND (shell_backend);
mail_session = e_mail_backend_get_session (mail_backend);
- photo_cache = e_mail_ui_session_get_photo_cache (
- E_MAIL_UI_SESSION (mail_session));
-
- request->priv->mime_type = g_strdup ("image/*");
-
- escaped_string = g_hash_table_lookup (
- request->priv->uri_query, "mailaddr");
- if (escaped_string == NULL || *escaped_string == '\0')
- goto exit;
+ photo_cache = e_mail_ui_session_get_photo_cache (E_MAIL_UI_SESSION (mail_session));
- cia = camel_internet_address_new ();
+ escaped_string = g_hash_table_lookup (uri_query, "mailaddr");
+ if (escaped_string && *escaped_string) {
+ cia = camel_internet_address_new ();
- unescaped_string = g_uri_unescape_string (escaped_string, NULL);
- camel_address_decode (CAMEL_ADDRESS (cia), unescaped_string);
- g_free (unescaped_string);
+ unescaped_string = g_uri_unescape_string (escaped_string, NULL);
+ camel_address_decode (CAMEL_ADDRESS (cia), unescaped_string);
+ g_free (unescaped_string);
- if (camel_internet_address_get (cia, 0, NULL, &email_address))
- e_photo_cache_get_photo_sync (
- photo_cache, email_address,
- cancellable, &stream, &error);
+ if (camel_internet_address_get (cia, 0, NULL, &email_address))
+ success = e_photo_cache_get_photo_sync (
+ photo_cache, email_address,
+ cancellable, &stream, error);
- g_object_unref (cia);
+ g_object_unref (cia);
- /* Ignore cancellations. */
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_clear_error (&error);
- } else if (error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_clear_error (&error);
+ if (success) {
+ *out_stream = stream;
+ *out_stream_length = -1;
+ *out_mime_type = g_strdup ("image/*");
+ }
}
-exit:
- if (stream == NULL)
- stream = get_empty_image_stream ();
-
- g_simple_async_result_set_op_res_gpointer (
- simple, g_object_ref (stream),
- (GDestroyNotify) g_object_unref);
-
- g_object_unref (stream);
+ return success;
}
-static void
-mail_request_finalize (GObject *object)
+typedef struct _MailIdleData
{
- EMailRequestPrivate *priv;
+ EContentRequest *request;
+ SoupURI *suri;
+ GHashTable *uri_query;
+ GObject *requester;
+ GInputStream **out_stream;
+ gint64 *out_stream_length;
+ gchar **out_mime_type;
+ GCancellable *cancellable;
+ GError **error;
+
+ gboolean success;
+ EFlag *flag;
+} MailIdleData;
- priv = E_MAIL_REQUEST_GET_PRIVATE (object);
+static gboolean
+process_mail_request_idle_cb (gpointer user_data)
+{
+ MailIdleData *mid = user_data;
- if (priv->bytes != NULL)
- g_bytes_unref (priv->bytes);
+ g_return_val_if_fail (mid != NULL, FALSE);
+ g_return_val_if_fail (E_IS_MAIL_REQUEST (mid->request), FALSE);
+ g_return_val_if_fail (mid->suri != NULL, FALSE);
+ g_return_val_if_fail (mid->flag != NULL, FALSE);
- if (priv->uri_query != NULL)
- g_hash_table_destroy (priv->uri_query);
+ mid->success = mail_request_process_mail_sync (mid->request,
+ mid->suri, mid->uri_query, mid->requester, mid->out_stream,
+ mid->out_stream_length, mid->out_mime_type,
+ mid->cancellable, mid->error);
- g_free (priv->mime_type);
- g_free (priv->uri_base);
- g_free (priv->full_uri);
- g_free (priv->ret_mime_type);
+ e_flag_set (mid->flag);
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_mail_request_parent_class)->finalize (object);
+ return FALSE;
}
static gboolean
-mail_request_check_uri (SoupRequest *request,
- SoupURI *uri,
- GError **error)
-{
- return (strcmp (uri->scheme, "mail") == 0);
-}
-
-static void
-mail_request_send_async (SoupRequest *request,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_mail_request_process_sync (EContentRequest *request,
+ const gchar *uri,
+ GObject *requester,
+ GInputStream **out_stream,
+ gint64 *out_stream_length,
+ gchar **out_mime_type,
+ GCancellable *cancellable,
+ GError **error)
{
- EMailRequestPrivate *priv;
- GSimpleAsyncResult *simple;
- SoupURI *uri;
+ SoupURI *suri;
+ GHashTable *uri_query;
+ gboolean success = FALSE;
- priv = E_MAIL_REQUEST_GET_PRIVATE (request);
+ g_return_val_if_fail (E_IS_MAIL_REQUEST (request), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
- uri = soup_request_get_uri (request);
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
- d (printf ("received request for %s\n", soup_uri_to_string (uri, FALSE)));
+ suri = soup_uri_new (uri);
+ g_return_val_if_fail (suri != NULL, FALSE);
- if (uri->query) {
- priv->uri_query = soup_form_decode (uri->query);
+ if (suri->query) {
+ uri_query = soup_form_decode (suri->query);
} else {
- priv->uri_query = NULL;
+ uri_query = NULL;
}
- priv->full_uri = soup_uri_to_string (uri, FALSE);
- priv->uri_base = g_strdup_printf (
- "%s://%s%s", uri->scheme, uri->host, uri->path);
-
- simple = g_simple_async_result_new (
- G_OBJECT (request), callback,
- user_data, mail_request_send_async);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- if (g_strcmp0 (uri->host, "contact-photo") == 0) {
- e_util_run_simple_async_result_in_thread (
- simple, handle_contact_photo_request,
- cancellable);
+ if (g_strcmp0 (suri->host, "contact-photo") == 0) {
+ success = mail_request_process_contact_photo_sync (request, suri, uri_query, requester,
+ out_stream, out_stream_length, out_mime_type, cancellable, error);
} else {
- /* Process e-mail mail requests in this thread, which should be
- * the main/UI thread, because any EMailFormatter can create
- * GtkWidget-s, or manipulate with them, which should be always
- * done in the main/UI thread. */
- handle_mail_request (simple, G_OBJECT (request), cancellable);
- g_simple_async_result_complete_in_idle (simple);
- }
-
- g_object_unref (simple);
-}
-
-static GInputStream *
-mail_request_send_finish (SoupRequest *request,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- GInputStream *stream;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- stream = g_simple_async_result_get_op_res_gpointer (simple);
+ MailIdleData mid;
+
+ mid.request = request;
+ mid.suri = suri;
+ mid.uri_query = uri_query;
+ mid.requester = requester;
+ mid.out_stream = out_stream;
+ mid.out_stream_length = out_stream_length;
+ mid.out_mime_type = out_mime_type;
+ mid.cancellable = cancellable;
+ mid.error = error;
+ mid.flag = e_flag_new ();
+ mid.success = FALSE;
+
+ if (e_util_is_main_thread (NULL)) {
+ process_mail_request_idle_cb (&mid);
+ } else {
+ /* Process e-mail mail requests in this thread, which should be
+ * the main/UI thread, because any EMailFormatter can create
+ * GtkWidget-s, or manipulate with them, which should be always
+ * done in the main/UI thread. */
+ g_idle_add_full (
+ G_PRIORITY_HIGH_IDLE,
+ process_mail_request_idle_cb,
+ &mid, NULL);
+
+ e_flag_wait (mid.flag);
+ }
- /* Reset the stream before passing it back to webkit */
- if (G_IS_SEEKABLE (stream))
- g_seekable_seek (
- G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
+ e_flag_free (mid.flag);
- if (stream == NULL) {
- /* We must always return something */
- stream = g_memory_input_stream_new ();
- } else {
- g_object_ref (stream);
+ success = mid.success;
}
- return stream;
-}
+ if (uri_query)
+ g_hash_table_destroy (uri_query);
+ soup_uri_free (suri);
-static goffset
-mail_request_get_content_length (SoupRequest *request)
-{
- EMailRequestPrivate *priv;
- goffset content_length = -1; /* -1 means unknown */
-
- priv = E_MAIL_REQUEST_GET_PRIVATE (request);
-
- if (priv->bytes != NULL)
- content_length = g_bytes_get_size (priv->bytes);
-
- return content_length;
+ return success;
}
-static const gchar *
-mail_request_get_content_type (SoupRequest *request)
+static void
+e_mail_request_content_request_init (EContentRequestInterface *iface)
{
- EMailRequestPrivate *priv;
- gchar *mime_type;
-
- priv = E_MAIL_REQUEST_GET_PRIVATE (request);
-
- if (priv->mime_type != NULL) {
- mime_type = g_strdup (priv->mime_type);
- } else {
- mime_type = g_strdup ("text/html");
- }
-
- if (g_strcmp0 (mime_type, "text/html") == 0 &&
- priv->part_converted_to_utf8) {
- priv->ret_mime_type = g_strconcat (
- mime_type, "; charset=\"UTF-8\"", NULL);
- g_free (mime_type);
- } else {
- priv->ret_mime_type = mime_type;
- }
-
- d (printf ("Content-Type: %s\n", priv->ret_mime_type));
-
- return priv->ret_mime_type;
+ iface->can_process_uri = e_mail_request_can_process_uri;
+ iface->process_sync = e_mail_request_process_sync;
}
static void
e_mail_request_class_init (EMailRequestClass *class)
{
- GObjectClass *object_class;
- SoupRequestClass *request_class;
-
g_type_class_add_private (class, sizeof (EMailRequestPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = mail_request_finalize;
-
- request_class = SOUP_REQUEST_CLASS (class);
- request_class->schemes = data_schemes;
- request_class->send_async = mail_request_send_async;
- request_class->send_finish = mail_request_send_finish;
- request_class->get_content_type = mail_request_get_content_type;
- request_class->get_content_length = mail_request_get_content_length;
- request_class->check_uri = mail_request_check_uri;
}
static void
e_mail_request_init (EMailRequest *request)
{
- request->priv = E_MAIL_REQUEST_GET_PRIVATE (request);
- request->priv->part_converted_to_utf8 = FALSE;
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, E_TYPE_MAIL_REQUEST, EMailRequestPrivate);
}
+EContentRequest *
+e_mail_request_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_REQUEST, NULL);
+}
diff --git a/mail/e-mail-request.h b/mail/e-mail-request.h
index c85266e..cd35992 100644
--- a/mail/e-mail-request.h
+++ b/mail/e-mail-request.h
@@ -18,10 +18,7 @@
#ifndef E_MAIL_REQUEST_H
#define E_MAIL_REQUEST_H
-#define LIBSOUP_USE_UNSTABLE_REQUEST_API
-
-#include <libsoup/soup.h>
-#include <libsoup/soup-request.h>
+#include <e-util/e-util.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_REQUEST \
@@ -49,15 +46,17 @@ typedef struct _EMailRequestClass EMailRequestClass;
typedef struct _EMailRequestPrivate EMailRequestPrivate;
struct _EMailRequest {
- SoupRequest parent;
+ GObject parent;
EMailRequestPrivate *priv;
};
struct _EMailRequestClass {
- SoupRequestClass parent;
+ GObjectClass parent;
};
GType e_mail_request_get_type (void) G_GNUC_CONST;
+EContentRequest *
+ e_mail_request_new (void);
G_END_DECLS
diff --git a/shell/main.c b/shell/main.c
index 8b898b5..6788ac2 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -569,6 +569,7 @@ main (gint argc,
handle_term_signal, NULL, NULL);
#endif
+ e_util_init_main_thread (NULL);
e_passwords_init ();
gtk_window_set_default_icon_name ("evolution");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]