[epiphany] Use EphyDownload for pdf.js support
- From: Jan-Michael Brummer <jbrummer src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Use EphyDownload for pdf.js support
- Date: Tue, 21 Jan 2020 05:58:17 +0000 (UTC)
commit 316966bb7a8501149322c14b3371e7548006adda
Author: Jan-Michael Brummer <jan brummer tabos org>
Date: Sun Jan 19 13:59:42 2020 +0100
Use EphyDownload for pdf.js support
Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/1059
embed/ephy-embed-shell.c | 15 +++++-
embed/ephy-embed.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++
embed/ephy-embed.h | 2 +
embed/ephy-web-view.c | 67 ------------------------
4 files changed, 150 insertions(+), 68 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 213411e54..9b4c1f712 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -776,6 +776,7 @@ download_started_cb (WebKitWebContext *web_context,
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
g_autoptr (EphyDownload) ephy_download = NULL;
gboolean ephy_download_set;
+ WebKitWebView *web_view;
/* Is download locked down? */
if (g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN,
@@ -794,7 +795,19 @@ download_started_cb (WebKitWebContext *web_context,
return;
ephy_download = ephy_download_new (download);
- ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
+
+ web_view = webkit_download_get_web_view (download);
+ if (EPHY_IS_WEB_VIEW (web_view)) {
+ EphyEmbed *embed;
+
+ embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view);
+ ephy_embed_download_started (embed, ephy_download);
+
+ if (!ephy_web_view_in_pdf_viewer (EPHY_WEB_VIEW (web_view)))
+ ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
+ } else {
+ ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
+ }
}
static void
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index aaaa5e159..208730764 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -996,3 +996,137 @@ ephy_embed_detach_notification_container (EphyEmbed *embed)
gtk_container_remove (GTK_CONTAINER (embed->overlay), g_object_ref (GTK_WIDGET (container)));
}
}
+
+typedef struct {
+ char *document_uri;
+ char *remote_uri;
+ WebKitDownload *download;
+ EphyWebView *web_view;
+} PdfAsyncData;
+
+static PdfAsyncData *
+pdf_async_data_new (const char *document_uri,
+ const char *remote_uri,
+ EphyWebView *web_view)
+{
+ PdfAsyncData *data;
+
+ data = g_new0 (PdfAsyncData, 1);
+ data->document_uri = g_strdup (document_uri);
+ data->remote_uri = g_strdup (remote_uri);
+ data->web_view = web_view;
+
+ if (web_view)
+ g_object_add_weak_pointer (G_OBJECT (web_view), (gpointer *)&data->web_view);
+
+ return data;
+}
+
+static void
+pdf_async_data_free (PdfAsyncData *data)
+{
+ if (data->web_view)
+ g_object_remove_weak_pointer (G_OBJECT (data->web_view), (gpointer *)&data->web_view);
+
+ g_free (data->document_uri);
+ g_free (data->remote_uri);
+ g_free (data);
+}
+
+static void
+pdf_file_deleted (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr (GError) error = NULL;
+ if (!g_file_delete_finish (G_FILE (source), res, &error))
+ g_warning ("Could not delete temporary PDF file: %s", error->message);
+}
+
+static void
+pdf_file_loaded (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PdfAsyncData *data = user_data;
+ WebKitWebView *web_view = WEBKIT_WEB_VIEW (data->web_view);
+ GBytes *html_file;
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GString) html = NULL;
+ g_autofree gchar *b64 = NULL;
+ g_autofree gchar *requested_uri = NULL;
+ g_autofree char *file_data = NULL;
+ gsize len = 0;
+
+ if (!g_file_load_contents_finish (G_FILE (source), res, &file_data, &len, NULL, &error)) {
+ g_warning ("Could not read PDF file content: %s", error->message);
+ pdf_async_data_free (data);
+ return;
+ }
+
+ html_file = g_resources_lookup_data ("/org/gnome/epiphany/pdfjs/web/viewer.html", 0, NULL);
+
+ b64 = g_base64_encode ((const guchar *)file_data, len);
+ g_file_delete_async (G_FILE (source), G_PRIORITY_DEFAULT, NULL, pdf_file_deleted, NULL);
+
+ html = g_string_new ("");
+ g_string_printf (html, g_bytes_get_data (html_file, NULL), b64, g_path_get_basename (data->remote_uri));
+
+ webkit_web_view_load_alternate_html (web_view, html->str, data->remote_uri,
"ephy-resource:///org/gnome/epiphany/pdfjs/web/");
+
+ /* FIXME: Necessary WebKit API to access security level (TLS certificate) of a download is not
+ * available. Please fix this line once available.
+ */
+ ephy_web_view_set_security_level (data->web_view, EPHY_SECURITY_LEVEL_LOCAL_PAGE);
+
+ pdf_async_data_free (data);
+}
+
+static void
+pdf_download_finished_cb (WebKitDownload *download,
+ EphyEmbed *embed)
+{
+ EphyWebView *view = ephy_embed_get_web_view (embed);
+ WebKitURIRequest *request = webkit_download_get_request (download);
+ g_autoptr (GFile) file = NULL;
+ PdfAsyncData *pdf_data;
+ const char *document_uri = webkit_download_get_destination (download);
+ const char *remote_uri = webkit_uri_request_get_uri (request);
+
+ file = g_file_new_for_uri (document_uri);
+
+ pdf_data = pdf_async_data_new (document_uri, remote_uri, view);
+ g_file_load_contents_async (file, NULL, pdf_file_loaded, pdf_data);
+}
+
+static gboolean
+pdf_download_decide_destination_cb (WebKitDownload *wk_download,
+ gchar *suggested_filename,
+ gpointer user_data)
+{
+ EphyWebView *web_view = ephy_embed_get_web_view (EPHY_EMBED (user_data));
+
+ if (ephy_web_view_in_pdf_viewer (web_view)) {
+ g_autofree gchar *tmp_file = g_strdup_printf ("%s/%s", g_get_tmp_dir (), suggested_filename);
+ g_autofree gchar *file_uri = g_filename_to_uri (tmp_file, NULL, NULL);
+
+ webkit_download_set_allow_overwrite (wk_download, TRUE);
+ webkit_download_set_destination (wk_download, file_uri);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+ephy_embed_download_started (EphyEmbed *embed,
+ EphyDownload *ephy_download)
+{
+ EphyWebView *web_view = ephy_embed_get_web_view (embed);
+ WebKitDownload *download = ephy_download_get_webkit_download (ephy_download);
+
+ if (ephy_web_view_in_pdf_viewer (web_view)) {
+ g_signal_connect_object (download, "finished", G_CALLBACK (pdf_download_finished_cb), embed, 0);
+ g_signal_connect_object (download, "decide-destination", G_CALLBACK
(pdf_download_decide_destination_cb), embed, 0);
+ }
+}
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index 919a6d366..5004bffcd 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -54,5 +54,7 @@ gboolean ephy_embed_inspector_is_loaded (EphyEmbed *embed);
const char *ephy_embed_get_title (EphyEmbed *embed);
void ephy_embed_attach_notification_container (EphyEmbed *embed);
void ephy_embed_detach_notification_container (EphyEmbed *embed);
+void ephy_embed_download_started (EphyEmbed *embed,
+ EphyDownload *ephy_download);
G_END_DECLS
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index ebe28e15a..49f59f9b7 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -858,68 +858,6 @@ ephy_web_view_style_updated (GtkWidget *web_view)
webkit_web_view_set_background_color (WEBKIT_WEB_VIEW (web_view), &color);
}
-/**
- * TODO: Please note that we are currently making use of soup function to download
- * the requested pdf file. This is due to an issue with EphyDownload emitting download
- * finished signal before the file really exists in 50% of the cases. That
- * would lead to a very bad pdf experience therefore we are using soup.
- * Please switch to EphyDownload as soon as the issue is fixed.
- */
-static void
-pdf_loaded (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
-{
- WebKitWebView *web_view = WEBKIT_WEB_VIEW (user_data);
- EphyWebView *view = EPHY_WEB_VIEW (web_view);
- GBytes *html_file;
- g_autoptr (GString) html = NULL;
- g_autofree gchar *b64 = NULL;
- SoupURI *uri = NULL;
- g_autofree gchar *requested_uri = NULL;
-
- if (msg->status_code != 200) {
- g_warning ("PDF file could not be loaded, got status code %d\n", msg->status_code);
- return;
- }
-
- html_file = g_resources_lookup_data ("/org/gnome/epiphany/pdfjs/web/viewer.html", 0, NULL);
- b64 = g_base64_encode ((const guchar *)msg->response_body->data, msg->response_body->length);
-
- uri = soup_message_get_uri (msg);
-
- html = g_string_new ("");
- g_string_printf (html, g_bytes_get_data (html_file, NULL), b64, g_path_get_basename (uri->path));
- requested_uri = soup_uri_to_string (uri, FALSE);
-
- /* FIXME: Remove this, and remove the hack from update_security_status_for_committed_load(),
- * when we switch from SoupSession to EphyDownload.
- *
- * We are using SoupSession directly, bypassing WebKit's functionality for ignoring
- * TLS certificate errors, so we should be guaranteed there are no security issues
- */
- if (!strcmp (SOUP_URI_SCHEME_HTTPS, soup_uri_get_scheme (uri)))
- ephy_web_view_set_security_level (view, EPHY_SECURITY_LEVEL_STRONG_SECURITY);
- else
- ephy_web_view_set_security_level (view, EPHY_SECURITY_LEVEL_TO_BE_DETERMINED);
-
- webkit_web_view_load_alternate_html (web_view, html->str, requested_uri,
"ephy-resource:///org/gnome/epiphany/pdfjs/web/");
-
- g_object_unref (session);
-}
-
-static void
-load_pdf (WebKitWebView *web_view,
- const gchar *request_uri)
-{
- SoupSession *session = soup_session_new ();
- SoupMessage *msg;
-
- msg = soup_message_new ("GET", request_uri);
-
- soup_session_queue_message (session, g_steal_pointer (&msg), pdf_loaded, web_view);
-}
-
static gboolean
ephy_web_view_decide_policy (WebKitWebView *web_view,
WebKitPolicyDecision *decision,
@@ -946,11 +884,6 @@ ephy_web_view_decide_policy (WebKitWebView *web_view,
EphyWebView *view = EPHY_WEB_VIEW (web_view);
view->in_pdf_viewer = TRUE;
- webkit_policy_decision_ignore (decision);
-
- load_pdf (web_view, request_uri);
-
- return FALSE;
}
/* If WebKit can't handle the mime type start the download
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]