def test_file_pathsep(self, sep): url = QUrl('qute://pdfjs/file') query = QUrlQuery() query.addQueryItem('filename', 'foo{}bar'.format(sep)) url.setQuery(query) with pytest.raises(qutescheme.RequestDeniedError): qutescheme.data_for_url(url)
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.NotFoundError): qutescheme.data_for_url(QUrl('qute://pdfjs/no/file.html')) expected = 'pdfjs resource requested but not found: /no/file.html' assert caplog.messages == [expected]
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): qutescheme.data_for_url(QUrl('qute://pdfjs/no/file.html')) assert len(caplog.records) == 1 assert (caplog.records[0].message == 'pdfjs resource requested but not found: /no/file.html')
def createRequest(self, _op, request, _outgoing_data): """Create a new request. Args: request: const QNetworkRequest & req _op: Operation op _outgoing_data: QIODevice * outgoingData Return: A QNetworkReply. """ try: mimetype, data = qutescheme.data_for_url(request.url()) except qutescheme.NoHandlerFound: errorstr = "No handler found for {}!".format( request.url().toDisplayString()) return networkreply.ErrorNetworkReply( request, errorstr, QNetworkReply.ContentNotFoundError, self.parent()) except qutescheme.QuteSchemeOSError as e: return networkreply.ErrorNetworkReply( request, str(e), QNetworkReply.ContentNotFoundError, self.parent()) except qutescheme.QuteSchemeError as e: return networkreply.ErrorNetworkReply(request, e.errorstring, e.error, self.parent()) return networkreply.FixedDataNetworkReply(request, data, mimetype, self.parent())
def createRequest(self, _op, request, _outgoing_data): """Create a new request. Args: request: const QNetworkRequest & req _op: Operation op _outgoing_data: QIODevice * outgoingData Return: A QNetworkReply. """ try: mimetype, data = qutescheme.data_for_url(request.url()) except qutescheme.NoHandlerFound: errorstr = "No handler found for {}!".format( request.url().toDisplayString()) return networkreply.ErrorNetworkReply( request, errorstr, QNetworkReply.ContentNotFoundError, self.parent()) except qutescheme.QuteSchemeOSError as e: return networkreply.ErrorNetworkReply( request, str(e), QNetworkReply.ContentNotFoundError, self.parent()) except qutescheme.QuteSchemeError as e: return networkreply.ErrorNetworkReply(request, e.errorstring, e.error, self.parent()) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) return networkreply.RedirectNetworkReply(e.url, self.parent()) return networkreply.FixedDataNetworkReply(request, data, mimetype, self.parent())
def handler(request): """Scheme handler for qute:// URLs. Args: request: QNetworkRequest to answer to. Return: A QNetworkReply. """ try: mimetype, data = qutescheme.data_for_url(request.url()) except qutescheme.NoHandlerFound: errorstr = "No handler found for {}!".format( request.url().toDisplayString()) return networkreply.ErrorNetworkReply( request, errorstr, QNetworkReply.ContentNotFoundError) except qutescheme.QuteSchemeOSError 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.Redirect as e: qtutils.ensure_valid(e.url) return networkreply.RedirectNetworkReply(e.url) return networkreply.FixedDataNetworkReply(request, data, mimetype)
def requestStarted(self, job): """Handle a request for a qute: scheme. This method must be reimplemented by all custom URL scheme handlers. The request is asynchronous and does not need to be handled right away. Args: job: QWebEngineUrlRequestJob """ url = job.requestUrl() if url.scheme() in ['chrome-error', 'chrome-extension']: # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378 job.fail(QWebEngineUrlRequestJob.UrlInvalid) return if not self._check_initiator(job): return if job.requestMethod() != b'GET': job.fail(QWebEngineUrlRequestJob.RequestDenied) return assert url.scheme() == 'qute' log.misc.debug("Got request for {}".format(url.toDisplayString())) try: mimetype, data = qutescheme.data_for_url(url) except qutescheme.Error as e: errors = { qutescheme.NotFoundError: QWebEngineUrlRequestJob.UrlNotFound, qutescheme.UrlInvalidError: QWebEngineUrlRequestJob.UrlInvalid, qutescheme.RequestDeniedError: QWebEngineUrlRequestJob.RequestDenied, qutescheme.SchemeOSError: QWebEngineUrlRequestJob.UrlNotFound, qutescheme.Error: QWebEngineUrlRequestJob.RequestFailed, } exctype = type(e) log.misc.error("{} while handling qute://* URL".format( exctype.__name__)) job.fail(errors[exctype]) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) job.redirect(e.url) else: log.misc.debug("Returning {} data".format(mimetype)) # We can't just use the QBuffer constructor taking a QByteArray, # because that somehow segfaults... # https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html buf = QBuffer(parent=self) buf.open(QIODevice.WriteOnly) buf.write(data) buf.seek(0) buf.close() job.reply(mimetype.encode('ascii'), buf)
def handler(request, operation, current_url): """Scheme handler for qute:// URLs. Args: request: QNetworkRequest to answer to. operation: The HTTP operation being done. current_url: The page we're on currently. Return: A QNetworkReply. """ if operation != QNetworkAccessManager.GetOperation: return networkreply.ErrorNetworkReply( request, "Unsupported request type", QNetworkReply.ContentOperationNotPermittedError) url = request.url() if ((url.scheme(), url.host(), url.path()) == ('qute', 'settings', '/set')): if current_url != QUrl('qute://settings/'): log.network.warning("Blocking malicious request from {} to {}" .format(current_url.toDisplayString(), url.toDisplayString())) return networkreply.ErrorNetworkReply( request, "Invalid qute://settings request", QNetworkReply.ContentAccessDenied) try: mimetype, data = qutescheme.data_for_url(url) except qutescheme.Error as e: errors = { qutescheme.NotFoundError: QNetworkReply.ContentNotFoundError, qutescheme.UrlInvalidError: QNetworkReply.ContentOperationNotPermittedError, qutescheme.RequestDeniedError: QNetworkReply.ContentAccessDenied, qutescheme.SchemeOSError: QNetworkReply.ContentNotFoundError, qutescheme.Error: QNetworkReply.InternalServerError, } exctype = type(e) log.misc.error("{} while handling qute://* URL".format( exctype.__name__)) return networkreply.ErrorNetworkReply(request, str(e), errors[exctype]) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) return networkreply.RedirectNetworkReply(e.url) return networkreply.FixedDataNetworkReply(request, data, mimetype)
def handler(request, operation, current_url): """Scheme handler for qute:// URLs. Args: request: QNetworkRequest to answer to. operation: The HTTP operation being done. current_url: The page we're on currently. Return: A QNetworkReply. """ if operation != QNetworkAccessManager.GetOperation: return networkreply.ErrorNetworkReply( request, "Unsupported request type", QNetworkReply.ContentOperationNotPermittedError) url = request.url() if ((url.scheme(), url.host(), url.path()) == ('qute', 'settings', '/set')): if current_url != QUrl('qute://settings/'): log.webview.warning("Blocking malicious request from {} to {}" .format(current_url.toDisplayString(), url.toDisplayString())) return networkreply.ErrorNetworkReply( request, "Invalid qute://settings request", QNetworkReply.ContentAccessDenied) try: mimetype, data = qutescheme.data_for_url(url) except qutescheme.Error as e: errors = { qutescheme.NotFoundError: QNetworkReply.ContentNotFoundError, qutescheme.UrlInvalidError: QNetworkReply.ContentOperationNotPermittedError, qutescheme.RequestDeniedError: QNetworkReply.ContentAccessDenied, qutescheme.SchemeOSError: QNetworkReply.ContentNotFoundError, qutescheme.Error: QNetworkReply.InternalServerError, } exctype = type(e) log.misc.error("{} while handling qute://* URL".format( exctype.__name__)) return networkreply.ErrorNetworkReply(request, str(e), errors[exctype]) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) return networkreply.RedirectNetworkReply(e.url) return networkreply.FixedDataNetworkReply(request, data, mimetype)
def test_viewer_page(self, data_tmpdir): """Load the /web/viewer.html page.""" filename = 'foobar.pdf' path = qutescheme._pdf_path(filename) # Make sure that the file exists otherwise the handler will attempt to # redirect to source (it's not necessary to make sure that it's valid # PDF content) with open(path, 'w', encoding='utf-8') as f: f.write('<pdf content>') _mimetype, data = qutescheme.data_for_url( QUrl('qute://pdfjs/web/viewer.html?filename=' + filename)) assert b'PDF.js' in data
def requestStarted(self, job): """Handle a request for a qute: scheme. This method must be reimplemented by all custom URL scheme handlers. The request is asynchronous and does not need to be handled right away. Args: job: QWebEngineUrlRequestJob """ url = job.requestUrl() if url.scheme() == 'chrome-error': # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378 job.fail(QWebEngineUrlRequestJob.UrlInvalid) return assert job.requestMethod() == b'GET' assert url.scheme() == 'qute' 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())) job.fail(QWebEngineUrlRequestJob.UrlNotFound) except qutescheme.QuteSchemeOSError: # FIXME:qtwebengine how do we show a better error here? 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? log.misc.exception("Error while handling qute://* URL") job.fail(QWebEngineUrlRequestJob.RequestFailed) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) job.redirect(e.url) else: log.misc.debug("Returning {} data".format(mimetype)) # We can't just use the QBuffer constructor taking a QByteArray, # because that somehow segfaults... # https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html buf = QBuffer(parent=self) buf.open(QIODevice.WriteOnly) buf.write(data) buf.seek(0) buf.close() job.reply(mimetype.encode('ascii'), buf)
def handler(request, operation, current_url): """Scheme handler for qute:// URLs. Args: request: QNetworkRequest to answer to. operation: The HTTP operation being done. current_url: The page we're on currently. Return: A QNetworkReply. """ if operation != QNetworkAccessManager.GetOperation: return networkreply.ErrorNetworkReply( request, "Unsupported request type", QNetworkReply.ContentOperationNotPermittedError) url = request.url() if ((url.scheme(), url.host(), url.path()) == ('qute', 'settings', '/set')): if current_url != QUrl('qute://settings/'): log.webview.warning( "Blocking malicious request from {} to {}".format( current_url.toDisplayString(), url.toDisplayString())) return networkreply.ErrorNetworkReply( request, "Invalid qute://settings request", QNetworkReply.ContentAccessDenied) 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: return networkreply.ErrorNetworkReply( request, str(e), QNetworkReply.ContentNotFoundError) except qutescheme.QuteSchemeError as e: return networkreply.ErrorNetworkReply(request, e.errorstring, e.error) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) return networkreply.RedirectNetworkReply(e.url) return networkreply.FixedDataNetworkReply(request, data, mimetype)
def requestStarted(self, job): """Handle a request for a qute: scheme. This method must be reimplemented by all custom URL scheme handlers. The request is asynchronous and does not need to be handled right away. Args: job: QWebEngineUrlRequestJob """ url = job.requestUrl() assert job.requestMethod() == b'GET' assert url.scheme() == 'qute' 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())) job.fail(QWebEngineUrlRequestJob.UrlNotFound) except qutescheme.QuteSchemeOSError: # FIXME:qtwebengine how do we show a better error here? 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? log.misc.exception("Error while handling qute://* URL") job.fail(QWebEngineUrlRequestJob.RequestFailed) except qutescheme.Redirect as e: qtutils.ensure_valid(e.url) job.redirect(e.url) else: log.misc.debug("Returning {} data".format(mimetype)) # We can't just use the QBuffer constructor taking a QByteArray, # because that somehow segfaults... # https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html buf = QBuffer(parent=self) buf.open(QIODevice.WriteOnly) buf.write(data) buf.seek(0) buf.close() job.reply(mimetype.encode('ascii'), buf)
def test_qutejavascript_404(self): url = QUrl("qute://javascript/404.js") with pytest.raises(qutescheme.SchemeOSError): qutescheme.data_for_url(url)
def test_existing_resource(self): """Test with a resource that exists.""" _mimetype, data = qutescheme.data_for_url( QUrl('qute://pdfjs/existing/file.html')) assert data == b'foobar'
def test_file_no_filename(self): with pytest.raises(qutescheme.UrlInvalidError): qutescheme.data_for_url(QUrl('qute://pdfjs/file'))
def test_file(self, download_tmpdir): """Load a file via qute://pdfjs/file.""" (download_tmpdir / 'testfile').write_binary(b'foo') _mimetype, data = qutescheme.data_for_url( QUrl('qute://pdfjs/file?filename=testfile')) assert data == b'foo'
def test_viewer_no_filename(self): with pytest.raises(qutescheme.UrlInvalidError): qutescheme.data_for_url(QUrl('qute://pdfjs/web/viewer.html'))
def test_viewer_page(self, data_tmpdir): """Load the /web/viewer.html page.""" _mimetype, data = qutescheme.data_for_url( QUrl('qute://pdfjs/web/viewer.html?filename=foobar')) assert b'PDF.js' in data
def test_qutejavascript_404(self): url = QUrl("qute://javascript/404.js") with pytest.raises(qutescheme.QuteSchemeOSError): qutescheme.data_for_url(url)
def test_viewer_inexistent_file_no_source(self): with pytest.raises(qutescheme.UrlInvalidError, match='Missing source'): qutescheme.data_for_url( QUrl('qute://pdfjs/web/viewer.html?filename=foobar'))
def test_viewer_inexistent_file(self): with pytest.raises(qutescheme.Redirect): qutescheme.data_for_url( QUrl('qute://pdfjs/web/viewer.html?' 'filename=foobar&source=example.org'))