diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 76542b7c4..dc3efd04e 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -45,7 +45,7 @@ import qutebrowser.resources from qutebrowser.completion.models import instances as completionmodels from qutebrowser.commands import cmdutils, runners, cmdexc from qutebrowser.config import style, config, websettings, configexc -from qutebrowser.browser import urlmarks, adblock, history +from qutebrowser.browser import urlmarks, adblock, history, browsertab from qutebrowser.browser.webkit import cookies, cache, downloads from qutebrowser.browser.webkit.network import (qutescheme, proxy, networkmanager) @@ -442,6 +442,8 @@ def _init_modules(args, crash_handler): os.environ.pop('QT_WAYLAND_DISABLE_WINDOWDECORATION', None) temp_downloads = downloads.TempDownloadManager(qApp) objreg.register('temporary-downloads', temp_downloads) + # Init backend-specific stuff + browsertab.init(args) def _init_late_modules(args): diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index d15f53df5..811c84fba 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -55,6 +55,16 @@ def create(win_id, parent=None): return tab_class(win_id=win_id, mode_manager=mode_manager, parent=parent) +def init(args): + """Initialize backend-specific modules.""" + if objreg.get('args').backend == 'webengine': + from qutebrowser.browser.webengine import webenginetab + webenginetab.init() + else: + from qutebrowser.browser.webkit import webkittab + webkittab.init() + + class WebTabError(Exception): """Base class for various errors.""" diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py new file mode 100644 index 000000000..5a1c58fc9 --- /dev/null +++ b/qutebrowser/browser/webengine/interceptor.py @@ -0,0 +1,61 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""A request interceptor taking care of adblocking and custom headers.""" + +from PyQt5.QtWidgets import QApplication +from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor + +from qutebrowser.utils import utils, log + + +class RequestInterceptor(QWebEngineUrlRequestInterceptor): + + """Handle ad blocking and custom headers.""" + + def __init__(self, host_blocker, parent=None): + super().__init__(parent) + self._host_blocker = host_blocker + + def install(self, profile): + """Install the interceptor on the given QWebEngineProfile.""" + profile.setRequestInterceptor(self) + + # Gets called in the IO thread -> showing crash window will fail + @utils.prevent_exceptions(None) + def interceptRequest(self, info): + """Handle the given request. + + Reimplementing this virtual function and setting the interceptor on a + profile makes it possible to intercept URL requests. This function is + executed on the IO thread, and therefore running long tasks here will + block networking. + + info contains the information about the URL request and will track + internally whether its members have been altered. + + Args: + info: QWebEngineUrlRequestInfo &info + """ + # FIXME:qtwebengine only block ads for NavigationTypeOther? + if (bytes(info.requestMethod()) == b'GET' and + self._host_blocker.is_blocked(info.requestUrl())): + log.webview.info("Request to {} blocked by host blocker.".format( + info.requestUrl().host())) + info.block(True) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 79fcc1dfc..81da3fb28 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -27,13 +27,25 @@ import functools from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint, QUrl, QTimer from PyQt5.QtGui import QKeyEvent, QIcon # pylint: disable=no-name-in-module,import-error,useless-suppression -from PyQt5.QtWidgets import QOpenGLWidget -from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript +from PyQt5.QtWidgets import QOpenGLWidget, QApplication +from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineScript, + QWebEngineProfile) # pylint: enable=no-name-in-module,import-error,useless-suppression from qutebrowser.browser import browsertab, mouse -from qutebrowser.browser.webengine import webview, webengineelem, tabhistory -from qutebrowser.utils import usertypes, qtutils, log, javascript, utils +from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory, + interceptor) +from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils, + objreg) + + +def init(): + """Initialize QtWebEngine-specific modules.""" + log.init.debug("Initializing request interceptor...") + host_blocker = objreg.get('host-blocker') + req_interceptor = interceptor.RequestInterceptor( + host_blocker, parent=QApplication.instance()) + req_interceptor.install(QWebEngineProfile.defaultProfile()) class WebEnginePrinting(browsertab.AbstractPrinting): diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index a185bfe7e..fe984b60e 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -35,6 +35,12 @@ from qutebrowser.browser.webkit import webview, tabhistory, webkitelem from qutebrowser.utils import qtutils, objreg, usertypes, utils, log +def init(): + """Initialize QtWebKit-specific modules.""" + # FIXME:qtwebengine Move things we don't need with QtWebEngine here. + pass + + class WebKitPrinting(browsertab.AbstractPrinting): """QtWebKit implementations related to printing."""