--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helpviewer/Network/FollowRedirectReply.py Sun Jul 22 15:32:52 2012 +0200 @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a network reply delegate allowing to check redirects. +""" + +from PyQt4.QtCore import pyqtSignal, QObject +from PyQt4.QtNetwork import QNetworkRequest + + +class FollowRedirectReply(QObject): + """ + Class implementing a network reply delegate allowing to check redirects + """ + finished = pyqtSignal() + + def __init__(self, url, manager, maxRedirects=5): + """ + Constructor + + @param url URL to get (QUrl) + @param manager reference to the network access manager (QNetworkAccessManager) + @keyparam maxRedirects maximum allowed redirects (integer) + """ + super().__init__() + + self.__manager = manager + self.__maxRedirects = maxRedirects + self.__redirectCount = 0 + + self.__reply = self.__manager.get(QNetworkRequest(url)) + self.__reply.finished[()].connect(self.__replyFinished) + + def reply(self): + """ + Public method to get the reply object. + + @return reference to the reply object (QNetworkReply) + """ + return self.__reply + + def originalUrl(self): + """ + Public method to get the original URL. + + @return original URL (QUrl) + """ + return self.__reply.request().url() + + def url(self): + """ + Public method to get the final URL (after redirects). + + @return final URL (QUrl) + """ + return self.__reply.url() + + def error(self): + """ + Public method to get the error information. + + @return error code (QNetworkReply.NetworkError) + """ + return self.__reply.error() + + def readAll(self): + """ + Public method to read all received data. + + @return received raw data (QByteArray) + """ + return self.__reply.readAll() + + def __replyFinished(self): + """ + Private slot handling the receipt of the requested data. + """ + replyStatus = self.__reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + if (replyStatus != 301 and replyStatus != 302) or \ + self.__redirectCount == self.__maxRedirects: + self.finished.emit() + return + + self.__redirectCount += 1 + + redirectUrl = self.__reply.attribute(QNetworkRequest.RedirectionTargetAttribute) + self.__reply.close() + self.__reply.finished[()].disconnect(self.__replyFinished) + + self.__reply = self.__manager.get(QNetworkRequest(redirectUrl)) + self.__reply.finished[()].connect(self.__replyFinished)