WIP: Properly signal scheme errors
This commit is contained in:
parent
2fcdc5a0c9
commit
92fcc523c5
@ -60,36 +60,39 @@ csrf_token = None
|
||||
_HANDLERS = {}
|
||||
|
||||
|
||||
class NoHandlerFound(Exception):
|
||||
class Error(Exception):
|
||||
|
||||
"""Raised when no handler was found for the given URL."""
|
||||
"""Exception for generic errors on a qute:// page."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class QuteSchemeOSError(Exception):
|
||||
class NotFoundError(Error):
|
||||
|
||||
"""Called when there was an OSError inside a handler."""
|
||||
"""Raised when the given URL was not found."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class QuteSchemeError(Exception):
|
||||
class SchemeOSError(Error):
|
||||
|
||||
"""Exception to signal that a handler should return an ErrorReply.
|
||||
"""Raised when there was an OSError inside a handler."""
|
||||
|
||||
Attributes correspond to the arguments in
|
||||
networkreply.ErrorNetworkReply.
|
||||
pass
|
||||
|
||||
Attributes:
|
||||
errorstring: Error string to print.
|
||||
error: Numerical error value.
|
||||
"""
|
||||
|
||||
def __init__(self, errorstring, error):
|
||||
self.errorstring = errorstring
|
||||
self.error = error
|
||||
super().__init__(errorstring)
|
||||
class UrlInvalidError(Error):
|
||||
|
||||
"""Raised when an invalid URL was opened."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class RequestDeniedError(Error):
|
||||
|
||||
"""Raised when the request is forbidden."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Redirect(Exception):
|
||||
@ -180,13 +183,13 @@ def data_for_url(url):
|
||||
try:
|
||||
handler = _HANDLERS[host]
|
||||
except KeyError:
|
||||
raise NoHandlerFound(url)
|
||||
raise NotFoundError("No handler found for {}".format(
|
||||
url.toDisplayString()))
|
||||
|
||||
try:
|
||||
mimetype, data = handler(url)
|
||||
except OSError as e:
|
||||
# FIXME:qtwebengine how to handle this?
|
||||
raise QuteSchemeOSError(e)
|
||||
raise SchemeOSError(e)
|
||||
|
||||
assert mimetype is not None, url
|
||||
if mimetype == 'text/html' and isinstance(data, str):
|
||||
@ -262,13 +265,13 @@ def qute_history(url):
|
||||
offset = QUrlQuery(url).queryItemValue("offset")
|
||||
offset = int(offset) if offset else None
|
||||
except ValueError as e:
|
||||
raise QuteSchemeError("Query parameter offset is invalid", e)
|
||||
raise UrlInvalidError("Query parameter offset is invalid")
|
||||
# Use start_time in query or current time.
|
||||
try:
|
||||
start_time = QUrlQuery(url).queryItemValue("start_time")
|
||||
start_time = float(start_time) if start_time else time.time()
|
||||
except ValueError as e:
|
||||
raise QuteSchemeError("Query parameter start_time is invalid", e)
|
||||
raise UrlInvalidError("Query parameter start_time is invalid")
|
||||
|
||||
return 'text/html', json.dumps(history_data(start_time, offset))
|
||||
else:
|
||||
@ -290,7 +293,7 @@ def qute_javascript(url):
|
||||
path = "javascript" + os.sep.join(path.split('/'))
|
||||
return 'text/html', utils.read_file(path, binary=False)
|
||||
else:
|
||||
raise QuteSchemeError("No file specified", ValueError())
|
||||
raise UrlInvalidError("No file specified")
|
||||
|
||||
|
||||
@add_handler('pyeval')
|
||||
@ -379,7 +382,7 @@ def qute_help(url):
|
||||
try:
|
||||
bdata = utils.read_file(path, binary=True)
|
||||
except OSError as e:
|
||||
raise QuteSchemeOSError(e)
|
||||
raise SchemeOSError(e)
|
||||
mimetype, _encoding = mimetypes.guess_type(urlpath)
|
||||
assert mimetype is not None, url
|
||||
return mimetype, bdata
|
||||
@ -461,8 +464,7 @@ def qute_settings(url):
|
||||
if url.path() == '/set':
|
||||
if url.password() != csrf_token:
|
||||
message.error("Invalid CSRF token for qute://settings!")
|
||||
raise QuteSchemeError("Invalid CSRF token!",
|
||||
QNetworkReply.ContentAccessDenied)
|
||||
raise RequestDeniedError("Invalid CSRF token!")
|
||||
return _qute_settings_set(url)
|
||||
|
||||
# Requests to qute://settings/set should only be allowed from
|
||||
|
@ -80,16 +80,19 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
|
||||
log.misc.debug("Got request for {}".format(url.toDisplayString()))
|
||||
try:
|
||||
mimetype, data = qutescheme.data_for_url(url)
|
||||
except qutescheme.NoHandlerFound:
|
||||
log.misc.debug("No handler found for {}".format(
|
||||
url.toDisplayString()))
|
||||
except qutescheme.NotFoundError:
|
||||
log.misc.exception("Error while handling qute://* URL")
|
||||
job.fail(QWebEngineUrlRequestJob.UrlNotFound)
|
||||
except qutescheme.QuteSchemeOSError:
|
||||
# FIXME:qtwebengine how do we show a better error here?
|
||||
except qutescheme.UrlInvalidError:
|
||||
log.misc.exception("Error while handling qute://* URL")
|
||||
job.fail(QWebEngineUrlRequestJob.UrlInvalid)
|
||||
except qutescheme.RequestDeniedError:
|
||||
log.misc.exception("Error while handling qute://* URL")
|
||||
job.fail(QWebEngineUrlRequestJob.RequestDenied)
|
||||
except qutescheme.SchemeOSError:
|
||||
log.misc.exception("OSError while handling qute://* URL")
|
||||
job.fail(QWebEngineUrlRequestJob.UrlNotFound)
|
||||
except qutescheme.QuteSchemeError:
|
||||
# FIXME:qtwebengine how do we show a better error here?
|
||||
except qutescheme.Error:
|
||||
log.misc.exception("Error while handling qute://* URL")
|
||||
job.fail(QWebEngineUrlRequestJob.RequestFailed)
|
||||
except qutescheme.Redirect as e:
|
||||
|
@ -59,15 +59,21 @@ def handler(request, operation, current_url):
|
||||
|
||||
try:
|
||||
mimetype, data = qutescheme.data_for_url(url)
|
||||
except qutescheme.NoHandlerFound:
|
||||
errorstr = "No handler found for {}!".format(url.toDisplayString())
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, errorstr, QNetworkReply.ContentNotFoundError)
|
||||
except qutescheme.QuteSchemeOSError as e:
|
||||
except qutescheme.NotFoundError as e:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, str(e), QNetworkReply.ContentNotFoundError)
|
||||
except qutescheme.QuteSchemeError as e:
|
||||
return networkreply.ErrorNetworkReply(request, e.errorstring, e.error)
|
||||
except qutescheme.SchemeOSError as e:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, str(e), QNetworkReply.ContentNotFoundError)
|
||||
except qutescheme.UrlInvalidError as e:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, str(e), QNetworkReply.ContentOperationNotPermittedError)
|
||||
except qutescheme.RequestDeniedError as e:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, str(e), QNetworkReply.ContentAccessDenied)
|
||||
except qutescheme.Error as e:
|
||||
return networkreply.ErrorNetworkReply(
|
||||
request, str(e), QNetworkReply.InternalServerError)
|
||||
except qutescheme.Redirect as e:
|
||||
qtutils.ensure_valid(e.url)
|
||||
return networkreply.RedirectNetworkReply(e.url)
|
||||
@ -86,9 +92,8 @@ def qute_pdfjs(url):
|
||||
# information, as the failed pdfjs requests are still in the log.
|
||||
log.misc.warning(
|
||||
"pdfjs resource requested but not found: {}".format(e.path))
|
||||
raise qutescheme.QuteSchemeError("Can't find pdfjs resource "
|
||||
"'{}'".format(e.path),
|
||||
QNetworkReply.ContentNotFoundError)
|
||||
raise qutescheme.NotFoundError("Can't find pdfjs resource '{}'".format(
|
||||
e.path))
|
||||
else:
|
||||
mimetype, _encoding = mimetypes.guess_type(url.fileName())
|
||||
assert mimetype is not None, url
|
||||
|
@ -61,13 +61,13 @@ class TestJavascriptHandler:
|
||||
def test_qutejavascript_404(self):
|
||||
url = QUrl("qute://javascript/404.js")
|
||||
|
||||
with pytest.raises(qutescheme.QuteSchemeOSError):
|
||||
with pytest.raises(qutescheme.SchemeOSError):
|
||||
qutescheme.data_for_url(url)
|
||||
|
||||
def test_qutejavascript_empty_query(self):
|
||||
url = QUrl("qute://javascript")
|
||||
|
||||
with pytest.raises(qutescheme.QuteSchemeError):
|
||||
with pytest.raises(qutescheme.InvalidURLError):
|
||||
qutescheme.qute_javascript(url)
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ class TestPDFJSHandler:
|
||||
def test_nonexisting_resource(self, caplog):
|
||||
"""Test with a resource that does not exist."""
|
||||
with caplog.at_level(logging.WARNING, 'misc'):
|
||||
with pytest.raises(qutescheme.QuteSchemeError):
|
||||
with pytest.raises(qutescheme.NotFoundError):
|
||||
qutescheme.data_for_url(QUrl('qute://pdfjs/no/file.html'))
|
||||
assert len(caplog.records) == 1
|
||||
assert (caplog.records[0].message ==
|
||||
|
Loading…
Reference in New Issue
Block a user