[geary/bug/728002-webkit2: 83/140] Allow ClientWebView resources to be loaded via either cid or geary URLs.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/bug/728002-webkit2: 83/140] Allow ClientWebView resources to be loaded via either cid or geary URLs.
- Date: Tue, 31 Jan 2017 23:05:31 +0000 (UTC)
commit 70cbe4a046ca1c1a33145aa40e5074e7a2c3eb62
Author: Michael James Gratton <mike vee net>
Date: Sat Jan 14 22:20:36 2017 +1100
Allow ClientWebView resources to be loaded via either cid or geary URLs.
* src/client/components/client-web-view.vala (ClientWebView): Rename
members referring to inline resources to internal resources, update
call sites.
(ClientWebView::handle_cid_request,
ClientWebView::handle_internal_request): Rework to use new common
::handle_internal_response method.
* src/client/web-process/web-process-extension.vala: Permit by default
any geary, cid, or data URI request.
src/client/components/client-web-view.vala | 54 +++++++++++++-------
src/client/composer/composer-widget.vala | 12 ++--
.../conversation-viewer/conversation-email.vala | 6 +-
.../conversation-viewer/conversation-message.vala | 2 +-
src/client/web-process/web-process-extension.vala | 13 ++---
5 files changed, 49 insertions(+), 38 deletions(-)
---
diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala
index 79e9179..08c7e5e 100644
--- a/src/client/components/client-web-view.vala
+++ b/src/client/components/client-web-view.vala
@@ -182,7 +182,7 @@ public class ClientWebView : WebKit.WebView {
private weak string? body = null;
- private Gee.Map<string,Geary.Memory.Buffer> cid_resources =
+ private Gee.Map<string,Geary.Memory.Buffer> internal_resources =
new Gee.HashMap<string,Geary.Memory.Buffer>();
private int preferred_height = 0;
@@ -194,8 +194,8 @@ public class ClientWebView : WebKit.WebView {
/** Emitted when a user clicks a link in this web view. */
public signal void link_activated(string uri);
- /** Emitted when the web view has loaded an inline part. */
- public signal void inline_resource_loaded(string cid);
+ /** Emitted when the view has loaded a resource added to it. */
+ public signal void internal_resource_loaded(string name);
/** Emitted when a remote image load was disallowed. */
public signal void remote_image_load_blocked();
@@ -294,17 +294,24 @@ public class ClientWebView : WebKit.WebView {
}
/**
- * Adds an inline resource that may be accessed via a cid:id url.
+ * Adds an resource that may be accessed from the view via a URL.
+ *
+ * Internal resources may be access via both the internal `geary`
+ * scheme (for resources such as an image inserted via the
+ * composer) or via the `cid` scheme (for standard HTML email IMG
+ * elements).
*/
- public void add_inline_resource(string id, Geary.Memory.Buffer buf) {
- this.cid_resources[id] = buf;
+ public void add_internal_resource(string id, Geary.Memory.Buffer buf) {
+ this.internal_resources[id] = buf;
}
/**
- * Adds a set of inline resource that may be accessed via a cid:id url.
+ * Adds a set of internal resources to the view.
+ *
+ * @see add_internal_resource
*/
- public void add_inline_resources(Gee.Map<string,Geary.Memory.Buffer> res) {
- this.cid_resources.set_all(res);
+ public void add_internal_resources(Gee.Map<string,Geary.Memory.Buffer> res) {
+ this.internal_resources.set_all(res);
}
/**
@@ -379,15 +386,8 @@ public class ClientWebView : WebKit.WebView {
}
private void handle_cid_request(WebKit.URISchemeRequest request) {
- string cid = request.get_uri().substring(CID_URL_PREFIX.length);
- Geary.Memory.Buffer? buf = this.cid_resources[cid];
- if (buf != null) {
- request.finish(buf.get_input_stream(), buf.size, null);
- inline_resource_loaded(cid);
- } else {
- request.finish_error(
- new FileError.NOENT("Unknown CID: %s".printf(cid))
- );
+ if (!handle_internal_response(request)) {
+ request.finish_error(new FileError.NOENT("Unknown CID"));
}
}
@@ -395,11 +395,23 @@ public class ClientWebView : WebKit.WebView {
if (request.get_uri() == INTERNAL_URL_BODY) {
Geary.Memory.Buffer buf = new Geary.Memory.StringBuffer(this.body);
request.finish(buf.get_input_stream(), buf.size, null);
- } else {
+ } else if (!handle_internal_response(request)) {
request.finish_error(new FileError.NOENT("Unknown internal URL"));
}
}
+ private bool handle_internal_response(WebKit.URISchemeRequest request) {
+ string name = soup_uri_decode(request.get_path());
+ Geary.Memory.Buffer? buf = this.internal_resources[name];
+ bool handled = false;
+ if (buf != null) {
+ request.finish(buf.get_input_stream(), buf.size, null);
+ internal_resource_loaded(name);
+ handled = true;
+ }
+ return handled;
+ }
+
// Only allow string-based page loads, and notify but ignore if
// the user attempts to click on a link. Deny everything else.
private bool on_decide_policy(WebKit.WebView view,
@@ -454,3 +466,7 @@ public class ClientWebView : WebKit.WebView {
}
}
+
+// XXX this needs to be moved into the libsoup bindings
+extern string soup_uri_decode(string part);
+
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index f95b91d..4b8c627 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -1427,8 +1427,9 @@ public class ComposerWidget : Gtk.EventBox {
if (this.pending_attachments != null) {
foreach(Geary.Attachment part in this.pending_attachments) {
try {
+ string? content_id = part.content_id;
Geary.Mime.DispositionType? type =
- part.content_disposition.disposition_type;
+ part.content_disposition.disposition_type;
File file = part.file;
if (type == Geary.Mime.DispositionType.INLINE) {
// We only care about the Content Ids of
@@ -1438,11 +1439,10 @@ public class ComposerWidget : Gtk.EventBox {
// possible to be referenced from an IMG SRC
// using a cid: URL anyway, so treat it as an
// attachment instead.
- if (part.content_id != null) {
- this.cid_files[part.content_id] = file;
- this.editor.add_inline_resource(
- part.content_id,
- new Geary.Memory.FileBuffer(file, true)
+ if (content_id != null) {
+ this.cid_files[content_id] = file;
+ this.editor.add_internal_resource(
+ content_id, new Geary.Memory.FileBuffer(file, true)
);
} else {
type = Geary.Mime.DispositionType.ATTACHMENT;
diff --git a/src/client/conversation-viewer/conversation-email.vala
b/src/client/conversation-viewer/conversation-email.vala
index 4ea63f3..e24ff84 100644
--- a/src/client/conversation-viewer/conversation-email.vala
+++ b/src/client/conversation-viewer/conversation-email.vala
@@ -453,7 +453,7 @@ public class ConversationEmail : Gtk.Box {
}
this.primary_message = new ConversationMessage(message, config, load_images);
- this.primary_message.web_view.add_inline_resources(cid_resources);
+ this.primary_message.web_view.add_internal_resources(cid_resources);
connect_message_view_signals(this.primary_message);
this.primary_message.summary.add(this.actions);
@@ -494,7 +494,7 @@ public class ConversationEmail : Gtk.Box {
ConversationMessage attached_message =
new ConversationMessage(sub_message, config, false);
connect_message_view_signals(attached_message);
- attached_message.web_view.add_inline_resources(cid_resources);
+ attached_message.web_view.add_internal_resources(cid_resources);
this.sub_messages.add(attached_message);
this._attached_messages.add(attached_message);
}
@@ -627,7 +627,7 @@ public class ConversationEmail : Gtk.Box {
private void connect_message_view_signals(ConversationMessage view) {
view.flag_remote_images.connect(on_flag_remote_images);
view.remember_remote_images.connect(on_remember_remote_images);
- view.web_view.inline_resource_loaded.connect((id) => {
+ view.web_view.internal_resource_loaded.connect((id) => {
this.inlined_content_ids.add(id);
});
view.web_view.notify["has-valid-height"].connect(() => {
diff --git a/src/client/conversation-viewer/conversation-message.vala
b/src/client/conversation-viewer/conversation-message.vala
index 9758abf..86fb187 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -707,7 +707,7 @@ public class ConversationMessage : Gtk.Grid {
id = REPLACED_CID_TEMPLATE.printf(this.next_replaced_buffer_number++);
}
- this.web_view.add_inline_resource(id, buffer);
+ this.web_view.add_internal_resource(id, buffer);
return "<img alt=\"%s\" class=\"%s\" src=\"%s%s\" />".printf(
Geary.HTML.escape_markup(filename),
diff --git a/src/client/web-process/web-process-extension.vala
b/src/client/web-process/web-process-extension.vala
index ac7efc4..1b4980b 100644
--- a/src/client/web-process/web-process-extension.vala
+++ b/src/client/web-process/web-process-extension.vala
@@ -29,10 +29,7 @@ public void webkit_web_extension_initialize_with_user_data(WebKit.WebExtension e
public class GearyWebExtension : Object {
- private const string CID_URL_PREFIX = "cid:";
- private const string DATA_URL_PREFIX = "data:";
- private const string INTERNAL_URL_PREFIX = "geary:";
- private const string INTERNAL_URL_BODY = INTERNAL_URL_PREFIX + "body";
+ private const string[] ALLOWED_SCHEMES = { "cid", "geary", "data" };
private WebKit.WebExtension extension;
@@ -64,11 +61,9 @@ public class GearyWebExtension : Object {
WebKit.URIRequest request,
WebKit.URIResponse? response) {
bool should_load = false;
- string req_uri = request.get_uri();
- if (req_uri.has_prefix(CID_URL_PREFIX) ||
- req_uri.has_prefix(DATA_URL_PREFIX) ||
- req_uri == INTERNAL_URL_BODY) {
- // Always load images/resources with these prefixes
+ Soup.URI? uri = new Soup.URI(request.get_uri());
+ if (uri != null && uri.get_scheme() in ALLOWED_SCHEMES) {
+ // Always load internal resources
should_load = true;
} else {
// Only load anything else if remote image loading is
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]