summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2021-01-27 14:06:21 +0100
committerFlorian Bruhin <me@the-compiler.org>2021-01-27 14:06:21 +0100
commit7d8fd507924309227ebb6c11c3d32cb0b013d238 (patch)
treeefbc2f302b577b51ed59c8b8092908f843daba4d
parentb0c812b239e000da384c04f716e8ec9f38ad870a (diff)
downloadqutebrowser-7d8fd507924309227ebb6c11c3d32cb0b013d238.tar.gz
qutebrowser-7d8fd507924309227ebb6c11c3d32cb0b013d238.zip
Add qt.workarounds.remove_service_workers setting
See #5656, #5634
-rw-r--r--doc/changelog.asciidoc4
-rw-r--r--doc/help/settings.asciidoc11
-rw-r--r--qutebrowser/config/configdata.yml13
-rw-r--r--qutebrowser/misc/backendproblem.py17
-rw-r--r--tests/end2end/data/service-worker/data.json1
-rw-r--r--tests/end2end/data/service-worker/index.html11
-rw-r--r--tests/end2end/data/service-worker/worker.js8
-rw-r--r--tests/end2end/test_invocations.py55
8 files changed, 112 insertions, 8 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index 2b4011a20..21bd24412 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -94,6 +94,10 @@ Added
- New `:bookmark-list` command which lists all bookmarks/quickmarks. The
corresponding `qute://bookmarks` URL already existed since v0.8.0, but it was
never exposed as a command.
+- New `qt.workarounds.remove_service_workers` setting which can be used to
+ remove the "Service Workers" directory on every start. Usage of this option is
+ generally discouraged, except in situations where the underlying QtWebEngine bug
+ is a known cause for crashes.
- New userscripts:
* `kodi` to play videos in Kodi
* `qr` to generate a QR code of the current URL
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 03b48c182..742b1ab49 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -282,6 +282,7 @@
|<<qt.highdpi,qt.highdpi>>|Turn on Qt HighDPI scaling.
|<<qt.low_end_device_mode,qt.low_end_device_mode>>|When to use Chromium's low-end device mode.
|<<qt.process_model,qt.process_model>>|Which Chromium process model to use.
+|<<qt.workarounds.remove_service_workers,qt.workarounds.remove_service_workers>>|Delete the QtWebEngine Service Worker directory on every start.
|<<scrolling.bar,scrolling.bar>>|When/how to show the scrollbar.
|<<scrolling.smooth,scrolling.smooth>>|Enable smooth scrolling for web pages.
|<<search.ignore_case,search.ignore_case>>|When to find text on a page case-insensitively.
@@ -3638,6 +3639,16 @@ Default: +pass:[process-per-site-instance]+
This setting is only available with the QtWebEngine backend.
+[[qt.workarounds.remove_service_workers]]
+=== qt.workarounds.remove_service_workers
+Delete the QtWebEngine Service Worker directory on every start.
+This workaround can help with certain crashes caused by an unknown QtWebEngine bug related to Service Workers. Those crashes happen seemingly immediately on Windows; after one hour of operation on other systems.
+Note however that enabling this option *can lead to data loss* on some pages (as Service Worker data isn't persisted) and will negatively impact start-up time.
+
+Type: <<types,Bool>>
+
+Default: +pass:[false]+
+
[[scrolling.bar]]
=== scrolling.bar
When/how to show the scrollbar.
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 69786f2b3..cee077c14 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -286,6 +286,19 @@ qt.highdpi:
As an alternative to this, it's possible to set font sizes and the
`zoom.default` setting.
+qt.workarounds.remove_service_workers:
+ type: Bool
+ default: false
+ desc: >-
+ Delete the QtWebEngine Service Worker directory on every start.
+
+ This workaround can help with certain crashes caused by an unknown QtWebEngine bug
+ related to Service Workers. Those crashes happen seemingly immediately on Windows;
+ after one hour of operation on other systems.
+
+ Note however that enabling this option *can lead to data loss* on some pages (as
+ Service Worker data isn't persisted) and will negatively impact start-up time.
+
## auto_save
auto_save.interval:
diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py
index 1011e539d..b5f72b521 100644
--- a/qutebrowser/misc/backendproblem.py
+++ b/qutebrowser/misc/backendproblem.py
@@ -403,21 +403,22 @@ class _BackendProblemChecker:
# Nuke the service worker directory once for every install with Qt
# 5.14, given that it seems to cause a variety of segfaults.
configfiles.state['general']['serviceworker_workaround'] = '514'
- affected = True
+ reason = 'Qt 5.14'
+ elif configfiles.state.qt_version_changed:
+ reason = 'Qt version changed'
+ elif config.val.qt.workarounds.remove_service_workers:
+ reason = 'Explicitly enabled'
else:
- # Otherwise, just nuke it when the Qt version changed.
- affected = configfiles.state.qt_version_changed
-
- if not affected:
return
- service_worker_dir = os.path.join(standarddir.data(), 'webengine',
- 'Service Worker')
+ service_worker_dir = os.path.join(
+ standarddir.data(), 'webengine', 'Service Worker')
bak_dir = service_worker_dir + '-bak'
if not os.path.exists(service_worker_dir):
return
- log.init.info("Qt version changed, removing service workers")
+ log.init.info(
+ f"Removing service workers at {service_worker_dir} (reason: {reason})")
# Keep one backup around - we're not 100% sure what persistent data
# could be in there, but this folder can grow to ~300 MB.
diff --git a/tests/end2end/data/service-worker/data.json b/tests/end2end/data/service-worker/data.json
new file mode 100644
index 000000000..6d9590305
--- /dev/null
+++ b/tests/end2end/data/service-worker/data.json
@@ -0,0 +1 @@
+{"foo": "bar"}
diff --git a/tests/end2end/data/service-worker/index.html b/tests/end2end/data/service-worker/index.html
new file mode 100644
index 000000000..b79c9f47b
--- /dev/null
+++ b/tests/end2end/data/service-worker/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Service worker test</title>
+ <script>navigator.serviceWorker.register('worker.js')</script>
+ </head>
+ <body>
+ This page will register a service worker when loaded.
+ </body>
+</html>
diff --git a/tests/end2end/data/service-worker/worker.js b/tests/end2end/data/service-worker/worker.js
new file mode 100644
index 000000000..26a063520
--- /dev/null
+++ b/tests/end2end/data/service-worker/worker.js
@@ -0,0 +1,8 @@
+self.addEventListener('install', event => {
+ console.log("Installing service worker");
+ event.waitUntil(
+ caches.open('example-cache')
+ .then(cache => cache.add('data.json'))
+ .then(self.skipWaiting())
+ );
+});
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
index c4f7282fd..b509e355b 100644
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -19,6 +19,7 @@
"""Test starting qutebrowser with special arguments/environments."""
+import configparser
import subprocess
import sys
import logging
@@ -435,3 +436,57 @@ def test_preferred_colorscheme(request, quteproc_new):
quteproc_new.send_cmd(':jseval matchMedia("(prefers-color-scheme: dark)").matches')
quteproc_new.wait_for(message='True')
+
+
+@pytest.mark.qtwebkit_skip
+@pytest.mark.parametrize('reason', [
+ 'Explicitly enabled',
+ pytest.param('Qt 5.14', marks=utils.qt514),
+ 'Qt version changed',
+ None,
+])
+def test_service_worker_workaround(
+ request, server, quteproc_new, short_tmpdir, reason):
+ """Make sure we remove the QtWebEngine Service Worker directory if configured."""
+ args = _base_args(request.config) + ['--basedir', str(short_tmpdir)]
+ if reason == 'Explicitly enabled':
+ settings_args = ['-s', 'qt.workarounds.remove_service_workers', 'true']
+ else:
+ settings_args = []
+
+ service_worker_dir = short_tmpdir / 'data' / 'webengine' / 'Service Worker'
+
+ # First invocation: Create directory
+ quteproc_new.start(args)
+ quteproc_new.open_path('data/service-worker/index.html')
+ server.wait_for(verb='GET', path='/data/service-worker/data.json')
+ quteproc_new.send_cmd(':quit')
+ quteproc_new.wait_for_quit()
+ assert service_worker_dir.exists()
+
+ # Edit state file if needed
+ state_file = short_tmpdir / 'data' / 'state'
+ if reason == 'Qt 5.14':
+ state_file.remove()
+ elif reason == 'Qt version changed':
+ parser = configparser.ConfigParser()
+ parser.read(state_file)
+ del parser['general']['qt_version']
+ with state_file.open('w', encoding='utf-8') as f:
+ parser.write(f)
+
+ # Second invocation: Directory gets removed (if workaround enabled)
+ quteproc_new.start(args + settings_args)
+ if reason is not None:
+ quteproc_new.wait_for(
+ message=(f'Removing service workers at {service_worker_dir} '
+ f'(reason: {reason})'))
+
+ quteproc_new.send_cmd(':quit')
+ quteproc_new.wait_for_quit()
+
+ if reason is None:
+ assert service_worker_dir.exists()
+ quteproc_new.ensure_not_logged(message='Removing service workers at *')
+ else:
+ assert not service_worker_dir.exists()