Move special network replies to their own file.
This commit is contained in:
parent
c4da44e90c
commit
142e90cdd3
@ -31,7 +31,7 @@ else:
|
|||||||
|
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.utils import message, log, usertypes, utils, objreg
|
from qutebrowser.utils import message, log, usertypes, utils, objreg
|
||||||
from qutebrowser.network import qutescheme, schemehandler
|
from qutebrowser.network import qutescheme, networkreply
|
||||||
|
|
||||||
|
|
||||||
class NetworkManager(QNetworkAccessManager):
|
class NetworkManager(QNetworkAccessManager):
|
||||||
@ -148,7 +148,7 @@ class NetworkManager(QNetworkAccessManager):
|
|||||||
"""
|
"""
|
||||||
scheme = req.url().scheme()
|
scheme = req.url().scheme()
|
||||||
if scheme == 'https' and not SSL_AVAILABLE:
|
if scheme == 'https' and not SSL_AVAILABLE:
|
||||||
return schemehandler.ErrorNetworkReply(
|
return networkreply.ErrorNetworkReply(
|
||||||
req, "SSL is not supported by the installed Qt library!",
|
req, "SSL is not supported by the installed Qt library!",
|
||||||
QNetworkReply.ProtocolUnknownError)
|
QNetworkReply.ProtocolUnknownError)
|
||||||
elif scheme in self._scheme_handlers:
|
elif scheme in self._scheme_handlers:
|
||||||
|
128
qutebrowser/network/networkreply.py
Normal file
128
qutebrowser/network/networkreply.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||||
|
|
||||||
|
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||||
|
#
|
||||||
|
# Based on the Eric5 helpviewer,
|
||||||
|
# Copyright (c) 2009 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
"""Special network replies.."""
|
||||||
|
|
||||||
|
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
|
||||||
|
from PyQt5.QtCore import pyqtSlot, QIODevice, QByteArray, QTimer
|
||||||
|
|
||||||
|
|
||||||
|
class FixedDataNetworkReply(QNetworkReply):
|
||||||
|
|
||||||
|
"""QNetworkReply subclass for fixed data."""
|
||||||
|
|
||||||
|
def __init__(self, request, fileData, mimeType, parent=None):
|
||||||
|
"""Constructor.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: reference to the request object (QNetworkRequest)
|
||||||
|
fileData: reference to the data buffer (QByteArray)
|
||||||
|
mimeType: for the reply (string)
|
||||||
|
parent: reference to the parent object (QObject)
|
||||||
|
"""
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._data = fileData
|
||||||
|
|
||||||
|
self.setRequest(request)
|
||||||
|
self.setUrl(request.url())
|
||||||
|
self.setOpenMode(QIODevice.ReadOnly)
|
||||||
|
|
||||||
|
self.setHeader(QNetworkRequest.ContentTypeHeader, mimeType)
|
||||||
|
self.setHeader(QNetworkRequest.ContentLengthHeader,
|
||||||
|
QByteArray.number(len(fileData)))
|
||||||
|
self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200)
|
||||||
|
self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, 'OK')
|
||||||
|
# For some reason, a segfault will be triggered if these lambdas aren't
|
||||||
|
# there.
|
||||||
|
QTimer.singleShot(0, lambda: self.metaDataChanged.emit())
|
||||||
|
QTimer.singleShot(0, lambda: self.readyRead.emit())
|
||||||
|
QTimer.singleShot(0, lambda: self.finished.emit())
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def abort(self):
|
||||||
|
"""Abort the operation."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def bytesAvailable(self):
|
||||||
|
"""Determine the bytes available for being read.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
bytes available (int)
|
||||||
|
"""
|
||||||
|
return len(self._data) + super().bytesAvailable()
|
||||||
|
|
||||||
|
def readData(self, maxlen):
|
||||||
|
"""Retrieve data from the reply object.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
maxlen maximum number of bytes to read (int)
|
||||||
|
|
||||||
|
Return:
|
||||||
|
bytestring containing the data
|
||||||
|
"""
|
||||||
|
len_ = min(maxlen, len(self._data))
|
||||||
|
buf = bytes(self._data[:len_])
|
||||||
|
self._data = self._data[len_:]
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def isFinished(self):
|
||||||
|
"""Check if the reply is finished."""
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorNetworkReply(QNetworkReply):
|
||||||
|
|
||||||
|
"""QNetworkReply which always returns an error."""
|
||||||
|
|
||||||
|
def __init__(self, req, errorstring, error, parent=None):
|
||||||
|
"""Constructor.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
req: The QNetworkRequest associated with this reply.
|
||||||
|
errorstring: The error string to print.
|
||||||
|
error: The numerical error value.
|
||||||
|
parent: The parent to pass to QNetworkReply.
|
||||||
|
"""
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setRequest(req)
|
||||||
|
self.setUrl(req.url())
|
||||||
|
# We don't actually want to read anything, but we still need to open
|
||||||
|
# the device to avoid getting a warning.
|
||||||
|
self.setOpenMode(QIODevice.ReadOnly)
|
||||||
|
self.setError(error, errorstring)
|
||||||
|
# For some reason, a segfault will be triggered if these lambdas aren't
|
||||||
|
# there.
|
||||||
|
QTimer.singleShot(0, lambda: self.error.emit(error))
|
||||||
|
QTimer.singleShot(0, lambda: self.finished.emit())
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
"""Do nothing since it's a fake reply."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def bytesAvailable(self):
|
||||||
|
"""We always have 0 bytes available."""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def readData(self):
|
||||||
|
"""No data available."""
|
||||||
|
return bytes()
|
@ -30,7 +30,7 @@ Module attributes:
|
|||||||
from PyQt5.QtNetwork import QNetworkReply
|
from PyQt5.QtNetwork import QNetworkReply
|
||||||
|
|
||||||
import qutebrowser
|
import qutebrowser
|
||||||
from qutebrowser.network import schemehandler
|
from qutebrowser.network import schemehandler, networkreply
|
||||||
from qutebrowser.utils import version, utils, jinja, log, message, docutils
|
from qutebrowser.utils import version, utils, jinja, log, message, docutils
|
||||||
|
|
||||||
|
|
||||||
@ -65,16 +65,16 @@ class QuteSchemeHandler(schemehandler.SchemeHandler):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
errorstr = "No handler found for {}!".format(
|
errorstr = "No handler found for {}!".format(
|
||||||
request.url().toDisplayString())
|
request.url().toDisplayString())
|
||||||
return schemehandler.ErrorNetworkReply(
|
return networkreply.ErrorNetworkReply(
|
||||||
request, errorstr, QNetworkReply.ContentNotFoundError,
|
request, errorstr, QNetworkReply.ContentNotFoundError,
|
||||||
self.parent())
|
self.parent())
|
||||||
try:
|
try:
|
||||||
data = handler(self._win_id, request)
|
data = handler(self._win_id, request)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
return schemehandler.ErrorNetworkReply(
|
return networkreply.ErrorNetworkReply(
|
||||||
request, str(e), QNetworkReply.ContentNotFoundError,
|
request, str(e), QNetworkReply.ContentNotFoundError,
|
||||||
self.parent())
|
self.parent())
|
||||||
return schemehandler.SpecialNetworkReply(
|
return networkreply.FixedDataNetworkReply(
|
||||||
request, data, 'text/html', self.parent())
|
request, data, 'text/html', self.parent())
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@
|
|||||||
|
|
||||||
"""Base class for custom scheme handlers."""
|
"""Base class for custom scheme handlers."""
|
||||||
|
|
||||||
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
|
from PyQt5.QtCore import QObject
|
||||||
from PyQt5.QtCore import pyqtSlot, QObject, QIODevice, QByteArray, QTimer
|
|
||||||
|
|
||||||
|
|
||||||
class SchemeHandler(QObject):
|
class SchemeHandler(QObject):
|
||||||
@ -50,105 +49,3 @@ class SchemeHandler(QObject):
|
|||||||
A QNetworkReply.
|
A QNetworkReply.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class SpecialNetworkReply(QNetworkReply):
|
|
||||||
|
|
||||||
"""QNetworkReply subclass for special data."""
|
|
||||||
|
|
||||||
def __init__(self, request, fileData, mimeType, parent=None):
|
|
||||||
"""Constructor.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
request: reference to the request object (QNetworkRequest)
|
|
||||||
fileData: reference to the data buffer (QByteArray)
|
|
||||||
mimeType: for the reply (string)
|
|
||||||
parent: reference to the parent object (QObject)
|
|
||||||
"""
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
self._data = fileData
|
|
||||||
|
|
||||||
self.setRequest(request)
|
|
||||||
self.setUrl(request.url())
|
|
||||||
self.setOpenMode(QIODevice.ReadOnly)
|
|
||||||
|
|
||||||
self.setHeader(QNetworkRequest.ContentTypeHeader, mimeType)
|
|
||||||
self.setHeader(QNetworkRequest.ContentLengthHeader,
|
|
||||||
QByteArray.number(len(fileData)))
|
|
||||||
self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200)
|
|
||||||
self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, 'OK')
|
|
||||||
# For some reason, a segfault will be triggered if these lambdas aren't
|
|
||||||
# there.
|
|
||||||
QTimer.singleShot(0, lambda: self.metaDataChanged.emit())
|
|
||||||
QTimer.singleShot(0, lambda: self.readyRead.emit())
|
|
||||||
QTimer.singleShot(0, lambda: self.finished.emit())
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def abort(self):
|
|
||||||
"""Abort the operation."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def bytesAvailable(self):
|
|
||||||
"""Determine the bytes available for being read.
|
|
||||||
|
|
||||||
Return:
|
|
||||||
bytes available (int)
|
|
||||||
"""
|
|
||||||
return len(self._data) + super().bytesAvailable()
|
|
||||||
|
|
||||||
def readData(self, maxlen):
|
|
||||||
"""Retrieve data from the reply object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
maxlen maximum number of bytes to read (int)
|
|
||||||
|
|
||||||
Return:
|
|
||||||
bytestring containing the data
|
|
||||||
"""
|
|
||||||
len_ = min(maxlen, len(self._data))
|
|
||||||
buf = bytes(self._data[:len_])
|
|
||||||
self._data = self._data[len_:]
|
|
||||||
return buf
|
|
||||||
|
|
||||||
def isFinished(self):
|
|
||||||
"""Check if the reply is finished."""
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorNetworkReply(QNetworkReply):
|
|
||||||
|
|
||||||
"""QNetworkReply which always returns an error."""
|
|
||||||
|
|
||||||
def __init__(self, req, errorstring, error, parent=None):
|
|
||||||
"""Constructor.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
req: The QNetworkRequest associated with this reply.
|
|
||||||
errorstring: The error string to print.
|
|
||||||
error: The numerical error value.
|
|
||||||
parent: The parent to pass to QNetworkReply.
|
|
||||||
"""
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setRequest(req)
|
|
||||||
self.setUrl(req.url())
|
|
||||||
# We don't actually want to read anything, but we still need to open
|
|
||||||
# the device to avoid getting a warning.
|
|
||||||
self.setOpenMode(QIODevice.ReadOnly)
|
|
||||||
self.setError(error, errorstring)
|
|
||||||
# For some reason, a segfault will be triggered if these lambdas aren't
|
|
||||||
# there.
|
|
||||||
QTimer.singleShot(0, lambda: self.error.emit(error))
|
|
||||||
QTimer.singleShot(0, lambda: self.finished.emit())
|
|
||||||
|
|
||||||
def abort(self):
|
|
||||||
"""Do nothing since it's a fake reply."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def bytesAvailable(self):
|
|
||||||
"""We always have 0 bytes available."""
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def readData(self):
|
|
||||||
"""No data available."""
|
|
||||||
return bytes()
|
|
||||||
|
Loading…
Reference in New Issue
Block a user