webengine: Initial SSL error support
This commit is contained in:
parent
65625a9dea
commit
6697d692e1
@ -797,8 +797,6 @@ Valid values:
|
|||||||
|
|
||||||
Default: +pass:[ask]+
|
Default: +pass:[ask]+
|
||||||
|
|
||||||
This setting is only available with the QtWebKit backend.
|
|
||||||
|
|
||||||
[[network-dns-prefetch]]
|
[[network-dns-prefetch]]
|
||||||
=== dns-prefetch
|
=== dns-prefetch
|
||||||
Whether to try to pre-fetch DNS entries to speed up browsing.
|
Whether to try to pre-fetch DNS entries to speed up browsing.
|
||||||
|
@ -75,6 +75,23 @@ class UnsupportedOperationError(WebTabError):
|
|||||||
"""Raised when an operation is not supported with the given backend."""
|
"""Raised when an operation is not supported with the given backend."""
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractCertificateErrorWrapper:
|
||||||
|
|
||||||
|
"""A wrapper over an SSL/certificate error."""
|
||||||
|
|
||||||
|
def __init__(self, error):
|
||||||
|
self._error = error
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def is_overridable(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class TabData:
|
class TabData:
|
||||||
|
|
||||||
"""A simple namespace with a fixed set of attributes.
|
"""A simple namespace with a fixed set of attributes.
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
import html
|
import html
|
||||||
|
|
||||||
|
import jinja2
|
||||||
|
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.utils import usertypes, message, log
|
from qutebrowser.utils import usertypes, message, log
|
||||||
|
|
||||||
@ -110,3 +112,48 @@ def javascript_alert(url, js_msg, abort_on):
|
|||||||
html.escape(js_msg))
|
html.escape(js_msg))
|
||||||
message.ask('Javascript alert', msg, mode=usertypes.PromptMode.alert,
|
message.ask('Javascript alert', msg, mode=usertypes.PromptMode.alert,
|
||||||
abort_on=abort_on)
|
abort_on=abort_on)
|
||||||
|
|
||||||
|
|
||||||
|
def ignore_certificate_errors(url, errors, abort_on):
|
||||||
|
"""Display a certificate error question.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL the errors happened in
|
||||||
|
errors: A list of QSslErrors or QWebEngineCertificateErrors
|
||||||
|
|
||||||
|
Return:
|
||||||
|
True if the error should be ignored, False otherwise.
|
||||||
|
"""
|
||||||
|
ssl_strict = config.get('network', 'ssl-strict')
|
||||||
|
log.webview.debug("Certificate errors {!r}, strict {}".format(
|
||||||
|
errors, ssl_strict))
|
||||||
|
|
||||||
|
for error in errors:
|
||||||
|
assert error.is_overridable(), repr(error)
|
||||||
|
|
||||||
|
if ssl_strict == 'ask':
|
||||||
|
err_template = jinja2.Template("""
|
||||||
|
Errors while loading <b>{{url.toDisplayString()}}</b>:<br/>
|
||||||
|
<ul>
|
||||||
|
{% for err in errors %}
|
||||||
|
<li>{{err}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
""".strip())
|
||||||
|
msg = err_template.render(url=url, errors=errors)
|
||||||
|
|
||||||
|
return message.ask(title="Certificate errors - continue?", text=msg,
|
||||||
|
mode=usertypes.PromptMode.yesno, default=False,
|
||||||
|
abort_on=abort_on)
|
||||||
|
elif ssl_strict is False:
|
||||||
|
log.webview.debug("ssl-strict is False, only warning about errors")
|
||||||
|
for err in errors:
|
||||||
|
# FIXME we might want to use warn here (non-fatal error)
|
||||||
|
# https://github.com/The-Compiler/qutebrowser/issues/114
|
||||||
|
message.error('Certificate error: {}'.format(err))
|
||||||
|
return True
|
||||||
|
elif ssl_strict is True:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid ssl_strict value {!r}".format(ssl_strict))
|
||||||
|
raise AssertionError("Not reached")
|
||||||
|
@ -30,7 +30,8 @@ from PyQt5.QtGui import QKeyEvent, QIcon
|
|||||||
# pylint: disable=no-name-in-module,import-error,useless-suppression
|
# pylint: disable=no-name-in-module,import-error,useless-suppression
|
||||||
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
|
from PyQt5.QtWidgets import QOpenGLWidget, QApplication
|
||||||
from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineScript,
|
from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineScript,
|
||||||
QWebEngineProfile)
|
QWebEngineProfile,
|
||||||
|
QWebEngineCertificateError)
|
||||||
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
||||||
|
|
||||||
from qutebrowser.browser import browsertab, mouse, shared
|
from qutebrowser.browser import browsertab, mouse, shared
|
||||||
@ -38,7 +39,7 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
|
|||||||
interceptor, webenginequtescheme,
|
interceptor, webenginequtescheme,
|
||||||
webenginedownloads)
|
webenginedownloads)
|
||||||
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
|
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
|
||||||
objreg, message)
|
objreg, message, debug)
|
||||||
|
|
||||||
|
|
||||||
_qute_scheme_handler = None
|
_qute_scheme_handler = None
|
||||||
@ -78,6 +79,26 @@ _JS_WORLD_MAP = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateErrorWrapper(browsertab.AbstractCertificateErrorWrapper):
|
||||||
|
|
||||||
|
"""A wrapper over a QWebEngineCertificateError."""
|
||||||
|
|
||||||
|
def __init__(self, error):
|
||||||
|
self._error = error
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self._error.errorDescription()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return utils.get_repr(
|
||||||
|
self, error=debug.qenum_key(QWebEngineCertificateError,
|
||||||
|
self._error.error()),
|
||||||
|
string=str(self))
|
||||||
|
|
||||||
|
def is_overridable(self):
|
||||||
|
return self._error.isOverridable()
|
||||||
|
|
||||||
|
|
||||||
class WebEnginePrinting(browsertab.AbstractPrinting):
|
class WebEnginePrinting(browsertab.AbstractPrinting):
|
||||||
|
|
||||||
"""QtWebEngine implementations related to printing."""
|
"""QtWebEngine implementations related to printing."""
|
||||||
|
@ -27,8 +27,9 @@ from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
|
|||||||
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
||||||
|
|
||||||
from qutebrowser.browser import shared
|
from qutebrowser.browser import shared
|
||||||
|
from qutebrowser.browser.webengine import webenginetab
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.utils import log, debug, usertypes, objreg, qtutils
|
from qutebrowser.utils import log, debug, usertypes, objreg, qtutils, jinja
|
||||||
|
|
||||||
|
|
||||||
class WebEngineView(QWebEngineView):
|
class WebEngineView(QWebEngineView):
|
||||||
@ -107,7 +108,7 @@ class WebEnginePage(QWebEnginePage):
|
|||||||
_is_shutting_down: Whether the page is currently shutting down.
|
_is_shutting_down: Whether the page is currently shutting down.
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
certificate_error: FIXME:qtwebengine
|
certificate_error: Emitted on certificate errors.
|
||||||
link_clicked: Emitted when a link was clicked on a page.
|
link_clicked: Emitted when a link was clicked on a page.
|
||||||
shutting_down: Emitted when the page is shutting down.
|
shutting_down: Emitted when the page is shutting down.
|
||||||
"""
|
"""
|
||||||
@ -127,7 +128,29 @@ class WebEnginePage(QWebEnginePage):
|
|||||||
|
|
||||||
def certificateError(self, error):
|
def certificateError(self, error):
|
||||||
self.certificate_error.emit()
|
self.certificate_error.emit()
|
||||||
return super().certificateError(error)
|
url = error.url()
|
||||||
|
error = webenginetab.CertificateErrorWrapper(error)
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
error_page = jinja.render('error.html',
|
||||||
|
title="Error while loading page",
|
||||||
|
url=url.toDisplayString(), error=str(error),
|
||||||
|
icon='', qutescheme=False)
|
||||||
|
|
||||||
|
if not error.is_overridable():
|
||||||
|
log.webview.error("Non-overridable certificate error: "
|
||||||
|
"{}".format(error))
|
||||||
|
self.setHtml(error_page)
|
||||||
|
return False
|
||||||
|
|
||||||
|
ignore = shared.ignore_certificate_errors(
|
||||||
|
url, [error], abort_on=[self.loadStarted, self.shutting_down])
|
||||||
|
|
||||||
|
if not ignore:
|
||||||
|
log.webview.error("Certificate error: {}".format(error))
|
||||||
|
self.setHtml(error_page)
|
||||||
|
|
||||||
|
return ignore
|
||||||
|
|
||||||
def javaScriptConfirm(self, url, js_msg):
|
def javaScriptConfirm(self, url, js_msg):
|
||||||
if self._is_shutting_down:
|
if self._is_shutting_down:
|
||||||
|
@ -24,7 +24,6 @@ import collections
|
|||||||
import netrc
|
import netrc
|
||||||
import html
|
import html
|
||||||
|
|
||||||
import jinja2
|
|
||||||
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, PYQT_VERSION, QCoreApplication,
|
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, PYQT_VERSION, QCoreApplication,
|
||||||
QUrl, QByteArray)
|
QUrl, QByteArray)
|
||||||
from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkReply, QSslError,
|
from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkReply, QSslError,
|
||||||
@ -34,8 +33,9 @@ from qutebrowser.config import config
|
|||||||
from qutebrowser.utils import (message, log, usertypes, utils, objreg, qtutils,
|
from qutebrowser.utils import (message, log, usertypes, utils, objreg, qtutils,
|
||||||
urlutils, debug)
|
urlutils, debug)
|
||||||
from qutebrowser.browser import shared
|
from qutebrowser.browser import shared
|
||||||
from qutebrowser.browser.webkit.network import webkitqutescheme, networkreply
|
from qutebrowser.browser.webkit import webkittab
|
||||||
from qutebrowser.browser.webkit.network import filescheme
|
from qutebrowser.browser.webkit.network import (webkitqutescheme, networkreply,
|
||||||
|
filescheme)
|
||||||
|
|
||||||
|
|
||||||
HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%'
|
HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%'
|
||||||
@ -112,24 +112,6 @@ def init():
|
|||||||
QSslSocket.setDefaultCiphers(good_ciphers)
|
QSslSocket.setDefaultCiphers(good_ciphers)
|
||||||
|
|
||||||
|
|
||||||
class SslError(QSslError):
|
|
||||||
|
|
||||||
"""A QSslError subclass which provides __hash__ on Qt < 5.4."""
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
try:
|
|
||||||
# Qt >= 5.4
|
|
||||||
# pylint: disable=not-callable,useless-suppression
|
|
||||||
return super().__hash__()
|
|
||||||
except TypeError:
|
|
||||||
return hash((self.certificate().toDer(), self.error()))
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return utils.get_repr(
|
|
||||||
self, error=debug.qenum_key(QSslError, self.error()),
|
|
||||||
string=self.errorString())
|
|
||||||
|
|
||||||
|
|
||||||
class NetworkManager(QNetworkAccessManager):
|
class NetworkManager(QNetworkAccessManager):
|
||||||
|
|
||||||
"""Our own QNetworkAccessManager.
|
"""Our own QNetworkAccessManager.
|
||||||
@ -203,6 +185,19 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
self.setCache(cache)
|
self.setCache(cache)
|
||||||
cache.setParent(app)
|
cache.setParent(app)
|
||||||
|
|
||||||
|
def _get_abort_signals(self, owner=None):
|
||||||
|
"""Get a list of signals which should abort a question."""
|
||||||
|
abort_on = [self.shutting_down]
|
||||||
|
if owner is not None:
|
||||||
|
abort_on.append(owner.destroyed)
|
||||||
|
# This might be a generic network manager, e.g. one belonging to a
|
||||||
|
# DownloadManager. In this case, just skip the webview thing.
|
||||||
|
if self._tab_id is not None:
|
||||||
|
tab = objreg.get('tab', scope='tab', window=self._win_id,
|
||||||
|
tab=self._tab_id)
|
||||||
|
abort_on.append(tab.load_started)
|
||||||
|
return abort_on
|
||||||
|
|
||||||
def _ask(self, title, text, mode, owner=None, default=None):
|
def _ask(self, title, text, mode, owner=None, default=None):
|
||||||
"""Ask a blocking question in the statusbar.
|
"""Ask a blocking question in the statusbar.
|
||||||
|
|
||||||
@ -216,17 +211,7 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
Return:
|
Return:
|
||||||
The answer the user gave or None if the prompt was cancelled.
|
The answer the user gave or None if the prompt was cancelled.
|
||||||
"""
|
"""
|
||||||
abort_on = [self.shutting_down]
|
abort_on = self._get_abort_signals(owner)
|
||||||
if owner is not None:
|
|
||||||
abort_on.append(owner.destroyed)
|
|
||||||
|
|
||||||
# This might be a generic network manager, e.g. one belonging to a
|
|
||||||
# DownloadManager. In this case, just skip the webview thing.
|
|
||||||
if self._tab_id is not None:
|
|
||||||
tab = objreg.get('tab', scope='tab', window=self._win_id,
|
|
||||||
tab=self._tab_id)
|
|
||||||
abort_on.append(tab.load_started)
|
|
||||||
|
|
||||||
return message.ask(title=title, text=text, mode=mode,
|
return message.ask(title=title, text=text, mode=mode,
|
||||||
abort_on=abort_on, default=default)
|
abort_on=abort_on, default=default)
|
||||||
|
|
||||||
@ -248,11 +233,8 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
reply: The QNetworkReply that is encountering the errors.
|
reply: The QNetworkReply that is encountering the errors.
|
||||||
errors: A list of errors.
|
errors: A list of errors.
|
||||||
"""
|
"""
|
||||||
errors = [SslError(e) for e in errors]
|
errors = [webkittab.CertificateErrorWrapper(e) for e in errors]
|
||||||
ssl_strict = config.get('network', 'ssl-strict')
|
log.webview.debug("Certificate errors {!r}".format(errors))
|
||||||
log.webview.debug("SSL errors {!r}, strict {}".format(
|
|
||||||
errors, ssl_strict))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
host_tpl = urlutils.host_tuple(reply.url())
|
host_tpl = urlutils.host_tuple(reply.url())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -268,42 +250,22 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
log.webview.debug("Already accepted: {} / "
|
log.webview.debug("Already accepted: {} / "
|
||||||
"rejected {}".format(is_accepted, is_rejected))
|
"rejected {}".format(is_accepted, is_rejected))
|
||||||
|
|
||||||
if (ssl_strict and ssl_strict != 'ask') or is_rejected:
|
if is_rejected:
|
||||||
return
|
return
|
||||||
elif is_accepted:
|
elif is_accepted:
|
||||||
reply.ignoreSslErrors()
|
reply.ignoreSslErrors()
|
||||||
return
|
return
|
||||||
|
|
||||||
if ssl_strict == 'ask':
|
abort_on = self._get_abort_signals(reply)
|
||||||
err_template = jinja2.Template("""
|
ignore = shared.ignore_certificate_errors(reply.url(), errors,
|
||||||
Errors while loading <b>{{url.toDisplayString()}}</b>:<br/>
|
abort_on=abort_on)
|
||||||
<ul>
|
if ignore:
|
||||||
{% for err in errors %}
|
|
||||||
<li>{{err.errorString()}}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
""".strip())
|
|
||||||
msg = err_template.render(url=reply.url(), errors=errors)
|
|
||||||
|
|
||||||
answer = self._ask('SSL errors - continue?', msg,
|
|
||||||
mode=usertypes.PromptMode.yesno, owner=reply,
|
|
||||||
default=False)
|
|
||||||
log.webview.debug("Asked for SSL errors, answer {}".format(answer))
|
|
||||||
if answer:
|
|
||||||
reply.ignoreSslErrors()
|
|
||||||
err_dict = self._accepted_ssl_errors
|
|
||||||
else:
|
|
||||||
err_dict = self._rejected_ssl_errors
|
|
||||||
if host_tpl is not None:
|
|
||||||
err_dict[host_tpl] += errors
|
|
||||||
else:
|
|
||||||
log.webview.debug("ssl-strict is False, only warning about errors")
|
|
||||||
for err in errors:
|
|
||||||
# FIXME we might want to use warn here (non-fatal error)
|
|
||||||
# https://github.com/The-Compiler/qutebrowser/issues/114
|
|
||||||
message.error('SSL error: {}'.format(err.errorString()))
|
|
||||||
reply.ignoreSslErrors()
|
reply.ignoreSslErrors()
|
||||||
self._accepted_ssl_errors[host_tpl] += errors
|
err_dict = self._accepted_ssl_errors
|
||||||
|
else:
|
||||||
|
err_dict = self._rejected_ssl_errors
|
||||||
|
if host_tpl is not None:
|
||||||
|
err_dict[host_tpl] += errors
|
||||||
|
|
||||||
def clear_all_ssl_errors(self):
|
def clear_all_ssl_errors(self):
|
||||||
"""Clear all remembered SSL errors."""
|
"""Clear all remembered SSL errors."""
|
||||||
@ -347,12 +309,7 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
authenticator.setUser(user)
|
authenticator.setUser(user)
|
||||||
authenticator.setPassword(password)
|
authenticator.setPassword(password)
|
||||||
else:
|
else:
|
||||||
abort_on = [self.shutting_down, reply.destroyed]
|
abort_on = self._get_abort_signals(reply)
|
||||||
if self._tab_id is not None:
|
|
||||||
tab = objreg.get('tab', scope='tab', window=self._win_id,
|
|
||||||
tab=self._tab_id)
|
|
||||||
abort_on.append(tab.load_started)
|
|
||||||
|
|
||||||
shared.authentication_required(reply.url(), authenticator,
|
shared.authentication_required(reply.url(), authenticator,
|
||||||
abort_on=abort_on)
|
abort_on=abort_on)
|
||||||
|
|
||||||
|
@ -30,11 +30,12 @@ from PyQt5.QtWidgets import QApplication
|
|||||||
from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
|
from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
from PyQt5.QtPrintSupport import QPrinter
|
from PyQt5.QtPrintSupport import QPrinter
|
||||||
|
from PyQt5.QtNetwork import QSslError
|
||||||
|
|
||||||
from qutebrowser.browser import browsertab
|
from qutebrowser.browser import browsertab
|
||||||
from qutebrowser.browser.webkit import webview, tabhistory, webkitelem
|
from qutebrowser.browser.webkit import webview, tabhistory, webkitelem
|
||||||
from qutebrowser.browser.webkit.network import proxy, webkitqutescheme
|
from qutebrowser.browser.webkit.network import proxy, webkitqutescheme
|
||||||
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log
|
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
@ -49,6 +50,36 @@ def init():
|
|||||||
objreg.register('js-bridge', js_bridge)
|
objreg.register('js-bridge', js_bridge)
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateErrorWrapper(browsertab.AbstractCertificateErrorWrapper):
|
||||||
|
|
||||||
|
"""A wrapper over a QSslError."""
|
||||||
|
|
||||||
|
def __init__(self, error):
|
||||||
|
self._error = error
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self._error.errorString()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return utils.get_repr(
|
||||||
|
self, error=debug.qenum_key(QSslError, self._error.error()),
|
||||||
|
string=str(self))
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
try:
|
||||||
|
# Qt >= 5.4
|
||||||
|
return hash(self._error)
|
||||||
|
except TypeError:
|
||||||
|
return hash((self._error.certificate().toDer(),
|
||||||
|
self._error.error()))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self._error == other._error
|
||||||
|
|
||||||
|
def is_overridable(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class WebKitPrinting(browsertab.AbstractPrinting):
|
class WebKitPrinting(browsertab.AbstractPrinting):
|
||||||
|
|
||||||
"""QtWebKit implementations related to printing."""
|
"""QtWebKit implementations related to printing."""
|
||||||
|
@ -430,8 +430,7 @@ def data(readonly=False):
|
|||||||
"Whether to send DNS requests over the configured proxy."),
|
"Whether to send DNS requests over the configured proxy."),
|
||||||
|
|
||||||
('ssl-strict',
|
('ssl-strict',
|
||||||
SettingValue(typ.BoolAsk(), 'ask',
|
SettingValue(typ.BoolAsk(), 'ask'),
|
||||||
backends=[usertypes.Backend.QtWebKit]),
|
|
||||||
"Whether to validate SSL handshakes."),
|
"Whether to validate SSL handshakes."),
|
||||||
|
|
||||||
('dns-prefetch',
|
('dns-prefetch',
|
||||||
|
@ -166,16 +166,14 @@ Feature: Prompts
|
|||||||
|
|
||||||
# SSL
|
# SSL
|
||||||
|
|
||||||
@qtwebengine_todo: SSL errors are not implemented yet
|
|
||||||
Scenario: SSL error with ssl-strict = false
|
Scenario: SSL error with ssl-strict = false
|
||||||
When I run :debug-clear-ssl-errors
|
When I run :debug-clear-ssl-errors
|
||||||
And I set network -> ssl-strict to false
|
And I set network -> ssl-strict to false
|
||||||
And I load an SSL page
|
And I load an SSL page
|
||||||
And I wait until the SSL page finished loading
|
And I wait until the SSL page finished loading
|
||||||
Then the error "SSL error: *" should be shown
|
Then the error "Certificate error: *" should be shown
|
||||||
And the page should contain the plaintext "Hello World via SSL!"
|
And the page should contain the plaintext "Hello World via SSL!"
|
||||||
|
|
||||||
@qtwebengine_todo: SSL errors are not implemented yet
|
|
||||||
Scenario: SSL error with ssl-strict = true
|
Scenario: SSL error with ssl-strict = true
|
||||||
When I run :debug-clear-ssl-errors
|
When I run :debug-clear-ssl-errors
|
||||||
And I set network -> ssl-strict to true
|
And I set network -> ssl-strict to true
|
||||||
@ -183,7 +181,6 @@ Feature: Prompts
|
|||||||
Then "Error while loading *: SSL handshake failed" should be logged
|
Then "Error while loading *: SSL handshake failed" should be logged
|
||||||
And the page should contain the plaintext "Unable to load page"
|
And the page should contain the plaintext "Unable to load page"
|
||||||
|
|
||||||
@qtwebengine_todo: SSL errors are not implemented yet
|
|
||||||
Scenario: SSL error with ssl-strict = ask -> yes
|
Scenario: SSL error with ssl-strict = ask -> yes
|
||||||
When I run :debug-clear-ssl-errors
|
When I run :debug-clear-ssl-errors
|
||||||
And I set network -> ssl-strict to ask
|
And I set network -> ssl-strict to ask
|
||||||
@ -193,7 +190,6 @@ Feature: Prompts
|
|||||||
And I wait until the SSL page finished loading
|
And I wait until the SSL page finished loading
|
||||||
Then the page should contain the plaintext "Hello World via SSL!"
|
Then the page should contain the plaintext "Hello World via SSL!"
|
||||||
|
|
||||||
@qtwebengine_todo: SSL errors are not implemented yet
|
|
||||||
Scenario: SSL error with ssl-strict = ask -> no
|
Scenario: SSL error with ssl-strict = ask -> no
|
||||||
When I run :debug-clear-ssl-errors
|
When I run :debug-clear-ssl-errors
|
||||||
And I set network -> ssl-strict to ask
|
And I set network -> ssl-strict to ask
|
||||||
@ -473,7 +469,6 @@ Feature: Prompts
|
|||||||
|
|
||||||
# https://github.com/The-Compiler/qutebrowser/issues/1249#issuecomment-175205531
|
# https://github.com/The-Compiler/qutebrowser/issues/1249#issuecomment-175205531
|
||||||
# https://github.com/The-Compiler/qutebrowser/pull/2054#issuecomment-258285544
|
# https://github.com/The-Compiler/qutebrowser/pull/2054#issuecomment-258285544
|
||||||
@qtwebengine_todo: SSL errors are not implemented yet
|
|
||||||
Scenario: Interrupting SSL prompt during a notification prompt
|
Scenario: Interrupting SSL prompt during a notification prompt
|
||||||
When I set content -> notifications to ask
|
When I set content -> notifications to ask
|
||||||
And I set network -> ssl-strict to ask
|
And I set network -> ssl-strict to ask
|
||||||
|
@ -53,6 +53,19 @@ def is_ignored_qt_message(message):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_ignored_lowlevel_message(message):
|
||||||
|
"""Check if we want to ignore a lowlevel process output."""
|
||||||
|
if 'Running without the SUID sandbox!' in message:
|
||||||
|
return True
|
||||||
|
elif message.startswith('Xlib: sequence lost'):
|
||||||
|
# https://travis-ci.org/The-Compiler/qutebrowser/jobs/157941720
|
||||||
|
# ???
|
||||||
|
return True
|
||||||
|
elif 'CERT_PKIXVerifyCert for localhost failed' in message:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class LogLine(testprocess.Line):
|
class LogLine(testprocess.Line):
|
||||||
|
|
||||||
"""A parsed line from the qutebrowser log output.
|
"""A parsed line from the qutebrowser log output.
|
||||||
@ -222,14 +235,7 @@ class QuteProc(testprocess.Process):
|
|||||||
except testprocess.InvalidLine:
|
except testprocess.InvalidLine:
|
||||||
if not line.strip():
|
if not line.strip():
|
||||||
return None
|
return None
|
||||||
elif 'Running without the SUID sandbox!' in line:
|
elif is_ignored_qt_message(line) or is_ignored_lowlevel_message(line):
|
||||||
# QtWebEngine error
|
|
||||||
return None
|
|
||||||
elif line.startswith('Xlib: sequence lost'):
|
|
||||||
# https://travis-ci.org/The-Compiler/qutebrowser/jobs/157941720
|
|
||||||
# ???
|
|
||||||
return None
|
|
||||||
elif is_ignored_qt_message(line):
|
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
Loading…
Reference in New Issue
Block a user