diff options
author | Florian Bruhin <me@the-compiler.org> | 2021-01-27 14:06:21 +0100 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2021-01-27 14:06:21 +0100 |
commit | 7d8fd507924309227ebb6c11c3d32cb0b013d238 (patch) | |
tree | efbc2f302b577b51ed59c8b8092908f843daba4d | |
parent | b0c812b239e000da384c04f716e8ec9f38ad870a (diff) | |
download | qutebrowser-7d8fd507924309227ebb6c11c3d32cb0b013d238.tar.gz qutebrowser-7d8fd507924309227ebb6c11c3d32cb0b013d238.zip |
Add qt.workarounds.remove_service_workers setting
See #5656, #5634
-rw-r--r-- | doc/changelog.asciidoc | 4 | ||||
-rw-r--r-- | doc/help/settings.asciidoc | 11 | ||||
-rw-r--r-- | qutebrowser/config/configdata.yml | 13 | ||||
-rw-r--r-- | qutebrowser/misc/backendproblem.py | 17 | ||||
-rw-r--r-- | tests/end2end/data/service-worker/data.json | 1 | ||||
-rw-r--r-- | tests/end2end/data/service-worker/index.html | 11 | ||||
-rw-r--r-- | tests/end2end/data/service-worker/worker.js | 8 | ||||
-rw-r--r-- | tests/end2end/test_invocations.py | 55 |
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() |