Add request filter API for host blocking
Closes https://github.com/qutebrowser/qutebrowser-extensions/issues/8
This commit is contained in:
parent
3d6f604739
commit
7ad7623d73
37
qutebrowser/api/requests.py
Normal file
37
qutebrowser/api/requests.py
Normal file
@ -0,0 +1,37 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""APIs related to intercepting/blocking requests."""
|
||||
|
||||
import typing
|
||||
|
||||
import attr
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from qutebrowser.extensions import requests
|
||||
# pylint: disable=unused-import
|
||||
from qutebrowser.extensions.requests import Request
|
||||
|
||||
|
||||
def register_filter(reqfilter: requests.RequestFilterType) -> None:
|
||||
"""Register a request filter.
|
||||
|
||||
Whenever a request happens, the filter gets called with a Request object.
|
||||
"""
|
||||
requests.register_filter(reqfilter)
|
@ -119,9 +119,15 @@ class HostBlocker:
|
||||
return False
|
||||
|
||||
host = url.host()
|
||||
return ((host in self._blocked_hosts or
|
||||
host in self._config_blocked_hosts) and
|
||||
not _is_whitelisted_url(url))
|
||||
blocked = ((host in self._blocked_hosts or
|
||||
host in self._config_blocked_hosts) and
|
||||
not _is_whitelisted_url(url))
|
||||
|
||||
if blocked:
|
||||
logger.info("Request to {} blocked by host blocker."
|
||||
.format(url.host()))
|
||||
|
||||
return blocked
|
||||
|
||||
def _read_hosts_file(self, filename, target):
|
||||
"""Read hosts from the given filename.
|
||||
|
@ -26,15 +26,15 @@ from PyQt5.QtWebEngineCore import (QWebEngineUrlRequestInterceptor,
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.browser import shared
|
||||
from qutebrowser.utils import utils, log, debug
|
||||
from qutebrowser.extensions import requests
|
||||
|
||||
|
||||
class RequestInterceptor(QWebEngineUrlRequestInterceptor):
|
||||
|
||||
"""Handle ad blocking and custom headers."""
|
||||
|
||||
def __init__(self, host_blocker, args, parent=None):
|
||||
def __init__(self, args, parent=None):
|
||||
super().__init__(parent)
|
||||
self._host_blocker = host_blocker
|
||||
self._args = args
|
||||
|
||||
def install(self, profile):
|
||||
@ -84,9 +84,10 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
|
||||
return
|
||||
|
||||
# FIXME:qtwebengine only block ads for NavigationTypeOther?
|
||||
if self._host_blocker.is_blocked(url, first_party):
|
||||
log.webview.info("Request to {} blocked by host blocker.".format(
|
||||
url.host()))
|
||||
request = requests.Request(first_party_url=first_party,
|
||||
request_url=url)
|
||||
requests.run_filters(request)
|
||||
if request.is_blocked:
|
||||
info.block(True)
|
||||
|
||||
for header, value in shared.custom_headers(url=url):
|
||||
|
@ -60,10 +60,8 @@ def init():
|
||||
_qute_scheme_handler.install(webenginesettings.private_profile)
|
||||
|
||||
log.init.debug("Initializing request interceptor...")
|
||||
host_blocker = objreg.get('host-blocker')
|
||||
args = objreg.get('args')
|
||||
req_interceptor = interceptor.RequestInterceptor(
|
||||
host_blocker, args=args, parent=app)
|
||||
req_interceptor = interceptor.RequestInterceptor(args=args, parent=app)
|
||||
req_interceptor.install(webenginesettings.default_profile)
|
||||
req_interceptor.install(webenginesettings.private_profile)
|
||||
|
||||
|
@ -39,6 +39,7 @@ from PyQt5.QtCore import QUrl
|
||||
from qutebrowser.browser import downloads
|
||||
from qutebrowser.browser.webkit import webkitelem
|
||||
from qutebrowser.utils import log, objreg, message, usertypes, utils, urlutils
|
||||
from qutebrowser.extensions import requests
|
||||
|
||||
|
||||
@attr.s
|
||||
@ -354,8 +355,9 @@ class _Downloader:
|
||||
# qute, see the comments/discussion on
|
||||
# https://github.com/qutebrowser/qutebrowser/pull/962#discussion_r40256987
|
||||
# and https://github.com/qutebrowser/qutebrowser/issues/1053
|
||||
host_blocker = objreg.get('host-blocker')
|
||||
if host_blocker.is_blocked(url):
|
||||
request = requests.Request(first_party_url=None, request_url=url)
|
||||
requests.run_filters(request)
|
||||
if request.is_blocked:
|
||||
log.downloads.debug("Skipping {}, host-blocked".format(url))
|
||||
# We still need an empty file in the output, QWebView can be pretty
|
||||
# picky about displaying a file correctly when not all assets are
|
||||
|
@ -38,6 +38,7 @@ if MYPY:
|
||||
from qutebrowser.utils import (message, log, usertypes, utils, objreg,
|
||||
urlutils, debug)
|
||||
from qutebrowser.browser import shared
|
||||
from qutebrowser.extensions import requests
|
||||
from qutebrowser.browser.webkit import certificateerror
|
||||
from qutebrowser.browser.webkit.network import (webkitqutescheme, networkreply,
|
||||
filescheme)
|
||||
@ -405,10 +406,10 @@ class NetworkManager(QNetworkAccessManager):
|
||||
# the webpage shutdown here.
|
||||
current_url = QUrl()
|
||||
|
||||
host_blocker = objreg.get('host-blocker')
|
||||
if host_blocker.is_blocked(req.url(), current_url):
|
||||
log.webview.info("Request to {} blocked by host blocker.".format(
|
||||
req.url().host()))
|
||||
request = requests.Request(first_party_url=current_url,
|
||||
request_url=req.url())
|
||||
requests.run_filters(request)
|
||||
if request.is_blocked:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
req, HOSTBLOCK_ERROR_STRING, QNetworkReply.ContentAccessDenied,
|
||||
self)
|
||||
|
53
qutebrowser/extensions/requests.py
Normal file
53
qutebrowser/extensions/requests.py
Normal file
@ -0,0 +1,53 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Infrastructure for filtering requests."""
|
||||
|
||||
import typing
|
||||
|
||||
import attr
|
||||
|
||||
|
||||
@attr.s
|
||||
class Request:
|
||||
|
||||
"""A request which can be blocked."""
|
||||
|
||||
first_party_url = attr.ib() # type: QUrl
|
||||
request_url = attr.ib() # type: QUrl
|
||||
is_blocked = attr.ib(False) # type: bool
|
||||
|
||||
def block(self):
|
||||
"""Block this request."""
|
||||
self.is_blocked = True
|
||||
|
||||
|
||||
RequestFilterType = typing.Callable[[Request], None]
|
||||
|
||||
|
||||
_request_filters = [] # type: typing.List[RequestFilterType]
|
||||
|
||||
|
||||
def register_filter(reqfilter: RequestFilterType) -> None:
|
||||
_request_filters.append(reqfilter)
|
||||
|
||||
|
||||
def run_filters(info):
|
||||
for reqfilter in _request_filters:
|
||||
reqfilter(info)
|
Loading…
Reference in New Issue
Block a user