Move handling of certificate errors to webenginetab

This commit is contained in:
Florian Bruhin 2018-06-25 21:04:32 +02:00
parent 8a4bba11ed
commit 81b3ef937e
5 changed files with 50 additions and 41 deletions

View File

@ -893,10 +893,6 @@ class AbstractTab(QWidget):
self._progress = perc
self.load_progress.emit(perc)
@pyqtSlot()
def _on_ssl_errors(self):
self._has_ssl_errors = True
def url(self, requested=False):
raise NotImplementedError

View File

@ -28,6 +28,10 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
"""A wrapper over a QWebEngineCertificateError."""
def __init__(self, error):
super().__init__(error)
self.ignore = False
def __str__(self):
return self._error.errorDescription()
@ -37,5 +41,8 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
self._error.error()),
string=str(self))
def url(self):
return self._error.url()
def is_overridable(self):
return self._error.isOverridable()

View File

@ -31,14 +31,15 @@ from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QEvent, QPoint, QPointF,
from PyQt5.QtGui import QKeyEvent, QIcon
from PyQt5.QtNetwork import QAuthenticator
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript
from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineScript,
QWebEngineCertificateError)
from qutebrowser.config import configdata, config
from qutebrowser.browser import browsertab, mouse, shared
from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
interceptor, webenginequtescheme,
cookies, webenginedownloads,
webenginesettings)
webenginesettings, certificateerror)
from qutebrowser.misc import miscwidgets
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
message, objreg, jinja, debug)
@ -1224,6 +1225,34 @@ class WebEngineTab(browsertab.AbstractTab):
# the old icon is still displayed.
self.icon_changed.emit(QIcon())
@pyqtSlot(certificateerror.CertificateErrorWrapper)
def _on_ssl_errors(self, error):
self._has_ssl_errors = True
url = error.url()
log.webview.debug("Certificate error: {}".format(error))
if error.is_overridable():
error.ignore = shared.ignore_certificate_errors(
url, [error], abort_on=[self.shutting_down, self.load_started])
else:
log.webview.error("Non-overridable certificate error: "
"{}".format(error))
log.webview.debug("ignore {}, URL {}, requested {}".format(
error.ignore, url, self.url(requested=True)))
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-56207
# We can't really know when to show an error page, as the error might
# have happened when loading some resource.
# However, self.url() is not available yet and the requested URL
# might not match the URL we get from the error - so we just apply a
# heuristic here.
if (not qtutils.version_check('5.9') and
not error.ignore and
url.matches(self.url(requested=True), QUrl.RemoveScheme)):
self._show_error_page(url, str(error))
@pyqtSlot(QUrl)
def _on_predicted_navigation(self, url):
"""If we know we're going to visit an URL soon, change the settings.

View File

@ -24,10 +24,11 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWebEngineWidgets import (QWebEngineView, QWebEnginePage,
QWebEngineScript)
QWebEngineScript,
QWebEngineCertificateError)
from qutebrowser.browser import shared
from qutebrowser.browser.webengine import certificateerror, webenginesettings
from qutebrowser.browser.webengine import webenginesettings, certificateerror
from qutebrowser.config import config
from qutebrowser.utils import log, debug, usertypes, jinja, objreg, qtutils
from qutebrowser.misc import miscwidgets
@ -152,11 +153,13 @@ class WebEnginePage(QWebEnginePage):
Signals:
certificate_error: Emitted on certificate errors.
Needs to be directly connected to a slot setting the
'ignore' attribute.
shutting_down: Emitted when the page is shutting down.
navigation_request: Emitted on acceptNavigationRequest.
"""
certificate_error = pyqtSignal()
certificate_error = pyqtSignal(certificateerror.CertificateErrorWrapper)
shutting_down = pyqtSignal()
navigation_request = pyqtSignal(usertypes.NavigationRequest)
@ -181,39 +184,9 @@ class WebEnginePage(QWebEnginePage):
def certificateError(self, error):
"""Handle certificate errors coming from Qt."""
self.certificate_error.emit()
url = error.url()
error = certificateerror.CertificateErrorWrapper(error)
log.webview.debug("Certificate error: {}".format(error))
url_string = url.toDisplayString()
error_page = jinja.render(
'error.html', title="Error loading page: {}".format(url_string),
url=url_string, error=str(error))
if error.is_overridable():
ignore = shared.ignore_certificate_errors(
url, [error], abort_on=[self.loadStarted, self.shutting_down])
else:
log.webview.error("Non-overridable certificate error: "
"{}".format(error))
ignore = False
log.webview.debug("ignore {}, URL {}, requested {}".format(
ignore, url, self.requestedUrl()))
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-56207
# We can't really know when to show an error page, as the error might
# have happened when loading some resource.
# However, self.url() is not available yet and self.requestedUrl()
# might not match the URL we get from the error - so we just apply a
# heuristic here.
if (not qtutils.version_check('5.9') and
not ignore and
url.matches(self.requestedUrl(), QUrl.RemoveScheme)):
self.setHtml(error_page)
return ignore
self.certificate_error.emit(error)
return error.ignore
def javaScriptConfirm(self, url, js_msg):
"""Override javaScriptConfirm to use qutebrowser prompts."""

View File

@ -808,6 +808,10 @@ class WebKitTab(browsertab.AbstractTab):
if navigation.is_main_frame:
self.settings.update_for_url(navigation.url)
@pyqtSlot()
def _on_ssl_errors(self):
self._has_ssl_errors = True
def _connect_signals(self):
view = self._widget
page = view.page()