[epiphany] uri-tester: Never block the UI process main thread



commit 5da7d07062b31c1accbd202e412f13209bf13a24
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Sat Nov 26 19:02:07 2016 +0100

    uri-tester: Never block the UI process main thread
    
    Split the uri tester into updater and loader/filter. The updater code is
    done directly by EphyEmbedShell. The loader/filter part is what URITester
    is now, and it has been moved to the web extension again. The web extension
    creates the uri tester, but it doesn't use it until required and the
    load happens synchronously. This way it's now the web process the one
    waiting until everything is ready to load requests, leaving the UI
    process always responsive. I've also moved the previous checks to decide
    whether to apply adblock or https everywhere rules on a resource to the
    web extension, as well as the tracking queries handling, to avoid
    loading all the rules for resources that are not going to be filtered at
    all. This makes loading overview pages a lot faster, for example. I've
    also added a few more conditions to ensure we don't run the uri tester
    if it's not actually required.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775067

 configure.ac                                       |    2 +-
 embed/Makefile.am                                  |    2 -
 embed/ephy-embed-shell.c                           |  234 ++++++++-
 embed/web-extension/Makefile.am                    |    6 +-
 embed/web-extension/ephy-uri-tester-proxy.c        |  120 ----
 embed/{ => web-extension}/ephy-uri-tester.c        |  585 ++++----------------
 .../web-extension/ephy-uri-tester.h                |   32 +-
 embed/web-extension/ephy-web-extension-main.c      |    4 +-
 embed/web-extension/ephy-web-extension.c           |  206 +++++--
 embed/web-extension/ephy-web-extension.h           |    2 +-
 lib/Makefile.am                                    |    3 +-
 lib/ephy-dbus-names.h                              |    4 -
 .../ephy-uri-tester-shared.c                       |   37 +-
 .../ephy-uri-tester-shared.h                       |   11 +-
 14 files changed, 536 insertions(+), 712 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5fee50e..e3446dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@ LIBGD_INIT([_view-common notification static])
 
 LT_LIB_M
 
-GLIB_REQUIRED=2.44.0
+GLIB_REQUIRED=2.46.0
 GTK_REQUIRED=3.22.0
 WEBKITGTK_REQUIRED=2.15.2
 
diff --git a/embed/Makefile.am b/embed/Makefile.am
index 8d5f98b..b57c9d4 100644
--- a/embed/Makefile.am
+++ b/embed/Makefile.am
@@ -41,8 +41,6 @@ libephyembed_la_SOURCES = \
        ephy-find-toolbar.h             \
        ephy-notification-container.c   \
        ephy-notification-container.h   \
-       ephy-uri-tester.c               \
-       ephy-uri-tester.h               \
        ephy-view-source-handler.c      \
        ephy-view-source-handler.h      \
        ephy-web-view.c                 \
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 2ecc330..db3aa3c 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -34,19 +34,22 @@
 #include "ephy-profile-utils.h"
 #include "ephy-settings.h"
 #include "ephy-snapshot-service.h"
-#include "ephy-uri-tester.h"
+#include "ephy-uri-tester-shared.h"
 #include "ephy-view-source-handler.h"
 #include "ephy-web-app-utils.h"
 #include "ephy-web-extension-proxy.h"
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
+#include <httpseverywhere.h>
 #include <stdlib.h>
 
 #define PAGE_SETUP_FILENAME "page-setup-gtk.ini"
 #define PRINT_SETTINGS_FILENAME "print-settings.ini"
 #define OVERVIEW_RELOAD_DELAY 500
 
+#define ADBLOCK_FILTER_UPDATE_FREQUENCY 24 * 60 * 60 /* In seconds */
+
 typedef struct {
   WebKitWebContext *web_context;
   EphyHistoryService *global_history_service;
@@ -61,9 +64,11 @@ typedef struct {
   EphyViewSourceHandler *source_handler;
   guint update_overview_timeout_id;
   guint hiding_overview_item;
-  EphyUriTester *uri_tester;
   GDBusServer *dbus_server;
   GList *web_extensions;
+
+  char *adblock_data_dir;
+  GCancellable *uri_tester_update_cancellable;
 } EphyEmbedShellPrivate;
 
 enum {
@@ -96,6 +101,11 @@ ephy_embed_shell_dispose (GObject *object)
 {
   EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (EPHY_EMBED_SHELL (object));
 
+  if (priv->uri_tester_update_cancellable) {
+    g_cancellable_cancel (priv->uri_tester_update_cancellable);
+    g_clear_object (&priv->uri_tester_update_cancellable);
+  }
+
   if (priv->update_overview_timeout_id > 0) {
     g_source_remove (priv->update_overview_timeout_id);
     priv->update_overview_timeout_id = 0;
@@ -111,13 +121,22 @@ ephy_embed_shell_dispose (GObject *object)
   g_clear_object (&priv->downloads_manager);
   g_clear_object (&priv->hosts_manager);
   g_clear_object (&priv->web_context);
-  g_clear_object (&priv->uri_tester);
   g_clear_object (&priv->dbus_server);
 
   G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object);
 }
 
 static void
+ephy_embed_shell_finalize (GObject *object)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (EPHY_EMBED_SHELL (object));
+
+  g_free (priv->adblock_data_dir);
+
+  G_OBJECT_CLASS (ephy_embed_shell_parent_class)->finalize (object);
+}
+
+static void
 web_extension_form_auth_data_message_received_cb (WebKitUserContentManager *manager,
                                                   WebKitJavascriptResult   *message,
                                                   EphyEmbedShell           *shell)
@@ -567,6 +586,204 @@ ftp_request_cb (WebKitURISchemeRequest *request)
 }
 
 static void
+https_everywhere_update_cb (HTTPSEverywhereUpdater *updater,
+                            GAsyncResult           *result)
+{
+  GError *error = NULL;
+
+  https_everywhere_updater_update_finish (updater, result, &error);
+
+  if (!error)
+    return;
+
+  if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+      !g_error_matches (error, HTTPS_EVERYWHERE_UPDATE_ERROR, HTTPS_EVERYWHERE_UPDATE_ERROR_IN_PROGRESS) &&
+      !g_error_matches (error, HTTPS_EVERYWHERE_UPDATE_ERROR, 
HTTPS_EVERYWHERE_UPDATE_ERROR_NO_UPDATE_AVAILABLE))
+    g_warning ("Failed to update HTTPS Everywhere rulesets: %s", error->message);
+  g_error_free (error);
+}
+
+static const char *
+ephy_embed_shell_ensure_adblock_data_dir (EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  if (priv->adblock_data_dir)
+    return priv->adblock_data_dir;
+
+  /* The filters list is large, so we don't want to store a separate copy per
+   * web app, but users should otherwise be able to configure different filters
+   * per profile directory. */
+  if (priv->mode == EPHY_EMBED_SHELL_MODE_APPLICATION) {
+    char *default_dot_dir = ephy_default_dot_dir ();
+
+    priv->adblock_data_dir = g_build_filename (default_dot_dir, "adblock", NULL);
+    g_free (default_dot_dir);
+  } else
+    priv->adblock_data_dir = g_build_filename (ephy_dot_dir (), "adblock", NULL);
+  g_mkdir_with_parents (priv->adblock_data_dir, 0700);
+
+  return priv->adblock_data_dir;
+}
+
+static gboolean
+adblock_filter_file_is_valid (GFile *file)
+{
+  GFileInfo *file_info;
+  gboolean result = FALSE;
+
+  /* Now check if the local file is too old. */
+  file_info = g_file_query_info (file,
+                                 G_FILE_ATTRIBUTE_TIME_MODIFIED","G_FILE_ATTRIBUTE_STANDARD_SIZE,
+                                 G_FILE_QUERY_INFO_NONE,
+                                 NULL,
+                                 NULL);
+  if (file_info) {
+    if (g_file_info_get_size (file_info) > 0) {
+      GTimeVal current_time;
+      GTimeVal mod_time;
+
+      g_get_current_time (&current_time);
+      g_file_info_get_modification_time (file_info, &mod_time);
+
+      if (current_time.tv_sec > mod_time.tv_sec) {
+        gint64 expire_time = mod_time.tv_sec + ADBLOCK_FILTER_UPDATE_FREQUENCY;
+
+        result = current_time.tv_sec < expire_time;
+      }
+    }
+    g_object_unref (file_info);
+  }
+
+  return result;
+}
+
+typedef struct {
+  EphyEmbedShell *shell;
+
+  GFile *filter_file;
+  GFile *tmp_file;
+} AdblockFilterRetrieveData;
+
+static AdblockFilterRetrieveData *
+adblock_filter_retrieve_data_new (EphyEmbedShell *shell,
+                                  GFile          *filter_file)
+{
+  AdblockFilterRetrieveData* data;
+  char *path, *tmp_path;
+
+  data = g_slice_new (AdblockFilterRetrieveData);
+  data->shell = g_object_ref (shell);
+  data->filter_file = g_object_ref (filter_file);
+
+  path = g_file_get_path (filter_file);
+  tmp_path = g_strdup_printf ("%s.tmp", path);
+  g_free (path);
+  data->tmp_file = g_file_new_for_path (tmp_path);
+  g_free (tmp_path);
+
+  return data;
+}
+
+static void
+adblock_filter_retrieve_data_free (AdblockFilterRetrieveData *data)
+{
+  g_object_unref (data->shell);
+  g_object_unref (data->filter_file);
+  g_object_unref (data->tmp_file);
+
+  g_slice_free (AdblockFilterRetrieveData, data);
+}
+
+static void
+ephy_embed_shell_retrieve_filter_file_finished (GFile                     *src,
+                                                GAsyncResult              *result,
+                                                AdblockFilterRetrieveData *data)
+{
+  GError *error = NULL;
+
+  if (!g_file_copy_finish (src, result, &error) ||
+      !g_file_move (data->tmp_file, data->filter_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
+    GFileOutputStream *stream;
+
+    /* If failed to retrieve, create an empty file if it doesn't exist to unblock extensions */
+    stream = g_file_create (data->filter_file, G_FILE_CREATE_NONE, NULL, NULL);
+    g_object_unref (stream);
+
+    if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+      g_warning ("Error retrieving filter: %s\n", error->message);
+    g_error_free (error);
+  }
+
+  adblock_filter_retrieve_data_free (data);
+}
+
+static void
+ephy_embed_shell_retrieve_filter_file (EphyEmbedShell *shell,
+                                       GFile          *file)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+  GFile *src = g_file_new_for_uri (ADBLOCK_FILTER_URL);
+  AdblockFilterRetrieveData *data;
+
+  if (!priv->uri_tester_update_cancellable)
+    priv->uri_tester_update_cancellable = g_cancellable_new ();
+
+  data = adblock_filter_retrieve_data_new (shell, file);
+
+  g_file_copy_async (src, data->tmp_file,
+                     G_FILE_COPY_OVERWRITE,
+                     G_PRIORITY_DEFAULT,
+                     priv->uri_tester_update_cancellable,
+                     NULL, NULL,
+                     (GAsyncReadyCallback)ephy_embed_shell_retrieve_filter_file_finished,
+                     data);
+
+  g_object_unref (src);
+}
+
+static void
+ephy_embed_shell_update_adblock_filter_file (EphyEmbedShell *shell)
+{
+  GFile *filter_file;
+
+  filter_file = ephy_uri_tester_get_adblock_filer_file (ephy_embed_shell_ensure_adblock_data_dir (shell));
+
+  if (!adblock_filter_file_is_valid (filter_file))
+    ephy_embed_shell_retrieve_filter_file (shell, filter_file);
+
+  g_object_unref (filter_file);
+}
+
+static void
+ephy_embed_shell_update_uri_tester (EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  ephy_embed_shell_update_adblock_filter_file (shell);
+
+  if (priv->mode != EPHY_EMBED_SHELL_MODE_TEST &&
+      priv->mode != EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER) {
+    HTTPSEverywhereContext *context;
+    HTTPSEverywhereUpdater *updater;
+
+    if (!priv->uri_tester_update_cancellable)
+      priv->uri_tester_update_cancellable = g_cancellable_new ();
+
+    /* We might want to be smarter about this in the future. For now,
+     * trigger an update of the rulesets once each time Epiphany is started. */
+    context = https_everywhere_context_new ();
+    updater = https_everywhere_updater_new (context);
+    https_everywhere_updater_update (updater,
+                                     priv->uri_tester_update_cancellable,
+                                     (GAsyncReadyCallback)https_everywhere_update_cb,
+                                     NULL);
+    g_object_unref (context);
+    g_object_unref (updater);
+  }
+}
+
+static void
 web_extension_destroyed (EphyEmbedShell *shell,
                          GObject        *web_extension)
 {
@@ -606,9 +823,10 @@ initialize_web_extensions (WebKitWebContext *web_context,
   address = priv->dbus_server ? g_dbus_server_get_client_address (priv->dbus_server) : NULL;
 
   private_profile = EPHY_EMBED_SHELL_MODE_HAS_PRIVATE_PROFILE (priv->mode);
-  user_data = g_variant_new ("(mssb)",
+  user_data = g_variant_new ("(msssb)",
                              address,
                              ephy_dot_dir (),
+                             ephy_embed_shell_ensure_adblock_data_dir (shell),
                              private_profile);
   webkit_web_context_set_web_extensions_initialization_user_data (web_context, user_data);
 }
@@ -627,14 +845,11 @@ new_connection_cb (GDBusServer     *server,
                    GDBusConnection *connection,
                    EphyEmbedShell  *shell)
 {
-  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
   EphyWebExtensionProxy *extension;
 
   extension = ephy_web_extension_proxy_new (connection);
   ephy_embed_shell_watch_web_extension (shell, extension);
 
-  ephy_uri_tester_handle_new_dbus_connection (priv->uri_tester, connection);
-
   g_signal_connect_object (extension, "page-created",
                            G_CALLBACK (web_extension_page_created), shell, 0);
 
@@ -759,9 +974,9 @@ ephy_embed_shell_startup (GApplication *application)
 
   G_APPLICATION_CLASS (ephy_embed_shell_parent_class)->startup (application);
 
-  ephy_embed_shell_create_web_context (embed_shell);
+  ephy_embed_shell_update_uri_tester (embed_shell);
 
-  priv->uri_tester = ephy_uri_tester_new ();
+  ephy_embed_shell_create_web_context (embed_shell);
 
   ephy_embed_shell_setup_web_extensions_server (shell);
 
@@ -951,6 +1166,7 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
   GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
 
   object_class->dispose = ephy_embed_shell_dispose;
+  object_class->finalize = ephy_embed_shell_finalize;
   object_class->set_property = ephy_embed_shell_set_property;
   object_class->get_property = ephy_embed_shell_get_property;
   object_class->constructed = ephy_embed_shell_constructed;
diff --git a/embed/web-extension/Makefile.am b/embed/web-extension/Makefile.am
index 5e5a9a9..bf091ae 100644
--- a/embed/web-extension/Makefile.am
+++ b/embed/web-extension/Makefile.am
@@ -5,8 +5,8 @@ webextensiondir = $(pkglibdir)/web-extensions
 libephywebextension_la_SOURCES = \
        ephy-embed-form-auth.c          \
        ephy-embed-form-auth.h          \
-       ephy-uri-tester-proxy.c         \
-       ephy-uri-tester-proxy.h         \
+       ephy-uri-tester.c               \
+       ephy-uri-tester.h               \
        ephy-web-dom-utils.c            \
        ephy-web-dom-utils.h            \
        ephy-web-extension.c            \
@@ -24,6 +24,7 @@ libephywebextension_la_CPPFLAGS = \
        $(GTK_CFLAGS)                   \
        $(LIBSECRET_CFLAGS)             \
        $(LIBSOUP_CFLAGS)               \
+       $(HTTPSEVERYWHERE_CFLAGS)       \
        $(WEBKIT2GTK_WEB_EXTENSION_CFLAGS)
 
 libephywebextension_la_CFLAGS = \
@@ -39,6 +40,7 @@ libephywebextension_la_LIBADD = \
        $(GTK_LIBS)             \
        $(LIBSECRET_LIBS)       \
        $(LIBSOUP_LIBS)         \
+       $(HTTPSEVERYWHERE_LIBS) \
        $(WEBKIT2GTK_WEB_EXTENSION_LIBS)
 
 -include $(top_srcdir)/git.mk
diff --git a/embed/ephy-uri-tester.c b/embed/web-extension/ephy-uri-tester.c
similarity index 57%
rename from embed/ephy-uri-tester.c
rename to embed/web-extension/ephy-uri-tester.c
index a592fda..43fd3c3 100644
--- a/embed/ephy-uri-tester.c
+++ b/embed/web-extension/ephy-uri-tester.c
@@ -27,13 +27,8 @@
 #include "config.h"
 #include "ephy-uri-tester.h"
 
-#include "ephy-dbus-names.h"
 #include "ephy-debug.h"
-#include "ephy-embed-shell.h"
-#include "ephy-file-helpers.h"
-#include "ephy-settings.h"
-#include "ephy-uri-helpers.h"
-#include "ephy-uri-tester-interface.h"
+#include "ephy-uri-tester-shared.h"
 
 #include <gio/gio.h>
 #include <glib/gstdio.h>
@@ -41,14 +36,12 @@
 #include <libsoup/soup.h>
 #include <string.h>
 
-#define DEFAULT_FILTER_URL "https://easylist-downloads.adblockplus.org/easylist.txt";
 #define SIGNATURE_SIZE 8
-#define UPDATE_FREQUENCY 24 * 60 * 60 /* In seconds */
 
 struct _EphyUriTester {
   GObject parent_instance;
 
-  char *data_dir;
+  char *adblock_data_dir;
 
   GHashTable *pattern;
   GHashTable *keys;
@@ -68,17 +61,16 @@ struct _EphyUriTester {
   GRegex *regex_subdocument;
   GRegex *regex_frame_add;
 
-  GCancellable *cancellable;
+  GMainLoop *load_loop;
+  gboolean adblock_loaded;
+  gboolean https_everywhere_loaded;
 
   HTTPSEverywhereContext *https_everywhere_context;
-  GList *deferred_requests;
-
-  GList *dbus_peers;
 };
 
 enum {
   PROP_0,
-  PROP_BASE_DATA_DIR,
+  PROP_ADBLOCK_DATA_DIR,
   LAST_PROP
 };
 
@@ -86,171 +78,9 @@ static GParamSpec *obj_properties[LAST_PROP];
 
 G_DEFINE_TYPE (EphyUriTester, ephy_uri_tester, G_TYPE_OBJECT)
 
-typedef struct {
-  char *request_uri;
-  char *page_uri;
-  EphyUriTestFlags flags;
-  GDBusMethodInvocation *invocation;
-} DeferredRequest;
-
-static DeferredRequest *
-deferred_request_new (const char            *request_uri,
-                      const char            *page_uri,
-                      EphyUriTestFlags       flags,
-                      GDBusMethodInvocation *invocation)
-{
-  DeferredRequest *request = g_slice_new (DeferredRequest);
-  request->request_uri = g_strdup (request_uri);
-  request->page_uri = g_strdup (page_uri);
-  request->flags = flags;
-  /* Ownership of invocation is passed to g_dbus_method_invocation_return_value(). */
-  request->invocation = invocation;
-  return request;
-}
-
-static void
-deferred_request_free (DeferredRequest *request)
-{
-  g_free (request->request_uri);
-  g_free (request->page_uri);
-  g_slice_free (DeferredRequest, request);
-}
-
 static GString *
 ephy_uri_tester_fixup_regexp (const char *prefix, char *src);
 
-static void
-ephy_uri_tester_parse_file_at_uri (EphyUriTester *tester, GFile *file);
-
-static char *
-ephy_uri_tester_ensure_data_dir (const char *base_data_dir)
-{
-  char *folder;
-
-  /* Ensure adblock's dir is there. */
-  folder = g_build_filename (base_data_dir, "adblock", NULL);
-  g_mkdir_with_parents (folder, 0700);
-
-  return folder;
-}
-
-static char *
-ephy_uri_tester_get_fileuri_for_url (EphyUriTester *tester,
-                                     const char    *url)
-{
-  char *filename = NULL;
-  char *path = NULL;
-  char *uri = NULL;
-
-  if (!strncmp (url, "file", 4))
-    return g_strndup (url + 7, strlen (url) - 7);
-
-  filename = g_compute_checksum_for_string (G_CHECKSUM_MD5, url, -1);
-
-  path = g_build_filename (tester->data_dir, filename, NULL);
-  uri = g_filename_to_uri (path, NULL, NULL);
-
-  g_free (filename);
-  g_free (path);
-
-  return uri;
-}
-
-typedef struct {
-  EphyUriTester *tester;
-  GFile *dest_file;
-} RetrieveFilterAsyncData;
-
-static void
-ephy_uri_tester_retrieve_filter_finished (GFile                   *src,
-                                          GAsyncResult            *result,
-                                          RetrieveFilterAsyncData *data)
-{
-  GError *error = NULL;
-
-  if (!g_file_copy_finish (src, result, &error)) {
-    LOG ("Error retrieving filter: %s\n", error->message);
-    g_error_free (error);
-  } else
-    ephy_uri_tester_parse_file_at_uri (data->tester, data->dest_file);
-
-  g_object_unref (data->tester);
-  g_object_unref (data->dest_file);
-  g_slice_free (RetrieveFilterAsyncData, data);
-}
-
-static void
-ephy_uri_tester_retrieve_filter (EphyUriTester *tester,
-                                 const char    *url,
-                                 GFile         *file)
-{
-  GFile *src;
-  RetrieveFilterAsyncData *data;
-
-  src = g_file_new_for_uri (url);
-
-  data = g_slice_new (RetrieveFilterAsyncData);
-  data->tester = g_object_ref (tester);
-  data->dest_file = g_object_ref (file);
-
-  g_file_copy_async (src, file,
-                     G_FILE_COPY_OVERWRITE,
-                     G_PRIORITY_DEFAULT,
-                     NULL, NULL, NULL,
-                     (GAsyncReadyCallback)ephy_uri_tester_retrieve_filter_finished,
-                     data);
-
-  g_object_unref (src);
-}
-
-static gboolean
-ephy_uri_tester_filter_is_valid (GFile *file)
-{
-  GFileInfo *file_info = NULL;
-  gboolean result;
-
-  /* Now check if the local file is too old. */
-  file_info = g_file_query_info (file,
-                                 G_FILE_ATTRIBUTE_TIME_MODIFIED,
-                                 G_FILE_QUERY_INFO_NONE,
-                                 NULL,
-                                 NULL);
-  result = FALSE;
-  if (file_info) {
-    GTimeVal current_time;
-    GTimeVal mod_time;
-
-    g_get_current_time (&current_time);
-    g_file_info_get_modification_time (file_info, &mod_time);
-
-    if (current_time.tv_sec > mod_time.tv_sec) {
-      gint64 expire_time = mod_time.tv_sec + UPDATE_FREQUENCY;
-      result = current_time.tv_sec < expire_time;
-    }
-    g_object_unref (file_info);
-  }
-
-  return result;
-}
-
-static void
-ephy_uri_tester_load_patterns (EphyUriTester *tester)
-{
-  char *fileuri;
-  GFile *file;
-
-  fileuri = ephy_uri_tester_get_fileuri_for_url (tester, DEFAULT_FILTER_URL);
-  file = g_file_new_for_uri (fileuri);
-  g_free (fileuri);
-
-  if (!ephy_uri_tester_filter_is_valid (file))
-    ephy_uri_tester_retrieve_filter (tester, DEFAULT_FILTER_URL, file);
-  else
-    ephy_uri_tester_parse_file_at_uri (tester, file);
-
-  g_object_unref (file);
-}
-
 static inline int
 ephy_uri_tester_check_rule (EphyUriTester *tester,
                             GRegex        *regex,
@@ -672,6 +502,22 @@ ephy_uri_tester_parse_line (EphyUriTester *tester,
 }
 
 static void
+ephy_uri_tester_adblock_loaded (EphyUriTester *tester)
+{
+  tester->adblock_loaded = TRUE;
+  if (tester->https_everywhere_loaded)
+    g_main_loop_quit (tester->load_loop);
+}
+
+static void
+ephy_uri_tester_https_everywhere_loaded (EphyUriTester *tester)
+{
+  tester->https_everywhere_loaded = TRUE;
+  if (tester->adblock_loaded)
+    g_main_loop_quit (tester->load_loop);
+}
+
+static void
 file_parse_cb (GDataInputStream *stream, GAsyncResult *result, EphyUriTester *tester)
 {
   char *line;
@@ -684,6 +530,7 @@ file_parse_cb (GDataInputStream *stream, GAsyncResult *result, EphyUriTester *te
       g_error_free (error);
     }
 
+    ephy_uri_tester_adblock_loaded (tester);
     return;
   }
 
@@ -710,6 +557,7 @@ file_read_cb (GFile *file, GAsyncResult *result, EphyUriTester *tester)
     g_free (path);
     g_error_free (error);
 
+    ephy_uri_tester_adblock_loaded (tester);
     return;
   }
 
@@ -721,280 +569,114 @@ file_read_cb (GFile *file, GAsyncResult *result, EphyUriTester *tester)
   g_object_unref (data_stream);
 }
 
-static void
-ephy_uri_tester_parse_file_at_uri (EphyUriTester *tester, GFile *file)
-{
-  g_file_read_async (file, G_PRIORITY_DEFAULT_IDLE, NULL, (GAsyncReadyCallback)file_read_cb, tester);
-}
-
 static gboolean
-ephy_uri_tester_test_uri (EphyUriTester *tester,
+ephy_uri_tester_block_uri (EphyUriTester *tester,
                           const char    *req_uri,
                           const char    *page_uri)
 {
-  /* Always load the main resource. */
-  if (g_strcmp0 (req_uri, page_uri) == 0)
-    return FALSE;
-
-  /* Always load data requests, as uri_tester won't do any good here. */
-  if (g_str_has_prefix (req_uri, SOUP_URI_SCHEME_DATA))
-    return FALSE;
-
   /* check whitelisting rules before the normal ones */
   if (ephy_uri_tester_is_matched (tester, NULL, req_uri, page_uri, TRUE))
     return FALSE;
   return ephy_uri_tester_is_matched (tester, NULL, req_uri, page_uri, FALSE);
 }
 
-static char *
+char *
 ephy_uri_tester_rewrite_uri (EphyUriTester    *tester,
                              const char       *request_uri,
                              const char       *page_uri,
                              EphyUriTestFlags  flags)
 {
-  char *modified_uri = NULL;
-  char *result;
-
   /* Should we block the URL outright? */
   if ((flags & EPHY_URI_TEST_ADBLOCK) &&
-      ephy_uri_tester_test_uri (tester, request_uri, page_uri)) {
+      ephy_uri_tester_block_uri (tester, request_uri, page_uri)) {
     g_debug ("Request '%s' blocked (page: '%s')", request_uri, page_uri);
-    return g_strdup ("");
-  }
-
-  if ((flags & EPHY_URI_TEST_TRACKING_QUERIES)) {
-    /* Remove analytics from URL. Note that this function is a bit annoying to
-     * use: it returns NULL if it doesn't remove any query parameters. */
-    modified_uri = ephy_remove_tracking_from_uri (request_uri);
-  }
-
-  if (!modified_uri)
-    modified_uri = g_strdup (request_uri);
-
-  if ((flags & EPHY_URI_TEST_HTTPS_EVERYWHERE) &&
-      g_str_has_prefix (request_uri, "http://";)) {
-    result = https_everywhere_context_rewrite (tester->https_everywhere_context,
-                                               modified_uri);
-    g_free (modified_uri);
-  } else {
-    result = modified_uri;
-  }
-
-  return result;
-}
 
-typedef struct {
-  EphyUriTester *tester;
-  GDBusConnection *connection;
-  guint registration_id;
-} DBusPeerInfo;
-
-static DBusPeerInfo *
-dbus_peer_info_new (EphyUriTester   *tester,
-                    GDBusConnection *connection,
-                    guint            registration_id)
-{
-  DBusPeerInfo *peer = g_slice_new (DBusPeerInfo);
-  peer->tester = tester;
-  peer->connection = g_object_ref (connection);
-  peer->registration_id = registration_id;
-  return peer;
-}
-
-static void
-dbus_peer_info_free (DBusPeerInfo *peer)
-{
-  g_signal_handlers_disconnect_by_data (peer->connection, peer);
-
-  g_object_unref (peer->connection);
-  g_slice_free (DBusPeerInfo, peer);
-}
-
-static void
-dbus_connection_closed_cb (GDBusConnection *connection,
-                           gboolean         remote_peer_vanished,
-                           GError          *error,
-                           DBusPeerInfo    *peer)
-{
-  peer->tester->dbus_peers = g_list_remove (peer->tester->dbus_peers, peer);
-  dbus_peer_info_free (peer);
-}
-
-static void
-ephy_uri_tester_return_response (EphyUriTester         *tester,
-                                 const char            *request_uri,
-                                 const char            *page_uri,
-                                 EphyUriTestFlags       flags,
-                                 GDBusMethodInvocation *invocation)
-{
-  char *rewritten_uri;
-  rewritten_uri = ephy_uri_tester_rewrite_uri (tester, request_uri, page_uri, flags);
-  g_dbus_method_invocation_return_value (invocation,
-                                         g_variant_new ("(s)", rewritten_uri));
-  g_free (rewritten_uri);
-}
-
-static void
-handle_method_call (GDBusConnection       *connection,
-                    const char            *sender,
-                    const char            *object_path,
-                    const char            *interface_name,
-                    const char            *method_name,
-                    GVariant              *parameters,
-                    GDBusMethodInvocation *invocation,
-                    gpointer               user_data)
-{
-  EphyUriTester *tester = EPHY_URI_TESTER (user_data);
-  EphyUriTestFlags flags = 0;
-
-  if (g_strcmp0 (interface_name, EPHY_URI_TESTER_INTERFACE) != 0)
-    return;
-
-  if (g_strcmp0 (method_name, "MaybeRewriteUri") == 0) {
-    const char *request_uri;
-    const char *page_uri;
-
-    g_variant_get (parameters, "(&s&si)", &request_uri, &page_uri, &flags);
-
-    if (request_uri == NULL || request_uri == '\0') {
-      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-                                             "Request URI cannot be NULL or empty");
-      return;
-    }
-
-    if (page_uri == NULL || page_uri == '\0') {
-      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-                                             "Page URI cannot be NULL or empty");
-      return;
-    }
-
-    if ((flags & EPHY_URI_TEST_HTTPS_EVERYWHERE) == 0 ||
-        !g_str_has_prefix (request_uri, "http://";) ||
-        https_everywhere_context_get_initialized (tester->https_everywhere_context)) {
-      ephy_uri_tester_return_response (tester, request_uri, page_uri, flags, invocation);
-    } else {
-      DeferredRequest *request = deferred_request_new (request_uri, page_uri, flags, invocation);
-      tester->deferred_requests = g_list_append (tester->deferred_requests, request);
-    }
-  }
-}
-
-static const GDBusInterfaceVTable interface_vtable = {
-  handle_method_call,
-  NULL,
-  NULL
-};
-
-void
-ephy_uri_tester_handle_new_dbus_connection (EphyUriTester   *tester,
-                                            GDBusConnection *connection)
-{
-  static GDBusNodeInfo *introspection_data = NULL;
-  DBusPeerInfo *peer;
-  guint registration_id;
-  GError *error = NULL;
-
-  if (!introspection_data)
-    introspection_data = g_dbus_node_info_new_for_xml (ephy_uri_tester_introspection_xml, NULL);
-
-  registration_id =
-    g_dbus_connection_register_object (connection,
-                                       EPHY_URI_TESTER_OBJECT_PATH,
-                                       introspection_data->interfaces[0],
-                                       &interface_vtable,
-                                       g_object_ref (tester),
-                                       g_object_unref,
-                                       &error);
-  if (!registration_id) {
-    g_warning ("Failed to register URI tester object: %s\n", error->message);
-    g_error_free (error);
-    return;
+    return NULL;
   }
 
-  peer = dbus_peer_info_new (tester, connection, registration_id);
-  tester->dbus_peers = g_list_append (tester->dbus_peers, peer);
-
-  g_signal_connect (connection, "closed",
-                    G_CALLBACK (dbus_connection_closed_cb), peer);
-}
+  if ((flags & EPHY_URI_TEST_HTTPS_EVERYWHERE) && https_everywhere_context_get_initialized 
(tester->https_everywhere_context))
+    return https_everywhere_context_rewrite (tester->https_everywhere_context, request_uri);
 
-static void
-handle_deferred_request (DeferredRequest *request,
-                         EphyUriTester   *tester)
-{
-  ephy_uri_tester_return_response (tester,
-                                   request->request_uri,
-                                   request->page_uri,
-                                   request->flags,
-                                   request->invocation);
+  return g_strdup (request_uri);
 }
 
 static void
-https_everywhere_update_cb (HTTPSEverywhereUpdater *updater,
-                            GAsyncResult *result)
+https_everywhere_context_init_cb (HTTPSEverywhereContext *context,
+                                  GAsyncResult           *res,
+                                  EphyUriTester          *tester)
 {
   GError *error = NULL;
 
-  https_everywhere_updater_update_finish (updater, result, &error);
+  https_everywhere_context_init_finish (context, res, &error);
 
   if (error) {
-    if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
-        !g_error_matches (error, HTTPS_EVERYWHERE_UPDATE_ERROR, HTTPS_EVERYWHERE_UPDATE_ERROR_IN_PROGRESS) &&
-        !g_error_matches (error, HTTPS_EVERYWHERE_UPDATE_ERROR, 
HTTPS_EVERYWHERE_UPDATE_ERROR_NO_UPDATE_AVAILABLE))
-      g_warning ("Failed to update HTTPS Everywhere rulesets: %s", error->message);
+    g_warning ("Failed to initialize HTTPS Everywhere context: %s", error->message);
     g_error_free (error);
   }
 
-  g_object_unref (updater);
+  ephy_uri_tester_https_everywhere_loaded (tester);
 }
 
 static void
-ephy_uri_tester_update_https_everywhere_rulesets (EphyUriTester *tester)
+adblock_file_monitor_changed (GFileMonitor     *monitor,
+                              GFile            *file,
+                              GFile            *other_file,
+                              GFileMonitorEvent event_type,
+                              EphyUriTester    *tester)
 {
-  HTTPSEverywhereUpdater *updater;
-  EphyEmbedShell *shell;
-  EphyEmbedShellMode mode;
-
-  shell = ephy_embed_shell_get_default ();
-  mode = ephy_embed_shell_get_mode (shell);
-
-  if (mode == EPHY_EMBED_SHELL_MODE_TEST || mode == EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER)
+  if (event_type != G_FILE_MONITOR_EVENT_RENAMED)
     return;
 
-  /* We might want to be smarter about this in the future. For now,
-   * trigger an update of the rulesets once each time an EphyUriTester
-   * is created. The new rulesets will get used the next time a new
-   * EphyUriTester is created. Since EphyUriTester is only intended to
-   * be created once, that means the new rulesets will be used the next
-   * time Epiphany is restarted. */
-  updater = https_everywhere_updater_new (tester->https_everywhere_context);
-  https_everywhere_updater_update (updater,
-                                   tester->cancellable,
-                                   (GAsyncReadyCallback)https_everywhere_update_cb,
-                                   NULL);
+  g_signal_handlers_disconnect_by_func (monitor, adblock_file_monitor_changed, tester);
+  g_file_read_async (other_file, G_PRIORITY_DEFAULT_IDLE, NULL,
+                     (GAsyncReadyCallback)file_read_cb,
+                     tester);
 }
 
 static void
-https_everywhere_context_init_cb (HTTPSEverywhereContext *context,
-                                  GAsyncResult           *res,
-                                  EphyUriTester          *tester)
+ephy_uri_tester_load_sync (GTask         *task,
+                           EphyUriTester *tester)
 {
-  GError *error = NULL;
+  GMainContext *context;
+  GFile *filter_file;
+  GFileMonitor *monitor = NULL;
 
-  https_everywhere_context_init_finish (context, res, &error);
+  context = g_main_context_new ();
+  tester->load_loop = g_main_loop_new (context, FALSE);
+  g_main_context_push_thread_default (context);
 
-  /* Note that if this were not fatal, we would need some way to ensure
-   * that future pending requests would not get stuck forever. */
-  if (error) {
-    if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-      g_error ("Failed to initialize HTTPS Everywhere context: %s", error->message);
+  tester->https_everywhere_context = https_everywhere_context_new ();
+  https_everywhere_context_init (tester->https_everywhere_context, NULL,
+                                 (GAsyncReadyCallback)https_everywhere_context_init_cb,
+                                 tester);
+
+  filter_file = ephy_uri_tester_get_adblock_filer_file (tester->adblock_data_dir);
+  if (!g_file_query_exists (filter_file, NULL)) {
+    GError *error = NULL;
+
+    monitor = g_file_monitor_file (filter_file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
+    if (monitor) {
+       g_signal_connect (monitor, "changed", G_CALLBACK (adblock_file_monitor_changed), tester);
+    } else {
+      g_warning ("Failed to monitor adblock file: %s\n", error->message);
+      g_error_free (error);
+      ephy_uri_tester_adblock_loaded (tester);
+    }
   } else {
-    g_list_foreach (tester->deferred_requests, (GFunc)handle_deferred_request, tester);
-    ephy_uri_tester_update_https_everywhere_rulesets (tester);
+    g_file_read_async (filter_file, G_PRIORITY_DEFAULT_IDLE, NULL,
+                       (GAsyncReadyCallback)file_read_cb,
+                       tester);
   }
+  g_object_unref (filter_file);
+
+  g_main_loop_run (tester->load_loop);
 
-  g_list_free_full (tester->deferred_requests, (GDestroyNotify)deferred_request_free);
-  g_object_unref (tester);
+  if (monitor)
+    g_object_unref (monitor);
+  g_main_context_pop_thread_default (context);
+  g_main_context_unref (context);
+
+  g_task_return_boolean (task, TRUE);
 }
 
 static void
@@ -1050,24 +732,6 @@ ephy_uri_tester_init (EphyUriTester *tester)
 }
 
 static void
-ephy_uri_tester_constructed (GObject *object)
-{
-  EphyUriTester *tester = EPHY_URI_TESTER (object);
-
-  G_OBJECT_CLASS (ephy_uri_tester_parent_class)->constructed (object);
-
-  tester->cancellable = g_cancellable_new ();
-
-  tester->https_everywhere_context = https_everywhere_context_new ();
-  https_everywhere_context_init (tester->https_everywhere_context,
-                                 tester->cancellable,
-                                 (GAsyncReadyCallback)https_everywhere_context_init_cb,
-                                 g_object_ref (tester));
-
-  ephy_uri_tester_load_patterns (tester);
-}
-
-static void
 ephy_uri_tester_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
@@ -1076,8 +740,8 @@ ephy_uri_tester_set_property (GObject      *object,
   EphyUriTester *tester = EPHY_URI_TESTER (object);
 
   switch (prop_id) {
-    case PROP_BASE_DATA_DIR:
-      tester->data_dir = ephy_uri_tester_ensure_data_dir (g_value_get_string (value));
+    case PROP_ADBLOCK_DATA_DIR:
+      tester->adblock_data_dir = g_value_dup_string (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1086,41 +750,13 @@ ephy_uri_tester_set_property (GObject      *object,
 }
 
 static void
-unregister_dbus_object (DBusPeerInfo  *peer,
-                        EphyUriTester *tester)
-{
-  g_dbus_connection_unregister_object (peer->connection, peer->registration_id);
-}
-
-static void
-ephy_uri_tester_dispose (GObject *object)
-{
-  EphyUriTester *tester = EPHY_URI_TESTER (object);
-
-  LOG ("EphyUriTester disposing %p", object);
-
-  if (tester->cancellable) {
-    g_cancellable_cancel (tester->cancellable);
-    g_clear_object (&tester->cancellable);
-  }
-
-  if (tester->dbus_peers) {
-    g_list_foreach (tester->dbus_peers, (GFunc)unregister_dbus_object, tester);
-    g_list_free_full (tester->dbus_peers, (GDestroyNotify)dbus_peer_info_free);
-    tester->dbus_peers = NULL;
-  }
-
-  G_OBJECT_CLASS (ephy_uri_tester_parent_class)->dispose (object);
-}
-
-static void
 ephy_uri_tester_finalize (GObject *object)
 {
   EphyUriTester *tester = EPHY_URI_TESTER (object);
 
   LOG ("EphyUriTester finalizing %p", object);
 
-  g_free (tester->data_dir);
+  g_free (tester->adblock_data_dir);
 
   g_hash_table_destroy (tester->pattern);
   g_hash_table_destroy (tester->keys);
@@ -1140,6 +776,8 @@ ephy_uri_tester_finalize (GObject *object)
   g_regex_unref (tester->regex_subdocument);
   g_regex_unref (tester->regex_frame_add);
 
+  g_clear_object (&tester->https_everywhere_context);
+
   G_OBJECT_CLASS (ephy_uri_tester_parent_class)->finalize (object);
 }
 
@@ -1149,14 +787,12 @@ ephy_uri_tester_class_init (EphyUriTesterClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->set_property = ephy_uri_tester_set_property;
-  object_class->constructed = ephy_uri_tester_constructed;
-  object_class->dispose = ephy_uri_tester_dispose;
   object_class->finalize = ephy_uri_tester_finalize;
 
-  obj_properties[PROP_BASE_DATA_DIR] =
-    g_param_spec_string ("base-data-dir",
-                         "Base data dir",
-                         "The base dir where to create the adblock data dir",
+  obj_properties[PROP_ADBLOCK_DATA_DIR] =
+    g_param_spec_string ("adblock-data-dir",
+                         "Adblock data dir",
+                         "The adblock data dir",
                          NULL,
                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
 
@@ -1164,23 +800,22 @@ ephy_uri_tester_class_init (EphyUriTesterClass *klass)
 }
 
 EphyUriTester *
-ephy_uri_tester_new (void)
+ephy_uri_tester_new (const char *adblock_data_dir)
 {
-  EphyEmbedShell *shell;
-  EphyEmbedShellMode mode;
-  EphyUriTester *tester;
-  char *data_dir;
-
-  shell = ephy_embed_shell_get_default ();
-  mode = ephy_embed_shell_get_mode (shell);
-
-  /* The filters list is large, so we don't want to store a separate copy per
-   * web app, but users should otherwise be able to configure different filters
-   * per profile directory. */
-  data_dir = mode == EPHY_EMBED_SHELL_MODE_APPLICATION ? ephy_default_dot_dir ()
-                                                       : g_strdup (ephy_dot_dir ());
-
-  tester = g_object_new (EPHY_TYPE_URI_TESTER, "base-data-dir", data_dir, NULL);
-  g_free (data_dir);
-  return tester;
+  return EPHY_URI_TESTER (g_object_new (EPHY_TYPE_URI_TESTER, "adblock-data-dir", adblock_data_dir, NULL));
+}
+
+void
+ephy_uri_tester_load (EphyUriTester *tester)
+{
+  GTask *task;
+
+  g_return_if_fail (EPHY_IS_URI_TESTER (tester));
+
+  if (tester->adblock_loaded && tester->https_everywhere_loaded)
+    return;
+
+  task = g_task_new (tester, NULL, NULL, NULL);
+  g_task_run_in_thread_sync (task, (GTaskThreadFunc)ephy_uri_tester_load_sync);
+  g_object_unref (task);
 }
diff --git a/lib/ephy-uri-tester-interface.h b/embed/web-extension/ephy-uri-tester.h
similarity index 57%
rename from lib/ephy-uri-tester-interface.h
rename to embed/web-extension/ephy-uri-tester.h
index a90d2e9..cd6cc6b 100644
--- a/lib/ephy-uri-tester-interface.h
+++ b/embed/web-extension/ephy-uri-tester.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
- *  Copyright © 2016 Igalia S.L.
+ *  Copyright © 2011 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -20,26 +20,28 @@
 
 #pragma once
 
+#include <gio/gio.h>
+
 G_BEGIN_DECLS
 
-static const char ephy_uri_tester_introspection_xml[] =
-  "<node>"
-  " <interface name='org.gnome.Epiphany.UriTester'>"
-  "  <method name='MaybeRewriteUri'>"
-  "   <arg name='request_uri' type='s' direction='in'/>"
-  "   <arg name='page_uri' type='s' direction='in'/>"
-  "   <arg name='flags' type='i' direction='in'/>"
-  "   <arg name='modified_request_uri' type='s' direction='out'/>"
-  "  </method>"
-  " </interface>"
-  "</node>";
+#define EPHY_TYPE_URI_TESTER (ephy_uri_tester_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyUriTester, ephy_uri_tester, EPHY, URI_TESTER, GObject)
 
 typedef enum
 {
   EPHY_URI_TEST_ADBLOCK          = 1 << 1,
-  EPHY_URI_TEST_TRACKING_QUERIES = 1 << 2,
-  EPHY_URI_TEST_HTTPS_EVERYWHERE = 1 << 3,
-  EPHY_URI_TEST_ALL              = EPHY_URI_TEST_ADBLOCK | EPHY_URI_TEST_TRACKING_QUERIES | 
EPHY_URI_TEST_HTTPS_EVERYWHERE
+  EPHY_URI_TEST_HTTPS_EVERYWHERE = 1 << 2,
+  EPHY_URI_TEST_ALL              = EPHY_URI_TEST_ADBLOCK | EPHY_URI_TEST_HTTPS_EVERYWHERE
 } EphyUriTestFlags;
 
+
+EphyUriTester *ephy_uri_tester_new         (const char       *adblock_data_dir);
+void           ephy_uri_tester_load        (EphyUriTester    *tester);
+char          *ephy_uri_tester_rewrite_uri (EphyUriTester    *tester,
+                                            const char       *request_uri,
+                                            const char       *page_uri,
+                                            EphyUriTestFlags  flags);
+
+
 G_END_DECLS
diff --git a/embed/web-extension/ephy-web-extension-main.c b/embed/web-extension/ephy-web-extension-main.c
index 13f029a..c76f0bf 100644
--- a/embed/web-extension/ephy-web-extension-main.c
+++ b/embed/web-extension/ephy-web-extension-main.c
@@ -35,10 +35,11 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
 {
   const char *server_address;
   const char *dot_dir;
+  const char *adblock_data_dir;
   gboolean private_profile;
   GError *error = NULL;
 
-  g_variant_get (user_data, "(m&s&sb)", &server_address, &dot_dir, &private_profile);
+  g_variant_get (user_data, "(m&s&s&sb)", &server_address, &dot_dir, &adblock_data_dir, &private_profile);
 
   if (!server_address) {
     g_warning ("UI process did not start D-Bus server, giving up.");
@@ -57,6 +58,7 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
   ephy_web_extension_initialize (extension,
                                  webkit_extension,
                                  server_address,
+                                 adblock_data_dir,
                                  private_profile);
 }
 
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index c176b90..d95f4fa 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -30,7 +30,8 @@
 #include "ephy-hosts-manager.h"
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
-#include "ephy-uri-tester-proxy.h"
+#include "ephy-uri-helpers.h"
+#include "ephy-uri-tester.h"
 #include "ephy-web-dom-utils.h"
 #include "ephy-web-overview.h"
 
@@ -50,12 +51,13 @@ struct _EphyWebExtension {
   gboolean initialized;
 
   GDBusConnection *dbus_connection;
+  GArray *page_created_signals_pending;
 
   EphyFormAuthDataCache *form_auth_data_cache;
   GHashTable *form_auth_data_save_requests;
   EphyWebOverviewModel *overview_model;
   EphyHostsManager *hosts_manager;
-  EphyUriTesterProxy *uri_tester;
+  EphyUriTester *uri_tester;
 };
 
 static const char introspection_xml[] =
@@ -114,6 +116,16 @@ should_use_https_everywhere (const char *request_uri,
   gboolean result = TRUE;
 
   request_soup_uri = soup_uri_new (request_uri);
+  if (request_soup_uri->scheme != SOUP_URI_SCHEME_HTTP) {
+    soup_uri_free (request_soup_uri);
+    return FALSE;
+  }
+
+  if (!redirected_uri) {
+    soup_uri_free (request_soup_uri);
+    return TRUE;
+  }
+
   redirected_soup_uri = soup_uri_new (redirected_uri);
 
   if (request_soup_uri->scheme == SOUP_URI_SCHEME_HTTP &&
@@ -133,17 +145,51 @@ should_use_https_everywhere (const char *request_uri,
 }
 
 static gboolean
+should_use_adblocker (const char *request_uri,
+                      const char *page_uri)
+{
+  /* Always load the main resource. */
+  if (g_strcmp0 (request_uri, page_uri) == 0)
+    return FALSE;
+
+  /* Always load data requests, as uri_tester won't do any good here. */
+  if (g_str_has_prefix (request_uri, SOUP_URI_SCHEME_DATA))
+    return FALSE;
+
+  /* Always load about pages */
+  if (g_str_has_prefix (request_uri, "about") ||
+      g_str_has_prefix (request_uri, "ephy-about"))
+    return FALSE;
+
+  /* Always load resources */
+  if (g_str_has_prefix (request_uri, "resource://") ||
+      g_str_has_prefix (request_uri, "ephy-resource://"))
+    return FALSE;
+
+  /* Always load local files */
+  if (g_str_has_prefix (request_uri, "file://"))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
 web_page_send_request (WebKitWebPage     *web_page,
                        WebKitURIRequest  *request,
                        WebKitURIResponse *redirected_response,
                        EphyWebExtension  *extension)
 {
   const char *request_uri;
+  const char *redirected_response_uri;
   const char *page_uri;
-  char *modified_uri;
+  char *modified_uri = NULL;
   EphyUriTestFlags flags = EPHY_URI_TEST_ALL;
 
-  if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
+  request_uri = webkit_uri_request_get_uri (request);
+  page_uri = webkit_web_page_get_uri (web_page);
+
+  if (!should_use_adblocker (request_uri, page_uri) ||
+      !g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
     flags &= ~EPHY_URI_TEST_ADBLOCK;
 
   if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
@@ -153,28 +199,30 @@ web_page_send_request (WebKitWebPage     *web_page,
        * http://tools.ietf.org/id/draft-mayer-do-not-track-00.txt */
       soup_message_headers_append (headers, "DNT", "1");
     }
-  } else {
-    flags &= ~EPHY_URI_TEST_TRACKING_QUERIES;
+    modified_uri = ephy_remove_tracking_from_uri (request_uri);
   }
 
-  request_uri = webkit_uri_request_get_uri (request);
-  page_uri = webkit_web_page_get_uri (web_page);
-
-  if (redirected_response != NULL &&
-      !should_use_https_everywhere (request_uri,
-                                    webkit_uri_response_get_uri (redirected_response))) {
+  redirected_response_uri = redirected_response ? webkit_uri_response_get_uri (redirected_response) : NULL;
+  if (!should_use_https_everywhere (request_uri, redirected_response_uri))
     flags &= ~EPHY_URI_TEST_HTTPS_EVERYWHERE;
-  }
 
-  modified_uri = ephy_uri_tester_proxy_maybe_rewrite_uri (extension->uri_tester,
-                                                          request_uri,
-                                                          page_uri,
-                                                          flags);
+  if ((flags & EPHY_URI_TEST_ADBLOCK) || (flags & EPHY_URI_TEST_HTTPS_EVERYWHERE)) {
+    char *result;
 
-  if (strlen (modified_uri) == 0) {
-    LOG ("Refused to load %s", request_uri);
+    ephy_uri_tester_load (extension->uri_tester);
+    result = ephy_uri_tester_rewrite_uri (extension->uri_tester,
+                                          modified_uri ? modified_uri : request_uri,
+                                          page_uri, flags);
     g_free (modified_uri);
-    return TRUE;
+
+    if (!result) {
+      LOG ("Refused to load %s", request_uri);
+      return TRUE;
+    }
+
+    modified_uri = result;
+  } else if (!modified_uri) {
+    return FALSE;
   }
 
   if (g_strcmp0 (request_uri, modified_uri) != 0) {
@@ -1176,13 +1224,44 @@ ephy_web_extension_emit_page_created (EphyWebExtension *extension,
 }
 
 static void
+ephy_web_extension_emit_page_created_signals_pending (EphyWebExtension *extension)
+{
+  guint i;
+
+  if (!extension->page_created_signals_pending)
+    return;
+
+  for (i = 0; i < extension->page_created_signals_pending->len; i++) {
+    guint64 page_id;
+
+    page_id = g_array_index (extension->page_created_signals_pending, guint64, i);
+    ephy_web_extension_emit_page_created (extension, page_id);
+  }
+
+  g_array_free (extension->page_created_signals_pending, TRUE);
+  extension->page_created_signals_pending = NULL;
+}
+
+static void
+ephy_web_extension_queue_page_created_signal_emission (EphyWebExtension *extension,
+                                                       guint64           page_id)
+{
+  if (!extension->page_created_signals_pending)
+    extension->page_created_signals_pending = g_array_new (FALSE, FALSE, sizeof (guint64));
+  extension->page_created_signals_pending = g_array_append_val (extension->page_created_signals_pending, 
page_id);
+}
+
+static void
 ephy_web_extension_page_created_cb (EphyWebExtension *extension,
                                     WebKitWebPage    *web_page)
 {
   guint64 page_id;
 
   page_id = webkit_web_page_get_id (web_page);
-  ephy_web_extension_emit_page_created (extension, page_id);
+  if (extension->dbus_connection)
+    ephy_web_extension_emit_page_created (extension, page_id);
+  else
+    ephy_web_extension_queue_page_created_signal_emission (extension, page_id);
 
   g_signal_connect (web_page, "send-request",
                     G_CALLBACK (web_page_send_request),
@@ -1367,6 +1446,7 @@ ephy_web_extension_dispose (GObject *object)
 {
   EphyWebExtension *extension = EPHY_WEB_EXTENSION (object);
 
+  g_clear_object (&extension->uri_tester);
   g_clear_object (&extension->overview_model);
   g_clear_object (&extension->hosts_manager);
 
@@ -1378,6 +1458,11 @@ ephy_web_extension_dispose (GObject *object)
     extension->form_auth_data_save_requests = NULL;
   }
 
+  if (extension->page_created_signals_pending) {
+    g_array_free (extension->page_created_signals_pending, TRUE);
+    extension->page_created_signals_pending = NULL;
+  }
+
   g_clear_object (&extension->dbus_connection);
   g_clear_object (&extension->extension);
 
@@ -1411,6 +1496,45 @@ ephy_web_extension_get (void)
   return EPHY_WEB_EXTENSION (g_once (&once_init, ephy_web_extension_create_instance, NULL));
 }
 
+static void
+dbus_connection_created_cb (GObject          *source_object,
+                            GAsyncResult     *result,
+                            EphyWebExtension *extension)
+{
+  static GDBusNodeInfo *introspection_data = NULL;
+  GDBusConnection *connection;
+  guint registration_id;
+  GError *error = NULL;
+
+  if (!introspection_data)
+    introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+  connection = g_dbus_connection_new_for_address_finish (result, &error);
+  if (error) {
+    g_warning ("Failed to connect to UI process: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+  registration_id =
+    g_dbus_connection_register_object (connection,
+                                       EPHY_WEB_EXTENSION_OBJECT_PATH,
+                                       introspection_data->interfaces[0],
+                                       &interface_vtable,
+                                       extension,
+                                       NULL,
+                                       &error);
+  if (!registration_id) {
+    g_warning ("Failed to register web extension object: %s\n", error->message);
+    g_error_free (error);
+    g_object_unref (connection);
+    return;
+  }
+
+  extension->dbus_connection = connection;
+  ephy_web_extension_emit_page_created_signals_pending (extension);
+}
+
 static gboolean
 authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
                                  GIOStream         *stream,
@@ -1424,12 +1548,10 @@ void
 ephy_web_extension_initialize (EphyWebExtension   *extension,
                                WebKitWebExtension *wk_extension,
                                const char         *server_address,
+                               const char         *adblock_data_dir,
                                gboolean            is_private_profile)
 {
-  static GDBusNodeInfo *introspection_data = NULL;
   GDBusAuthObserver *observer;
-  guint registration_id;
-  GError *error = NULL;
 
   g_return_if_fail (EPHY_IS_WEB_EXTENSION (extension));
 
@@ -1452,35 +1574,13 @@ ephy_web_extension_initialize (EphyWebExtension   *extension,
   g_signal_connect (observer, "authorize-authenticated-peer",
                     G_CALLBACK (authorize_authenticated_peer_cb), extension);
 
-  /* Sync because this has to be ready before the first URI request, since
-   * WebKit does not provide any async way to rewrite URI requests. */
-  extension->dbus_connection =
-      g_dbus_connection_new_for_address_sync (server_address,
-                                              G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
-                                              observer,
-                                              NULL,
-                                              &error);
+  g_dbus_connection_new_for_address (server_address,
+                                     G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+                                     observer,
+                                     NULL,
+                                     (GAsyncReadyCallback)dbus_connection_created_cb,
+                                     extension);
   g_object_unref (observer);
 
-  /* Fatal. */
-  if (error)
-    g_error ("Failed to connect to UI process: %s", error->message);
-
-  if (!introspection_data)
-    introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
-  registration_id =
-    g_dbus_connection_register_object (extension->dbus_connection,
-                                       EPHY_WEB_EXTENSION_OBJECT_PATH,
-                                       introspection_data->interfaces[0],
-                                       &interface_vtable,
-                                       extension,
-                                       NULL,
-                                       &error);
-
-  /* Fatal. */
-  if (!registration_id)
-    g_error ("Failed to register web extension object: %s\n", error->message);
-
-  extension->uri_tester = ephy_uri_tester_proxy_new (extension->dbus_connection);
+  extension->uri_tester = ephy_uri_tester_new (adblock_data_dir);
 }
diff --git a/embed/web-extension/ephy-web-extension.h b/embed/web-extension/ephy-web-extension.h
index 3901967..bf0f482 100644
--- a/embed/web-extension/ephy-web-extension.h
+++ b/embed/web-extension/ephy-web-extension.h
@@ -33,7 +33,7 @@ EphyWebExtension *ephy_web_extension_get            (void);
 void              ephy_web_extension_initialize     (EphyWebExtension   *extension,
                                                      WebKitWebExtension *wk_extension,
                                                      const char         *server_address,
+                                                     const char         *adblock_data_dir,
                                                      gboolean            is_private_profile);
 
-
 G_END_DECLS
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1acd150..f8f21d0 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -49,7 +49,8 @@ libephymisc_la_SOURCES = \
        ephy-time-helpers.h                     \
        ephy-uri-helpers.c                      \
        ephy-uri-helpers.h                      \
-       ephy-uri-tester-interface.h             \
+       ephy-uri-tester-shared.c                \
+       ephy-uri-tester-shared.h                \
        ephy-web-app-utils.c                    \
        ephy-web-app-utils.h                    \
        ephy-zoom.c                             \
diff --git a/lib/ephy-dbus-names.h b/lib/ephy-dbus-names.h
index 0202777..b051f44 100644
--- a/lib/ephy-dbus-names.h
+++ b/lib/ephy-dbus-names.h
@@ -26,8 +26,4 @@ G_BEGIN_DECLS
 #define EPHY_WEB_EXTENSION_OBJECT_PATH  "/org/gnome/Epiphany/WebExtension"
 #define EPHY_WEB_EXTENSION_INTERFACE    "org.gnome.Epiphany.WebExtension"
 
-#define EPHY_URI_TESTER_SERVICE_NAME    "org.gnome.Epiphany.UriTester"
-#define EPHY_URI_TESTER_OBJECT_PATH     "/org/gnome/Epiphany/UriTester"
-#define EPHY_URI_TESTER_INTERFACE       "org.gnome.Epiphany.UriTester"
-
 G_END_DECLS
diff --git a/embed/web-extension/ephy-uri-tester-proxy.h b/lib/ephy-uri-tester-shared.c
similarity index 52%
rename from embed/web-extension/ephy-uri-tester-proxy.h
rename to lib/ephy-uri-tester-shared.c
index 2050203..40bba1c 100644
--- a/embed/web-extension/ephy-uri-tester-proxy.h
+++ b/lib/ephy-uri-tester-shared.c
@@ -18,23 +18,20 @@
  *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#pragma once
-
-#include <gio/gio.h>
-
-#include "ephy-uri-tester-interface.h"
-
-G_BEGIN_DECLS
-
-#define EPHY_TYPE_URI_TESTER_PROXY (ephy_uri_tester_proxy_get_type ())
-
-G_DECLARE_FINAL_TYPE (EphyUriTesterProxy, ephy_uri_tester_proxy, EPHY, URI_TESTER_PROXY, GObject)
-
-EphyUriTesterProxy *ephy_uri_tester_proxy_new (GDBusConnection *connection);
-
-char               *ephy_uri_tester_proxy_maybe_rewrite_uri (EphyUriTesterProxy *uri_tester,
-                                                             const char         *request_uri,
-                                                             const char         *page_uri,
-                                                             EphyUriTestFlags    flags);
-
-G_END_DECLS
+#include "config.h"
+#include "ephy-uri-tester-shared.h"
+
+GFile *
+ephy_uri_tester_get_adblock_filer_file (const char *adblock_data_dir)
+{
+  char *filter_filename, *filter_path;
+  GFile *filter_file;
+
+  filter_filename = g_compute_checksum_for_string (G_CHECKSUM_MD5, ADBLOCK_FILTER_URL, -1);
+  filter_path = g_build_filename (adblock_data_dir, filter_filename, NULL);
+  g_free (filter_filename);
+  filter_file = g_file_new_for_path (filter_path);
+  g_free (filter_path);
+
+  return filter_file;
+}
diff --git a/embed/ephy-uri-tester.h b/lib/ephy-uri-tester-shared.h
similarity index 67%
rename from embed/ephy-uri-tester.h
rename to lib/ephy-uri-tester-shared.h
index 8b3e19d..2c57856 100644
--- a/embed/ephy-uri-tester.h
+++ b/lib/ephy-uri-tester-shared.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
- *  Copyright © 2011 Igalia S.L.
+ *  Copyright © 2016 Igalia S.L.
  *
  *  This file is part of Epiphany.
  *
@@ -24,13 +24,8 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_TYPE_URI_TESTER (ephy_uri_tester_get_type ())
+#define ADBLOCK_FILTER_URL "https://easylist-downloads.adblockplus.org/easylist.txt";
 
-G_DECLARE_FINAL_TYPE (EphyUriTester, ephy_uri_tester, EPHY, URI_TESTER, GObject)
-
-EphyUriTester *ephy_uri_tester_new                  (void);
-
-void           ephy_uri_tester_handle_new_dbus_connection (EphyUriTester   *tester,
-                                                           GDBusConnection *connection);
+GFile *ephy_uri_tester_get_adblock_filer_file (const char *adblock_data_dir);
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]