Commit cff4bf1a authored by Michael Catanzaro's avatar Michael Catanzaro Committed by Michael Catanzaro
Browse files

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.
parent fea0ffc5
Pipeline #287103 canceled with stages
in 21 minutes and 28 seconds
......@@ -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);
......
......@@ -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,
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment