[epiphany/mcatanzaro/2.33.1] Add unresponsive web process error page




commit de8e08cc847f1809a6e207e53934acf72a24e7ef
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Fri May 14 17:11:14 2021 -0500

    Add unresponsive web process error page
    
    WebKitGTK 2.33.1 allows us to detect and kill runaway web processes.
    Let's take advantage of that.
    
    The process is not detected as unresponsive for quite a while -- 10
    seconds -- so there's no need for any secondary timeout at the Epiphany
    level. Let's kill it immediately when WebKit says the web process has
    been lost. If the WebKit timeout were shorter, then prompting the user
    to decide whether to kill the page would make more sense, but 10 seconds
    is long enough that any web content that hasn't returned to the main
    loop deserves to be immediately killed. There's no excuse for that.
    
    Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/965>

 embed/ephy-web-view.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 embed/ephy-web-view.h |  1 +
 meson.build           |  3 +--
 3 files changed, 69 insertions(+), 3 deletions(-)
---
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 2bcb619c4..acafd5977 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -821,6 +821,8 @@ process_terminated_cb (EphyWebView                       *web_view,
                        WebKitWebProcessTerminationReason  reason,
                        gpointer                           user_data)
 {
+  EphyWebViewErrorPage error_page = EPHY_WEB_VIEW_ERROR_PROCESS_CRASH;
+
   switch (reason) {
     case WEBKIT_WEB_PROCESS_CRASHED:
       g_warning (_("Web process crashed"));
@@ -828,14 +830,29 @@ process_terminated_cb (EphyWebView                       *web_view,
     case WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT:
       g_warning (_("Web process terminated due to exceeding memory limit"));
       break;
+    case WEBKIT_WEB_PROCESS_TERMINATED_BY_API:
+      g_warning (_("Web process terminated by API request"));
+      error_page = EPHY_WEB_VIEW_ERROR_UNRESPONSIVE_PROCESS;
+      break;
   }
 
   if (!ephy_embed_has_load_pending (EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view))) {
     ephy_web_view_load_error_page (web_view, ephy_web_view_get_address (web_view),
-                                   EPHY_WEB_VIEW_ERROR_PROCESS_CRASH, NULL, NULL);
+                                   error_page, NULL, NULL);
   }
 }
 
+static void
+is_web_process_responsive_changed_cb (EphyWebView *web_view,
+                                      GParamSpec  *pspec,
+                                      gpointer     user_data)
+{
+  WebKitWebView *view = WEBKIT_WEB_VIEW (web_view);
+
+  if (!webkit_web_view_get_is_web_process_responsive (view))
+    webkit_web_view_terminate_web_process (view);
+}
+
 static gboolean
 decide_policy_cb (WebKitWebView            *web_view,
                   WebKitPolicyDecision     *decision,
@@ -1909,6 +1926,40 @@ format_process_crash_error_page (const char  *uri,
   *style = "default";
 }
 
+static void
+format_unresponsive_process_error_page (const char  *uri,
+                                        char       **page_title,
+                                        char       **message_title,
+                                        char       **message_body,
+                                        char       **button_label,
+                                        char       **button_action,
+                                        const char **button_accesskey,
+                                        const char **icon_name,
+                                        const char **style)
+{
+  const char *first_paragraph;
+
+  /* Page title when web content has become unresponsive. */
+  *page_title = g_strdup_printf (_("Unresponsive Page"));
+
+  /* Message title when web content has become unresponsive. */
+  *message_title = g_strdup (_("Uh-oh!"));
+
+  /* Error details when web content has become unresponsive. */
+  first_paragraph = _("This page has been unresponsive for too long. Please reload or visit a different page 
to continue.");
+  *message_body = g_strdup_printf ("<p>%s</p>",
+                                   first_paragraph);
+
+  /* The button on the unresponsive process error page. DO NOT ADD MNEMONICS HERE. */
+  *button_label = g_strdup (_("Reload"));
+  *button_action = g_strdup_printf ("window.location = '%s';", uri);
+  /* Mnemonic for the Reload button on browser error pages. */
+  *button_accesskey = C_("reload-access-key", "R");
+
+  *icon_name = "computer-fail-symbolic.svg";
+  *style = "default";
+}
+
 static void
 format_tls_error_page (EphyWebView  *view,
                        const char   *origin,
@@ -2190,6 +2241,17 @@ ephy_web_view_load_error_page (EphyWebView          *view,
                                        &icon_name,
                                        &style);
       break;
+    case EPHY_WEB_VIEW_ERROR_UNRESPONSIVE_PROCESS:
+      format_unresponsive_process_error_page (uri,
+                                              &page_title,
+                                              &msg_title,
+                                              &msg_body,
+                                              &button_label,
+                                              &button_action,
+                                              &button_accesskey,
+                                              &icon_name,
+                                              &style);
+      break;
     case EPHY_WEB_VIEW_ERROR_INVALID_TLS_CERTIFICATE:
       format_tls_error_page (view,
                              origin,
@@ -3888,6 +3950,10 @@ ephy_web_view_init (EphyWebView *web_view)
                     G_CALLBACK (uri_changed_cb),
                     NULL);
 
+  g_signal_connect (web_view, "notify::is-web-process-responsive",
+                    G_CALLBACK (is_web_process_responsive_changed_cb),
+                    NULL);
+
   g_signal_connect (web_view, "mouse-target-changed",
                     G_CALLBACK (mouse_target_changed_cb),
                     NULL);
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index 0153b4b2f..8cf7019db 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -70,6 +70,7 @@ typedef enum {
   EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR,
   EPHY_WEB_VIEW_ERROR_PAGE_CRASH,
   EPHY_WEB_VIEW_ERROR_PROCESS_CRASH,
+  EPHY_WEB_VIEW_ERROR_UNRESPONSIVE_PROCESS,
   EPHY_WEB_VIEW_ERROR_INVALID_TLS_CERTIFICATE,
   EPHY_WEB_VIEW_ERROR_UNSAFE_BROWSING,
   EPHY_WEB_VIEW_ERROR_NO_SUCH_FILE,
diff --git a/meson.build b/meson.build
index b8c1a3741..6829efaa7 100644
--- a/meson.build
+++ b/meson.build
@@ -75,6 +75,7 @@ conf.set10('ENABLE_GSB', gsb_api_key != '')
 glib_requirement = '>= 2.67.1'
 gtk_requirement = '>= 3.24.0'
 nettle_requirement = '>= 3.4'
+webkitgtk_requirement = '>= 2.33.1'
 
 cairo_dep = dependency('cairo', version: '>= 1.2')
 gcr_dep = dependency('gcr-3', version: '>= 3.5.5')
@@ -99,12 +100,10 @@ portal_dep = dependency('libportal', version: '>= 0.0.2', required: get_option('
 sqlite3_dep = dependency('sqlite3', version: '>= 3.22')
 
 if get_option('soup2').enabled()
-  webkitgtk_requirement = '>= 2.31.2'
   libsoup_dep = dependency('libsoup-2.4', version: '>= 2.48.0')
   webkit2gtk_dep = dependency('webkit2gtk-4.0', version: webkitgtk_requirement)
   webkit2gtk_web_extension_dep = dependency('webkit2gtk-web-extension-4.0', version: webkitgtk_requirement)
 else
-  webkitgtk_requirement = '>= 2.33.0'
   libsoup_dep = dependency('libsoup-3.0', version: '>= 2.99.4')
   webkit2gtk_dep = dependency('webkit2gtk-4.1', version: webkitgtk_requirement)
   webkit2gtk_web_extension_dep = dependency('webkit2gtk-web-extension-4.1', version: webkitgtk_requirement)


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