diff --git a/src/base/net/downloadmanager.cpp b/src/base/net/downloadmanager.cpp index 21672274d..fa8288f88 100644 --- a/src/base/net/downloadmanager.cpp +++ b/src/base/net/downloadmanager.cpp @@ -42,6 +42,9 @@ #include "downloadhandler.h" #include "downloadmanager.h" +// Spoof Firefox 38 user agent to avoid web server banning +const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0"; + namespace { class NetworkCookieJar: public QNetworkCookieJar @@ -139,7 +142,7 @@ DownloadManager *DownloadManager::instance() return m_instance; } -DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFile, qint64 limit, bool handleRedirectToMagnet) +DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFile, qint64 limit, bool handleRedirectToMagnet, const QString &userAgent) { // Update proxy settings applyProxySettings(); @@ -149,8 +152,10 @@ DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFil const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); QNetworkRequest request(qurl); - // Spoof Firefox 38 user agent to avoid web server banning - request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0"); + if (userAgent.isEmpty()) + request.setRawHeader("User-Agent", DEFAULT_USER_AGENT); + else + request.setRawHeader("User-Agent", userAgent.toUtf8()); // Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents request.setRawHeader("Referer", request.url().toEncoded().data()); diff --git a/src/base/net/downloadmanager.h b/src/base/net/downloadmanager.h index 8621f70bd..9cd34151a 100644 --- a/src/base/net/downloadmanager.h +++ b/src/base/net/downloadmanager.h @@ -51,7 +51,7 @@ namespace Net static void freeInstance(); static DownloadManager *instance(); - DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false); + DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false, const QString &userAgent = ""); QList cookiesForUrl(const QUrl &url) const; bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); bool deleteCookie(const QNetworkCookie &cookie); diff --git a/src/gui/programupdater.cpp b/src/gui/programupdater.cpp index 3514c6f0f..c722d8ec2 100644 --- a/src/gui/programupdater.cpp +++ b/src/gui/programupdater.cpp @@ -28,23 +28,20 @@ * Contact : chris@qbittorrent.org */ -#include -#include -#include #include -#include #include #include #include #include -#include "programupdater.h" #include "base/utils/fs.h" -#include "base/preferences.h" +#include "base/net/downloadmanager.h" +#include "base/net/downloadhandler.h" +#include "programupdater.h" namespace { - const QUrl RSS_URL("http://www.fosshub.com/software/feedqBittorent"); + const QString RSS_URL("http://www.fosshub.com/software/feedqBittorent"); #ifdef Q_OS_MAC const QString OS_TYPE("Mac OS X"); @@ -59,99 +56,73 @@ ProgramUpdater::ProgramUpdater(QObject *parent, bool invokedByUser) : QObject(parent) , m_invokedByUser(invokedByUser) { - m_networkManager = new QNetworkAccessManager(this); - Preferences* const pref = Preferences::instance(); - // Proxy support - if (pref->isProxyEnabled()) { - QNetworkProxy proxy; - switch(pref->getProxyType()) { - case Proxy::SOCKS4: - case Proxy::SOCKS5: - case Proxy::SOCKS5_PW: - proxy.setType(QNetworkProxy::Socks5Proxy); - default: - proxy.setType(QNetworkProxy::HttpProxy); - break; - } - proxy.setHostName(pref->getProxyIp()); - proxy.setPort(pref->getProxyPort()); - // Proxy authentication - if (pref->isProxyAuthEnabled()) { - proxy.setUser(pref->getProxyUsername()); - proxy.setPassword(pref->getProxyPassword()); - } - m_networkManager->setProxy(proxy); - } -} - -ProgramUpdater::~ProgramUpdater() -{ - delete m_networkManager; } void ProgramUpdater::checkForUpdates() { - // SIGNAL/SLOT - connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), - this, SLOT(rssDownloadFinished(QNetworkReply*))); - // Send the request - QNetworkRequest request(RSS_URL); - // Don't change this User-Agent. In case our updater goes haywire, the filehost can indetify it and contact us. - request.setRawHeader("User-Agent", QString("qBittorrent/%1 ProgramUpdater (www.qbittorrent.org)").arg(VERSION).toLocal8Bit()); - m_networkManager->get(request); + Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl( + RSS_URL, false, 0, false, + // Don't change this User-Agent. In case our updater goes haywire, + // the filehost can identify it and contact us. + QString("qBittorrent/%1 ProgramUpdater (www.qbittorrent.org)").arg(VERSION)); + connect(handler, SIGNAL(downloadFinished(QString,QByteArray)), SLOT(rssDownloadFinished(QString,QByteArray))); + connect(handler, SIGNAL(downloadFailed(QString,QString)), SLOT(rssDownloadFailed(QString,QString))); } -void ProgramUpdater::rssDownloadFinished(QNetworkReply *reply) +void ProgramUpdater::rssDownloadFinished(const QString &url, const QByteArray &data) { - // Disconnect SIGNAL/SLOT - disconnect(m_networkManager, 0, this, 0); + Q_UNUSED(url); + qDebug("Finished downloading the new qBittorrent updates RSS"); QString version; - if (!reply->error()) { - qDebug("No download error, good."); - QXmlStreamReader xml(reply); - bool inItem = false; - QString updateLink; - QString type; - - while (!xml.atEnd()) { - xml.readNext(); - - if (xml.isStartElement()) { - if (xml.name() == "item") - inItem = true; - else if (inItem && xml.name() == "link") - updateLink = getStringValue(xml); - else if (inItem && xml.name() == "type") - type = getStringValue(xml); - else if (inItem && xml.name() == "version") - version = getStringValue(xml); - } - else if (xml.isEndElement()) { - if (inItem && xml.name() == "item") { - if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0) { - qDebug("The last update available is %s", qPrintable(version)); - if (!version.isEmpty()) { - qDebug("Detected version is %s", qPrintable(version)); - if (isVersionMoreRecent(version)) - m_updateUrl = updateLink; - } - break; - } + QXmlStreamReader xml(data); + bool inItem = false; + QString updateLink; + QString type; + + while (!xml.atEnd()) { + xml.readNext(); - inItem = false; - updateLink.clear(); - type.clear(); - version.clear(); + if (xml.isStartElement()) { + if (xml.name() == "item") + inItem = true; + else if (inItem && xml.name() == "link") + updateLink = getStringValue(xml); + else if (inItem && xml.name() == "type") + type = getStringValue(xml); + else if (inItem && xml.name() == "version") + version = getStringValue(xml); + } + else if (xml.isEndElement()) { + if (inItem && xml.name() == "item") { + if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0) { + qDebug("The last update available is %s", qPrintable(version)); + if (!version.isEmpty()) { + qDebug("Detected version is %s", qPrintable(version)); + if (isVersionMoreRecent(version)) + m_updateUrl = updateLink; + } + break; } + + inItem = false; + updateLink.clear(); + type.clear(); + version.clear(); } } } emit updateCheckFinished(!m_updateUrl.isEmpty(), version, m_invokedByUser); - // Clean up - reply->deleteLater(); +} + +void ProgramUpdater::rssDownloadFailed(const QString &url, const QString &error) +{ + Q_UNUSED(url); + + qDebug() << "Downloading the new qBittorrent updates RSS failed:" << error; + emit updateCheckFinished(false, QString(), m_invokedByUser); } void ProgramUpdater::updateProgram() diff --git a/src/gui/programupdater.h b/src/gui/programupdater.h index ecf71bd7c..cda228bbb 100644 --- a/src/gui/programupdater.h +++ b/src/gui/programupdater.h @@ -34,30 +34,27 @@ #include #include -class QNetworkReply; -class QNetworkAccessManager; - class ProgramUpdater: public QObject { Q_OBJECT + public: explicit ProgramUpdater(QObject *parent = 0, bool invokedByUser = false); - ~ProgramUpdater(); + void checkForUpdates(); void updateProgram(); -protected: - bool isVersionMoreRecent(const QString &remoteVersion) const; - -protected slots: - void rssDownloadFinished(QNetworkReply* reply); - signals: void updateCheckFinished(bool updateAvailable, QString version, bool invokedByUser); +private slots: + void rssDownloadFinished(const QString &url, const QByteArray &data); + void rssDownloadFailed(const QString &url, const QString &error); + private: + bool isVersionMoreRecent(const QString &remoteVersion) const; + QString m_updateUrl; - QNetworkAccessManager *m_networkManager; bool m_invokedByUser; };