mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-25 14:04:23 +00:00
Allow to specify proxy option per request
This commit is contained in:
parent
8993d87b32
commit
4745a40f0b
@ -2493,7 +2493,7 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶
|
|||||||
LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source));
|
LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source));
|
||||||
// Launch downloader
|
// Launch downloader
|
||||||
Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
|
Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
|
||||||
, this, &SessionImpl::handleDownloadFinished);
|
, true, this, &SessionImpl::handleDownloadFinished);
|
||||||
m_downloadedTorrents[source] = params;
|
m_downloadedTorrents[source] = params;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ void DNSUpdater::checkPublicIP()
|
|||||||
Q_ASSERT(m_state == OK);
|
Q_ASSERT(m_state == OK);
|
||||||
|
|
||||||
DownloadManager::instance()->download(
|
DownloadManager::instance()->download(
|
||||||
DownloadRequest(u"http://checkip.dyndns.org"_qs).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
|
DownloadRequest(u"http://checkip.dyndns.org"_qs).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
|
||||||
, this, &DNSUpdater::ipRequestFinished);
|
, true, this, &DNSUpdater::ipRequestFinished);
|
||||||
|
|
||||||
m_lastIPCheckTime = QDateTime::currentDateTime();
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
@ -128,8 +128,8 @@ void DNSUpdater::updateDNSService()
|
|||||||
|
|
||||||
m_lastIPCheckTime = QDateTime::currentDateTime();
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
DownloadManager::instance()->download(
|
DownloadManager::instance()->download(
|
||||||
DownloadRequest(getUpdateUrl()).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
|
DownloadRequest(getUpdateUrl()).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2))
|
||||||
, this, &DNSUpdater::ipUpdateFinished);
|
, true, this, &DNSUpdater::ipUpdateFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DNSUpdater::getUpdateUrl() const
|
QString DNSUpdater::getUpdateUrl() const
|
||||||
|
@ -56,16 +56,18 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadHandlerImpl::DownloadHandlerImpl(Net::DownloadManager *manager, const Net::DownloadRequest &downloadRequest)
|
Net::DownloadHandlerImpl::DownloadHandlerImpl(DownloadManager *manager
|
||||||
|
, const DownloadRequest &downloadRequest, const bool useProxy)
|
||||||
: DownloadHandler {manager}
|
: DownloadHandler {manager}
|
||||||
, m_manager {manager}
|
, m_manager {manager}
|
||||||
, m_downloadRequest {downloadRequest}
|
, m_downloadRequest {downloadRequest}
|
||||||
|
, m_useProxy {useProxy}
|
||||||
{
|
{
|
||||||
m_result.url = url();
|
m_result.url = url();
|
||||||
m_result.status = Net::DownloadStatus::Success;
|
m_result.status = DownloadStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::cancel()
|
void Net::DownloadHandlerImpl::cancel()
|
||||||
{
|
{
|
||||||
if (m_reply)
|
if (m_reply)
|
||||||
{
|
{
|
||||||
@ -78,7 +80,7 @@ void DownloadHandlerImpl::cancel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::assignNetworkReply(QNetworkReply *reply)
|
void Net::DownloadHandlerImpl::assignNetworkReply(QNetworkReply *reply)
|
||||||
{
|
{
|
||||||
Q_ASSERT(reply);
|
Q_ASSERT(reply);
|
||||||
Q_ASSERT(!m_reply);
|
Q_ASSERT(!m_reply);
|
||||||
@ -91,17 +93,22 @@ void DownloadHandlerImpl::assignNetworkReply(QNetworkReply *reply)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns original url
|
// Returns original url
|
||||||
QString DownloadHandlerImpl::url() const
|
QString Net::DownloadHandlerImpl::url() const
|
||||||
{
|
{
|
||||||
return m_downloadRequest.url();
|
return m_downloadRequest.url();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Net::DownloadRequest DownloadHandlerImpl::downloadRequest() const
|
Net::DownloadRequest Net::DownloadHandlerImpl::downloadRequest() const
|
||||||
{
|
{
|
||||||
return m_downloadRequest;
|
return m_downloadRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::processFinishedDownload()
|
bool Net::DownloadHandlerImpl::useProxy() const
|
||||||
|
{
|
||||||
|
return m_useProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net::DownloadHandlerImpl::processFinishedDownload()
|
||||||
{
|
{
|
||||||
qDebug("Download finished: %s", qUtf8Printable(url()));
|
qDebug("Download finished: %s", qUtf8Printable(url()));
|
||||||
|
|
||||||
@ -156,7 +163,7 @@ void DownloadHandlerImpl::processFinishedDownload()
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::checkDownloadSize(const qint64 bytesReceived, const qint64 bytesTotal)
|
void Net::DownloadHandlerImpl::checkDownloadSize(const qint64 bytesReceived, const qint64 bytesTotal)
|
||||||
{
|
{
|
||||||
if ((bytesTotal > 0) && (bytesTotal <= m_downloadRequest.limit()))
|
if ((bytesTotal > 0) && (bytesTotal <= m_downloadRequest.limit()))
|
||||||
{
|
{
|
||||||
@ -175,7 +182,7 @@ void DownloadHandlerImpl::checkDownloadSize(const qint64 bytesReceived, const qi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::handleRedirection(const QUrl &newUrl)
|
void Net::DownloadHandlerImpl::handleRedirection(const QUrl &newUrl)
|
||||||
{
|
{
|
||||||
if (m_redirectionCount >= MAX_REDIRECTIONS)
|
if (m_redirectionCount >= MAX_REDIRECTIONS)
|
||||||
{
|
{
|
||||||
@ -202,9 +209,9 @@ void DownloadHandlerImpl::handleRedirection(const QUrl &newUrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto redirected = static_cast<DownloadHandlerImpl *>(
|
auto redirected = static_cast<DownloadHandlerImpl *>(
|
||||||
m_manager->download(Net::DownloadRequest(m_downloadRequest).url(newUrlString)));
|
m_manager->download(DownloadRequest(m_downloadRequest).url(newUrlString), useProxy()));
|
||||||
redirected->m_redirectionCount = m_redirectionCount + 1;
|
redirected->m_redirectionCount = m_redirectionCount + 1;
|
||||||
connect(redirected, &DownloadHandlerImpl::finished, this, [this](const Net::DownloadResult &result)
|
connect(redirected, &DownloadHandlerImpl::finished, this, [this](const DownloadResult &result)
|
||||||
{
|
{
|
||||||
m_result = result;
|
m_result = result;
|
||||||
m_result.url = url();
|
m_result.url = url();
|
||||||
@ -212,18 +219,18 @@ void DownloadHandlerImpl::handleRedirection(const QUrl &newUrl)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::setError(const QString &error)
|
void Net::DownloadHandlerImpl::setError(const QString &error)
|
||||||
{
|
{
|
||||||
m_result.errorString = error;
|
m_result.errorString = error;
|
||||||
m_result.status = Net::DownloadStatus::Failed;
|
m_result.status = DownloadStatus::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadHandlerImpl::finish()
|
void Net::DownloadHandlerImpl::finish()
|
||||||
{
|
{
|
||||||
emit finished(m_result);
|
emit finished(m_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DownloadHandlerImpl::errorCodeToString(const QNetworkReply::NetworkError status)
|
QString Net::DownloadHandlerImpl::errorCodeToString(const QNetworkReply::NetworkError status)
|
||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
|
@ -36,33 +36,38 @@
|
|||||||
class QObject;
|
class QObject;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
class DownloadHandlerImpl final : public Net::DownloadHandler
|
namespace Net
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
class DownloadHandlerImpl final : public DownloadHandler
|
||||||
Q_DISABLE_COPY_MOVE(DownloadHandlerImpl)
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(DownloadHandlerImpl)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DownloadHandlerImpl(Net::DownloadManager *manager, const Net::DownloadRequest &downloadRequest);
|
DownloadHandlerImpl(DownloadManager *manager, const DownloadRequest &downloadRequest, bool useProxy);
|
||||||
|
|
||||||
void cancel() override;
|
void cancel() override;
|
||||||
|
|
||||||
QString url() const;
|
QString url() const;
|
||||||
const Net::DownloadRequest downloadRequest() const;
|
DownloadRequest downloadRequest() const;
|
||||||
|
bool useProxy() const;
|
||||||
|
|
||||||
void assignNetworkReply(QNetworkReply *reply);
|
void assignNetworkReply(QNetworkReply *reply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processFinishedDownload();
|
void processFinishedDownload();
|
||||||
void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal);
|
void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal);
|
||||||
void handleRedirection(const QUrl &newUrl);
|
void handleRedirection(const QUrl &newUrl);
|
||||||
void setError(const QString &error);
|
void setError(const QString &error);
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
static QString errorCodeToString(QNetworkReply::NetworkError status);
|
static QString errorCodeToString(QNetworkReply::NetworkError status);
|
||||||
|
|
||||||
Net::DownloadManager *m_manager = nullptr;
|
DownloadManager *m_manager = nullptr;
|
||||||
QNetworkReply *m_reply = nullptr;
|
QNetworkReply *m_reply = nullptr;
|
||||||
const Net::DownloadRequest m_downloadRequest;
|
const DownloadRequest m_downloadRequest;
|
||||||
short m_redirectionCount = 0;
|
const bool m_useProxy = false;
|
||||||
Net::DownloadResult m_result;
|
short m_redirectionCount = 0;
|
||||||
};
|
DownloadResult m_result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkCookie>
|
#include <QNetworkCookie>
|
||||||
#include <QNetworkCookieJar>
|
#include <QNetworkCookieJar>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
@ -51,101 +52,79 @@ namespace
|
|||||||
{
|
{
|
||||||
// Disguise as Firefox to avoid web server banning
|
// Disguise as Firefox to avoid web server banning
|
||||||
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0";
|
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0";
|
||||||
|
|
||||||
class NetworkCookieJar final : public QNetworkCookieJar
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit NetworkCookieJar(QObject *parent = nullptr)
|
|
||||||
: QNetworkCookieJar(parent)
|
|
||||||
{
|
|
||||||
const QDateTime now = QDateTime::currentDateTime();
|
|
||||||
QList<QNetworkCookie> cookies = Preferences::instance()->getNetworkCookies();
|
|
||||||
for (const QNetworkCookie &cookie : asConst(Preferences::instance()->getNetworkCookies()))
|
|
||||||
{
|
|
||||||
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
|
||||||
cookies.removeAll(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
setAllCookies(cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
~NetworkCookieJar() override
|
|
||||||
{
|
|
||||||
const QDateTime now = QDateTime::currentDateTime();
|
|
||||||
QList<QNetworkCookie> cookies = allCookies();
|
|
||||||
for (const QNetworkCookie &cookie : asConst(allCookies()))
|
|
||||||
{
|
|
||||||
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
|
||||||
cookies.removeAll(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
Preferences::instance()->setNetworkCookies(cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
using QNetworkCookieJar::allCookies;
|
|
||||||
using QNetworkCookieJar::setAllCookies;
|
|
||||||
|
|
||||||
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const override
|
|
||||||
{
|
|
||||||
const QDateTime now = QDateTime::currentDateTime();
|
|
||||||
QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
|
|
||||||
for (const QNetworkCookie &cookie : asConst(QNetworkCookieJar::cookiesForUrl(url)))
|
|
||||||
{
|
|
||||||
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
|
||||||
cookies.removeAll(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url) override
|
|
||||||
{
|
|
||||||
const QDateTime now = QDateTime::currentDateTime();
|
|
||||||
QList<QNetworkCookie> cookies = cookieList;
|
|
||||||
for (const QNetworkCookie &cookie : cookieList)
|
|
||||||
{
|
|
||||||
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
|
||||||
cookies.removeAll(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QNetworkCookieJar::setCookiesFromUrl(cookies, url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QNetworkRequest createNetworkRequest(const Net::DownloadRequest &downloadRequest)
|
|
||||||
{
|
|
||||||
QNetworkRequest request {downloadRequest.url()};
|
|
||||||
|
|
||||||
if (downloadRequest.userAgent().isEmpty())
|
|
||||||
request.setRawHeader("User-Agent", DEFAULT_USER_AGENT);
|
|
||||||
else
|
|
||||||
request.setRawHeader("User-Agent", downloadRequest.userAgent().toUtf8());
|
|
||||||
|
|
||||||
// Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents
|
|
||||||
request.setRawHeader("Referer", request.url().toEncoded().data());
|
|
||||||
#ifdef QT_NO_COMPRESS
|
|
||||||
// The macro "QT_NO_COMPRESS" defined in QT will disable the zlib related features
|
|
||||||
// and reply data auto-decompression in QT will also be disabled. But we can support
|
|
||||||
// gzip encoding and manually decompress the reply data.
|
|
||||||
request.setRawHeader("Accept-Encoding", "gzip");
|
|
||||||
#endif
|
|
||||||
// Qt doesn't support Magnet protocol so we need to handle redirections manually
|
|
||||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
|
|
||||||
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Net::DownloadManager::NetworkCookieJar final : public QNetworkCookieJar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NetworkCookieJar(QObject *parent = nullptr)
|
||||||
|
: QNetworkCookieJar(parent)
|
||||||
|
{
|
||||||
|
const QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = Preferences::instance()->getNetworkCookies();
|
||||||
|
for (const QNetworkCookie &cookie : asConst(Preferences::instance()->getNetworkCookies()))
|
||||||
|
{
|
||||||
|
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAllCookies(cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
~NetworkCookieJar() override
|
||||||
|
{
|
||||||
|
const QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = allCookies();
|
||||||
|
for (const QNetworkCookie &cookie : asConst(allCookies()))
|
||||||
|
{
|
||||||
|
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences::instance()->setNetworkCookies(cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
using QNetworkCookieJar::allCookies;
|
||||||
|
using QNetworkCookieJar::setAllCookies;
|
||||||
|
|
||||||
|
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const override
|
||||||
|
{
|
||||||
|
const QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
|
||||||
|
for (const QNetworkCookie &cookie : asConst(QNetworkCookieJar::cookiesForUrl(url)))
|
||||||
|
{
|
||||||
|
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url) override
|
||||||
|
{
|
||||||
|
const QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = cookieList;
|
||||||
|
for (const QNetworkCookie &cookie : cookieList)
|
||||||
|
{
|
||||||
|
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QNetworkCookieJar::setCookiesFromUrl(cookies, url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Net::DownloadManager *Net::DownloadManager::m_instance = nullptr;
|
Net::DownloadManager *Net::DownloadManager::m_instance = nullptr;
|
||||||
|
|
||||||
Net::DownloadManager::DownloadManager(QObject *parent)
|
Net::DownloadManager::DownloadManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, m_networkCookieJar {new NetworkCookieJar(this)}
|
||||||
{
|
{
|
||||||
connect(&m_networkManager, &QNetworkAccessManager::sslErrors, this, &Net::DownloadManager::ignoreSslErrors);
|
m_networkManager->setCookieJar(m_networkCookieJar);
|
||||||
connect(&m_networkManager, &QNetworkAccessManager::finished, this, &DownloadManager::handleReplyFinished);
|
connect(m_networkManager, &QNetworkAccessManager::sslErrors, this, &Net::DownloadManager::ignoreSslErrors);
|
||||||
|
|
||||||
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
|
connect(ProxyConfigurationManager::instance(), &ProxyConfigurationManager::proxyConfigurationChanged
|
||||||
, this, &DownloadManager::applyProxySettings);
|
, this, &DownloadManager::applyProxySettings);
|
||||||
m_networkManager.setCookieJar(new NetworkCookieJar(this));
|
|
||||||
applyProxySettings();
|
applyProxySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,14 +145,18 @@ Net::DownloadManager *Net::DownloadManager::instance()
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Net::DownloadHandler *Net::DownloadManager::download(const DownloadRequest &downloadRequest)
|
Net::DownloadHandler *Net::DownloadManager::download(const DownloadRequest &downloadRequest, const bool useProxy)
|
||||||
{
|
{
|
||||||
// Process download request
|
// Process download request
|
||||||
const QNetworkRequest request = createNetworkRequest(downloadRequest);
|
const ServiceID id = ServiceID::fromURL(downloadRequest.url());
|
||||||
const ServiceID id = ServiceID::fromURL(request.url());
|
|
||||||
const bool isSequentialService = m_sequentialServices.contains(id);
|
const bool isSequentialService = m_sequentialServices.contains(id);
|
||||||
|
|
||||||
auto downloadHandler = new DownloadHandlerImpl {this, downloadRequest};
|
auto downloadHandler = new DownloadHandlerImpl(this, downloadRequest, useProxy);
|
||||||
|
connect(downloadHandler, &DownloadHandler::finished, this
|
||||||
|
, [this, downloadHandler]
|
||||||
|
{
|
||||||
|
handleDownloadFinished(downloadHandler);
|
||||||
|
});
|
||||||
connect(downloadHandler, &DownloadHandler::finished, downloadHandler, &QObject::deleteLater);
|
connect(downloadHandler, &DownloadHandler::finished, downloadHandler, &QObject::deleteLater);
|
||||||
connect(downloadHandler, &QObject::destroyed, this, [this, id, downloadHandler]()
|
connect(downloadHandler, &QObject::destroyed, this, [this, id, downloadHandler]()
|
||||||
{
|
{
|
||||||
@ -189,7 +172,7 @@ Net::DownloadHandler *Net::DownloadManager::download(const DownloadRequest &down
|
|||||||
qDebug("Downloading %s...", qUtf8Printable(downloadRequest.url()));
|
qDebug("Downloading %s...", qUtf8Printable(downloadRequest.url()));
|
||||||
if (isSequentialService)
|
if (isSequentialService)
|
||||||
m_busyServices.insert(id);
|
m_busyServices.insert(id);
|
||||||
downloadHandler->assignNetworkReply(m_networkManager.get(request));
|
processRequest(downloadHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
return downloadHandler;
|
return downloadHandler;
|
||||||
@ -202,32 +185,32 @@ void Net::DownloadManager::registerSequentialService(const Net::ServiceID &servi
|
|||||||
|
|
||||||
QList<QNetworkCookie> Net::DownloadManager::cookiesForUrl(const QUrl &url) const
|
QList<QNetworkCookie> Net::DownloadManager::cookiesForUrl(const QUrl &url) const
|
||||||
{
|
{
|
||||||
return m_networkManager.cookieJar()->cookiesForUrl(url);
|
return m_networkCookieJar->cookiesForUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Net::DownloadManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
bool Net::DownloadManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
||||||
{
|
{
|
||||||
return m_networkManager.cookieJar()->setCookiesFromUrl(cookieList, url);
|
return m_networkCookieJar->setCookiesFromUrl(cookieList, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QNetworkCookie> Net::DownloadManager::allCookies() const
|
QList<QNetworkCookie> Net::DownloadManager::allCookies() const
|
||||||
{
|
{
|
||||||
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->allCookies();
|
return m_networkCookieJar->allCookies();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net::DownloadManager::setAllCookies(const QList<QNetworkCookie> &cookieList)
|
void Net::DownloadManager::setAllCookies(const QList<QNetworkCookie> &cookieList)
|
||||||
{
|
{
|
||||||
static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->setAllCookies(cookieList);
|
m_networkCookieJar->setAllCookies(cookieList);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Net::DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
bool Net::DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
||||||
{
|
{
|
||||||
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->deleteCookie(cookie);
|
return m_networkCookieJar->deleteCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Net::DownloadManager::hasSupportedScheme(const QString &url)
|
bool Net::DownloadManager::hasSupportedScheme(const QString &url)
|
||||||
{
|
{
|
||||||
const QStringList schemes = instance()->m_networkManager.supportedSchemes();
|
const QStringList schemes = QNetworkAccessManager().supportedSchemes();
|
||||||
return std::any_of(schemes.cbegin(), schemes.cend(), [&url](const QString &scheme)
|
return std::any_of(schemes.cbegin(), schemes.cend(), [&url](const QString &scheme)
|
||||||
{
|
{
|
||||||
return url.startsWith((scheme + u':'), Qt::CaseInsensitive);
|
return url.startsWith((scheme + u':'), Qt::CaseInsensitive);
|
||||||
@ -238,46 +221,42 @@ void Net::DownloadManager::applyProxySettings()
|
|||||||
{
|
{
|
||||||
const auto *proxyManager = ProxyConfigurationManager::instance();
|
const auto *proxyManager = ProxyConfigurationManager::instance();
|
||||||
const ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
|
const ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
|
||||||
QNetworkProxy proxy;
|
|
||||||
|
m_proxy = QNetworkProxy(QNetworkProxy::NoProxy);
|
||||||
|
|
||||||
if (!proxyManager->isProxyOnlyForTorrents() && (proxyConfig.type != ProxyType::None))
|
if (!proxyManager->isProxyOnlyForTorrents() && (proxyConfig.type != ProxyType::None))
|
||||||
{
|
{
|
||||||
// Proxy enabled
|
// Proxy enabled
|
||||||
proxy.setHostName(proxyConfig.ip);
|
|
||||||
proxy.setPort(proxyConfig.port);
|
|
||||||
// Default proxy type is HTTP, we must change if it is SOCKS5
|
|
||||||
if ((proxyConfig.type == ProxyType::SOCKS5) || (proxyConfig.type == ProxyType::SOCKS5_PW))
|
if ((proxyConfig.type == ProxyType::SOCKS5) || (proxyConfig.type == ProxyType::SOCKS5_PW))
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
|
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
|
||||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
m_proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << "using HTTP proxy";
|
qDebug() << Q_FUNC_INFO << "using HTTP proxy";
|
||||||
proxy.setType(QNetworkProxy::HttpProxy);
|
m_proxy.setType(QNetworkProxy::HttpProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_proxy.setHostName(proxyConfig.ip);
|
||||||
|
m_proxy.setPort(proxyConfig.port);
|
||||||
|
|
||||||
// Authentication?
|
// Authentication?
|
||||||
if (proxyManager->isAuthenticationRequired())
|
if (proxyManager->isAuthenticationRequired())
|
||||||
{
|
{
|
||||||
qDebug("Proxy requires authentication, authenticating...");
|
qDebug("Proxy requires authentication, authenticating...");
|
||||||
proxy.setUser(proxyConfig.username);
|
m_proxy.setUser(proxyConfig.username);
|
||||||
proxy.setPassword(proxyConfig.password);
|
m_proxy.setPassword(proxyConfig.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
proxy.setType(QNetworkProxy::NoProxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_networkManager.setProxy(proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net::DownloadManager::handleReplyFinished(const QNetworkReply *reply)
|
void Net::DownloadManager::handleDownloadFinished(DownloadHandlerImpl *finishedHandler)
|
||||||
{
|
{
|
||||||
// QNetworkReply::url() may be different from that of the original request
|
// QNetworkReply::url() may be different from that of the original request
|
||||||
// so we need QNetworkRequest::url() to properly process Sequential Services
|
// so we need QNetworkRequest::url() to properly process Sequential Services
|
||||||
// in the case when the redirection occurred.
|
// in the case when the redirection occurred.
|
||||||
const ServiceID id = ServiceID::fromURL(reply->request().url());
|
const ServiceID id = ServiceID::fromURL(finishedHandler->url());
|
||||||
const auto waitingJobsIter = m_waitingJobs.find(id);
|
const auto waitingJobsIter = m_waitingJobs.find(id);
|
||||||
if ((waitingJobsIter == m_waitingJobs.end()) || waitingJobsIter.value().isEmpty())
|
if ((waitingJobsIter == m_waitingJobs.end()) || waitingJobsIter.value().isEmpty())
|
||||||
{
|
{
|
||||||
@ -286,12 +265,38 @@ void Net::DownloadManager::handleReplyFinished(const QNetworkReply *reply)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto handler = static_cast<DownloadHandlerImpl *>(waitingJobsIter.value().dequeue());
|
auto handler = waitingJobsIter.value().dequeue();
|
||||||
qDebug("Downloading %s...", qUtf8Printable(handler->url()));
|
qDebug("Downloading %s...", qUtf8Printable(handler->url()));
|
||||||
handler->assignNetworkReply(m_networkManager.get(createNetworkRequest(handler->downloadRequest())));
|
processRequest(handler);
|
||||||
handler->disconnect(this);
|
handler->disconnect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Net::DownloadManager::processRequest(DownloadHandlerImpl *downloadHandler)
|
||||||
|
{
|
||||||
|
m_networkManager->setProxy((downloadHandler->useProxy() == true) ? m_proxy : QNetworkProxy(QNetworkProxy::NoProxy));
|
||||||
|
|
||||||
|
const DownloadRequest downloadRequest = downloadHandler->downloadRequest();
|
||||||
|
QNetworkRequest request {downloadRequest.url()};
|
||||||
|
|
||||||
|
if (downloadRequest.userAgent().isEmpty())
|
||||||
|
request.setRawHeader("User-Agent", DEFAULT_USER_AGENT);
|
||||||
|
else
|
||||||
|
request.setRawHeader("User-Agent", downloadRequest.userAgent().toUtf8());
|
||||||
|
|
||||||
|
// Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents
|
||||||
|
request.setRawHeader("Referer", request.url().toEncoded().data());
|
||||||
|
#ifdef QT_NO_COMPRESS
|
||||||
|
// The macro "QT_NO_COMPRESS" defined in QT will disable the zlib related features
|
||||||
|
// and reply data auto-decompression in QT will also be disabled. But we can support
|
||||||
|
// gzip encoding and manually decompress the reply data.
|
||||||
|
request.setRawHeader("Accept-Encoding", "gzip");
|
||||||
|
#endif
|
||||||
|
// Qt doesn't support Magnet protocol so we need to handle redirections manually
|
||||||
|
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
|
||||||
|
|
||||||
|
downloadHandler->assignNetworkReply(m_networkManager->get(request));
|
||||||
|
}
|
||||||
|
|
||||||
void Net::DownloadManager::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
void Net::DownloadManager::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||||
{
|
{
|
||||||
QStringList errorList;
|
QStringList errorList;
|
||||||
|
@ -31,13 +31,14 @@
|
|||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkProxy>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
|
|
||||||
|
class QNetworkAccessManager;
|
||||||
class QNetworkCookie;
|
class QNetworkCookie;
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QSslError;
|
class QSslError;
|
||||||
@ -123,6 +124,8 @@ namespace Net
|
|||||||
void finished(const DownloadResult &result);
|
void finished(const DownloadResult &result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DownloadHandlerImpl;
|
||||||
|
|
||||||
class DownloadManager : public QObject
|
class DownloadManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -133,10 +136,10 @@ namespace Net
|
|||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static DownloadManager *instance();
|
static DownloadManager *instance();
|
||||||
|
|
||||||
DownloadHandler *download(const DownloadRequest &downloadRequest);
|
DownloadHandler *download(const DownloadRequest &downloadRequest, bool useProxy);
|
||||||
|
|
||||||
template <typename Context, typename Func>
|
template <typename Context, typename Func>
|
||||||
void download(const DownloadRequest &downloadRequest, Context context, Func &&slot);
|
void download(const DownloadRequest &downloadRequest, bool useProxy, Context context, Func &&slot);
|
||||||
|
|
||||||
void registerSequentialService(const ServiceID &serviceID);
|
void registerSequentialService(const ServiceID &serviceID);
|
||||||
|
|
||||||
@ -152,23 +155,28 @@ namespace Net
|
|||||||
void ignoreSslErrors(QNetworkReply *, const QList<QSslError> &);
|
void ignoreSslErrors(QNetworkReply *, const QList<QSslError> &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class NetworkCookieJar;
|
||||||
|
|
||||||
explicit DownloadManager(QObject *parent = nullptr);
|
explicit DownloadManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
void applyProxySettings();
|
void applyProxySettings();
|
||||||
void handleReplyFinished(const QNetworkReply *reply);
|
void handleDownloadFinished(DownloadHandlerImpl *finishedHandler);
|
||||||
|
void processRequest(DownloadHandlerImpl *downloadHandler);
|
||||||
|
|
||||||
static DownloadManager *m_instance;
|
static DownloadManager *m_instance;
|
||||||
QNetworkAccessManager m_networkManager;
|
NetworkCookieJar *m_networkCookieJar = nullptr;
|
||||||
|
QNetworkAccessManager *m_networkManager = nullptr;
|
||||||
|
QNetworkProxy m_proxy;
|
||||||
|
|
||||||
QSet<ServiceID> m_sequentialServices;
|
QSet<ServiceID> m_sequentialServices;
|
||||||
QSet<ServiceID> m_busyServices;
|
QSet<ServiceID> m_busyServices;
|
||||||
QHash<ServiceID, QQueue<DownloadHandler *>> m_waitingJobs;
|
QHash<ServiceID, QQueue<DownloadHandlerImpl *>> m_waitingJobs;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Context, typename Func>
|
template <typename Context, typename Func>
|
||||||
void DownloadManager::download(const DownloadRequest &downloadRequest, Context context, Func &&slot)
|
void DownloadManager::download(const DownloadRequest &downloadRequest, bool useProxy, Context context, Func &&slot)
|
||||||
{
|
{
|
||||||
const DownloadHandler *handler = download(downloadRequest);
|
const DownloadHandler *handler = download(downloadRequest, useProxy);
|
||||||
connect(handler, &DownloadHandler::finished, context, slot);
|
connect(handler, &DownloadHandler::finished, context, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ void GeoIPManager::downloadDatabaseFile()
|
|||||||
{
|
{
|
||||||
const QDateTime curDatetime = QDateTime::currentDateTimeUtc();
|
const QDateTime curDatetime = QDateTime::currentDateTimeUtc();
|
||||||
const QString curUrl = DATABASE_URL.arg(QLocale::c().toString(curDatetime, u"yyyy-MM"));
|
const QString curUrl = DATABASE_URL.arg(QLocale::c().toString(curDatetime, u"yyyy-MM"));
|
||||||
DownloadManager::instance()->download({curUrl}, this, &GeoIPManager::downloadFinished);
|
DownloadManager::instance()->download({curUrl}, true, this, &GeoIPManager::downloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GeoIPManager::lookup(const QHostAddress &hostAddr) const
|
QString GeoIPManager::lookup(const QHostAddress &hostAddr) const
|
||||||
|
@ -148,7 +148,7 @@ void Feed::refresh()
|
|||||||
|
|
||||||
// NOTE: Should we allow manually refreshing for disabled session?
|
// NOTE: Should we allow manually refreshing for disabled session?
|
||||||
|
|
||||||
m_downloadHandler = Net::DownloadManager::instance()->download(m_url);
|
m_downloadHandler = Net::DownloadManager::instance()->download(m_url, true);
|
||||||
connect(m_downloadHandler, &Net::DownloadHandler::finished, this, &Feed::handleDownloadFinished);
|
connect(m_downloadHandler, &Net::DownloadHandler::finished, this, &Feed::handleDownloadFinished);
|
||||||
|
|
||||||
if (!m_iconPath.exists())
|
if (!m_iconPath.exists())
|
||||||
@ -378,7 +378,7 @@ void Feed::downloadIcon()
|
|||||||
const auto iconUrl = u"%1://%2/favicon.ico"_qs.arg(url.scheme(), url.host());
|
const auto iconUrl = u"%1://%2/favicon.ico"_qs.arg(url.scheme(), url.host());
|
||||||
Net::DownloadManager::instance()->download(
|
Net::DownloadManager::instance()->download(
|
||||||
Net::DownloadRequest(iconUrl).saveToFile(true).destFileName(m_iconPath)
|
Net::DownloadRequest(iconUrl).saveToFile(true).destFileName(m_iconPath)
|
||||||
, this, &Feed::handleIconDownloadFinished);
|
, true, this, &Feed::handleIconDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Feed::updateArticles(const QList<QVariantHash> &loadedArticles)
|
int Feed::updateArticles(const QList<QVariantHash> &loadedArticles)
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <QDomNode>
|
#include <QDomNode>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
@ -212,7 +213,7 @@ void SearchPluginManager::installPlugin(const QString &source)
|
|||||||
{
|
{
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true)
|
DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true)
|
||||||
, this, &SearchPluginManager::pluginDownloadFinished);
|
, true, this, &SearchPluginManager::pluginDownloadFinished);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -328,7 +329,7 @@ void SearchPluginManager::checkForUpdates()
|
|||||||
// Download version file from update server
|
// Download version file from update server
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
DownloadManager::instance()->download({m_updateUrl + u"versions.txt"}
|
DownloadManager::instance()->download({m_updateUrl + u"versions.txt"}
|
||||||
, this, &SearchPluginManager::versionInfoDownloadFinished);
|
, true, this, &SearchPluginManager::versionInfoDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchDownloadHandler *SearchPluginManager::downloadTorrent(const QString &siteUrl, const QString &url)
|
SearchDownloadHandler *SearchPluginManager::downloadTorrent(const QString &siteUrl, const QString &url)
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -479,8 +480,8 @@ void AddNewTorrentDialog::show(const QString &source, const BitTorrent::AddTorre
|
|||||||
{
|
{
|
||||||
// Launch downloader
|
// Launch downloader
|
||||||
Net::DownloadManager::instance()->download(
|
Net::DownloadManager::instance()->download(
|
||||||
Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
|
Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
|
||||||
, dlg, &AddNewTorrentDialog::handleDownloadFinished);
|
, true, dlg, &AddNewTorrentDialog::handleDownloadFinished);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1948,8 +1948,8 @@ void MainWindow::installPython()
|
|||||||
const auto installerURL = u"https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"_qs;
|
const auto installerURL = u"https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"_qs;
|
||||||
#endif
|
#endif
|
||||||
Net::DownloadManager::instance()->download(
|
Net::DownloadManager::instance()->download(
|
||||||
Net::DownloadRequest(installerURL).saveToFile(true)
|
Net::DownloadRequest(installerURL).saveToFile(true)
|
||||||
, this, &MainWindow::pythonDownloadFinished);
|
, true, this, &MainWindow::pythonDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
|
void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
|
||||||
|
@ -76,8 +76,8 @@ void ProgramUpdater::checkForUpdates() const
|
|||||||
// Don't change this User-Agent. In case our updater goes haywire,
|
// Don't change this User-Agent. In case our updater goes haywire,
|
||||||
// the filehost can identify it and contact us.
|
// the filehost can identify it and contact us.
|
||||||
Net::DownloadManager::instance()->download(
|
Net::DownloadManager::instance()->download(
|
||||||
Net::DownloadRequest(RSS_URL).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2 " ProgramUpdater (www.qbittorrent.org)"))
|
Net::DownloadRequest(RSS_URL).userAgent(QStringLiteral("qBittorrent/" QBT_VERSION_2 " ProgramUpdater (www.qbittorrent.org)"))
|
||||||
, this, &ProgramUpdater::rssDownloadFinished);
|
, true, this, &ProgramUpdater::rssDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProgramUpdater::getNewVersion() const
|
QString ProgramUpdater::getNewVersion() const
|
||||||
|
@ -87,7 +87,7 @@ void TrackersAdditionDialog::onDownloadButtonClicked()
|
|||||||
m_ui->downloadButton->setEnabled(false);
|
m_ui->downloadButton->setEnabled(false);
|
||||||
setCursor(Qt::WaitCursor);
|
setCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
Net::DownloadManager::instance()->download(url, this, &TrackersAdditionDialog::onTorrentListDownloadFinished);
|
Net::DownloadManager::instance()->download(url, true, this, &TrackersAdditionDialog::onTorrentListDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackersAdditionDialog::onTorrentListDownloadFinished(const Net::DownloadResult &result)
|
void TrackersAdditionDialog::onTorrentListDownloadFinished(const Net::DownloadResult &result)
|
||||||
|
@ -311,8 +311,8 @@ void PluginSelectDialog::addNewPlugin(const QString &pluginName)
|
|||||||
// Icon is missing, we must download it
|
// Icon is missing, we must download it
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
DownloadManager::instance()->download(
|
DownloadManager::instance()->download(
|
||||||
DownloadRequest(plugin->url + u"/favicon.ico").saveToFile(true)
|
DownloadRequest(plugin->url + u"/favicon.ico").saveToFile(true)
|
||||||
, this, &PluginSelectDialog::iconDownloadFinished);
|
, true, this, &PluginSelectDialog::iconDownloadFinished);
|
||||||
}
|
}
|
||||||
item->setText(PLUGIN_VERSION, plugin->version.toString());
|
item->setText(PLUGIN_VERSION, plugin->version.toString());
|
||||||
}
|
}
|
||||||
|
@ -658,8 +658,8 @@ void TrackerFiltersList::downloadFavicon(const QString &url)
|
|||||||
{
|
{
|
||||||
if (!m_downloadTrackerFavicon) return;
|
if (!m_downloadTrackerFavicon) return;
|
||||||
Net::DownloadManager::instance()->download(
|
Net::DownloadManager::instance()->download(
|
||||||
Net::DownloadRequest(url).saveToFile(true)
|
Net::DownloadRequest(url).saveToFile(true), true
|
||||||
, this, &TrackerFiltersList::handleFavicoDownloadFinished);
|
, this, &TrackerFiltersList::handleFavicoDownloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult &result)
|
void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult &result)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user