mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-14 01:03:08 -07:00
Improve DownloadManager.
Now we can use downloaded data directly without saving to file. We also can disable redirection to Magnet URI handling (useful for non-torrent files downloading).
This commit is contained in:
parent
336519b7b5
commit
c702a7e426
11 changed files with 45 additions and 27 deletions
|
@ -1049,7 +1049,7 @@ bool Session::addTorrent(QString source, const AddTorrentParams ¶ms)
|
||||||
if (Utils::Misc::isUrl(source)) {
|
if (Utils::Misc::isUrl(source)) {
|
||||||
Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source));
|
Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source));
|
||||||
// Launch downloader
|
// Launch downloader
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, 10485760 /* 10MB */);
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, true, 10485760 /* 10MB */, true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleDownloadFinished(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleDownloadFinished(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailed(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailed(QString, QString)));
|
||||||
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), this, SLOT(handleRedirectedToMagnet(QString, QString)));
|
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), this, SLOT(handleRedirectedToMagnet(QString, QString)));
|
||||||
|
|
|
@ -46,11 +46,13 @@ static QString errorCodeToString(QNetworkReply::NetworkError status);
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
||||||
DownloadHandler::DownloadHandler(QNetworkReply *reply, DownloadManager *manager, qint64 limit)
|
DownloadHandler::DownloadHandler(QNetworkReply *reply, DownloadManager *manager, bool saveToFile, qint64 limit, bool handleRedirectToMagnet)
|
||||||
: QObject(manager)
|
: QObject(manager)
|
||||||
, m_reply(reply)
|
, m_reply(reply)
|
||||||
, m_manager(manager)
|
, m_manager(manager)
|
||||||
|
, m_saveToFile(saveToFile)
|
||||||
, m_sizeLimit(limit)
|
, m_sizeLimit(limit)
|
||||||
|
, m_handleRedirectToMagnet(handleRedirectToMagnet)
|
||||||
, m_url(reply->url().toString())
|
, m_url(reply->url().toString())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
@ -88,11 +90,23 @@ void DownloadHandler::processFinishedDownload()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Success
|
// Success
|
||||||
QString filePath;
|
QByteArray replyData = m_reply->readAll();
|
||||||
if (saveToFile(filePath))
|
if (m_reply->rawHeader("Content-Encoding") == "gzip") {
|
||||||
emit downloadFinished(m_url, filePath);
|
// uncompress gzip reply
|
||||||
else
|
Utils::Gzip::uncompress(replyData, replyData);
|
||||||
emit downloadFailed(m_url, tr("I/O Error"));
|
}
|
||||||
|
|
||||||
|
if (m_saveToFile) {
|
||||||
|
QString filePath;
|
||||||
|
if (saveToFile(replyData, filePath))
|
||||||
|
emit downloadFinished(m_url, filePath);
|
||||||
|
else
|
||||||
|
emit downloadFailed(m_url, tr("I/O Error"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emit downloadFinished(m_url, replyData);
|
||||||
|
}
|
||||||
|
|
||||||
this->deleteLater();
|
this->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +140,7 @@ void DownloadHandler::init()
|
||||||
connect(m_reply, SIGNAL(finished()), this, SLOT(processFinishedDownload()));
|
connect(m_reply, SIGNAL(finished()), this, SLOT(processFinishedDownload()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DownloadHandler::saveToFile(QString &filePath)
|
bool DownloadHandler::saveToFile(const QByteArray &replyData, QString &filePath)
|
||||||
{
|
{
|
||||||
QTemporaryFile *tmpfile = new QTemporaryFile;
|
QTemporaryFile *tmpfile = new QTemporaryFile;
|
||||||
if (!tmpfile->open()) {
|
if (!tmpfile->open()) {
|
||||||
|
@ -138,11 +152,6 @@ bool DownloadHandler::saveToFile(QString &filePath)
|
||||||
filePath = tmpfile->fileName();
|
filePath = tmpfile->fileName();
|
||||||
qDebug("Temporary filename is: %s", qPrintable(filePath));
|
qDebug("Temporary filename is: %s", qPrintable(filePath));
|
||||||
if (m_reply->isOpen() || m_reply->open(QIODevice::ReadOnly)) {
|
if (m_reply->isOpen() || m_reply->open(QIODevice::ReadOnly)) {
|
||||||
QByteArray replyData = m_reply->readAll();
|
|
||||||
if (m_reply->rawHeader("Content-Encoding") == "gzip") {
|
|
||||||
// uncompress gzip reply
|
|
||||||
Utils::Gzip::uncompress(replyData, replyData);
|
|
||||||
}
|
|
||||||
tmpfile->write(replyData);
|
tmpfile->write(replyData);
|
||||||
tmpfile->close();
|
tmpfile->close();
|
||||||
// XXX: tmpfile needs to be deleted on Windows before using the file
|
// XXX: tmpfile needs to be deleted on Windows before using the file
|
||||||
|
@ -171,14 +180,20 @@ void DownloadHandler::handleRedirection(QUrl newUrl)
|
||||||
if (newUrlString.startsWith("magnet:", Qt::CaseInsensitive)) {
|
if (newUrlString.startsWith("magnet:", Qt::CaseInsensitive)) {
|
||||||
qDebug("Magnet redirect detected.");
|
qDebug("Magnet redirect detected.");
|
||||||
m_reply->abort();
|
m_reply->abort();
|
||||||
emit redirectedToMagnet(m_url, newUrlString);
|
if (m_handleRedirectToMagnet)
|
||||||
|
emit redirectedToMagnet(m_url, newUrlString);
|
||||||
|
else
|
||||||
|
emit downloadFailed(m_url, tr("Unexpected redirect to magnet URI."));
|
||||||
|
|
||||||
this->deleteLater();
|
this->deleteLater();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DownloadHandler *tmp = m_manager->downloadUrl(newUrlString, m_sizeLimit);
|
DownloadHandler *tmp = m_manager->downloadUrl(newUrlString, m_sizeLimit);
|
||||||
m_reply->deleteLater();
|
m_reply->deleteLater();
|
||||||
m_reply = tmp->m_reply;
|
m_reply = tmp->m_reply;
|
||||||
|
m_saveToFile = tmp->m_saveToFile;
|
||||||
m_sizeLimit = tmp->m_sizeLimit;
|
m_sizeLimit = tmp->m_sizeLimit;
|
||||||
|
m_handleRedirectToMagnet = tmp->m_handleRedirectToMagnet;
|
||||||
init();
|
init();
|
||||||
tmp->m_reply = 0;
|
tmp->m_reply = 0;
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
|
|
@ -47,12 +47,13 @@ namespace Net
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DownloadHandler(QNetworkReply *reply, DownloadManager *manager, qint64 limit = 0);
|
DownloadHandler(QNetworkReply *reply, DownloadManager *manager, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false);
|
||||||
~DownloadHandler();
|
~DownloadHandler();
|
||||||
|
|
||||||
QString url() const;
|
QString url() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void downloadFinished(const QString &url, const QByteArray &data);
|
||||||
void downloadFinished(const QString &url, const QString &filePath);
|
void downloadFinished(const QString &url, const QString &filePath);
|
||||||
void downloadFailed(const QString &url, const QString &reason);
|
void downloadFailed(const QString &url, const QString &reason);
|
||||||
void redirectedToMagnet(const QString &url, const QString &magnetUri);
|
void redirectedToMagnet(const QString &url, const QString &magnetUri);
|
||||||
|
@ -63,12 +64,14 @@ namespace Net
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
bool saveToFile(QString &filePath);
|
bool saveToFile(const QByteArray &replyData, QString &filePath);
|
||||||
void handleRedirection(QUrl newUrl);
|
void handleRedirection(QUrl newUrl);
|
||||||
|
|
||||||
QNetworkReply *m_reply;
|
QNetworkReply *m_reply;
|
||||||
DownloadManager *m_manager;
|
DownloadManager *m_manager;
|
||||||
|
bool m_saveToFile;
|
||||||
qint64 m_sizeLimit;
|
qint64 m_sizeLimit;
|
||||||
|
bool m_handleRedirectToMagnet;
|
||||||
QString m_url;
|
QString m_url;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ DownloadManager *DownloadManager::instance()
|
||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadHandler *DownloadManager::downloadUrl(const QString &url, qint64 limit)
|
DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFile, qint64 limit, bool handleRedirectToMagnet)
|
||||||
{
|
{
|
||||||
// Update proxy settings
|
// Update proxy settings
|
||||||
applyProxySettings();
|
applyProxySettings();
|
||||||
|
@ -91,7 +91,7 @@ DownloadHandler *DownloadManager::downloadUrl(const QString &url, qint64 limit)
|
||||||
qDebug("Downloading %s...", request.url().toEncoded().data());
|
qDebug("Downloading %s...", request.url().toEncoded().data());
|
||||||
// accept gzip
|
// accept gzip
|
||||||
request.setRawHeader("Accept-Encoding", "gzip");
|
request.setRawHeader("Accept-Encoding", "gzip");
|
||||||
return new DownloadHandler(m_networkManager.get(request), this, limit);
|
return new DownloadHandler(m_networkManager.get(request), this, saveToFile, limit, handleRedirectToMagnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QNetworkCookie> DownloadManager::cookiesForUrl(const QString &url) const
|
QList<QNetworkCookie> DownloadManager::cookiesForUrl(const QString &url) const
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Net
|
||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static DownloadManager *instance();
|
static DownloadManager *instance();
|
||||||
|
|
||||||
DownloadHandler *downloadUrl(const QString &url, qint64 limit = 0);
|
DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false);
|
||||||
QList<QNetworkCookie> cookiesForUrl(const QString &url) const;
|
QList<QNetworkCookie> cookiesForUrl(const QString &url) const;
|
||||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ void AddNewTorrentDialog::show(QString source, QWidget *parent)
|
||||||
|
|
||||||
if (Utils::Misc::isUrl(source)) {
|
if (Utils::Misc::isUrl(source)) {
|
||||||
// Launch downloader
|
// Launch downloader
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, 10485760 /* 10MB */);
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, true, 10485760 /* 10MB */, true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), dlg, SLOT(handleDownloadFinished(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), dlg, SLOT(handleDownloadFinished(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), dlg, SLOT(handleDownloadFailed(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), dlg, SLOT(handleDownloadFailed(QString, QString)));
|
||||||
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), dlg, SLOT(handleRedirectedToMagnet(QString, QString)));
|
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), dlg, SLOT(handleRedirectedToMagnet(QString, QString)));
|
||||||
|
|
|
@ -1570,7 +1570,7 @@ void MainWindow::installPython()
|
||||||
{
|
{
|
||||||
setCursor(QCursor(Qt::WaitCursor));
|
setCursor(QCursor(Qt::WaitCursor));
|
||||||
// Download python
|
// Download python
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl("https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi");
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl("https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi", true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(pythonDownloadSuccess(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(pythonDownloadSuccess(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(pythonDownloadFailure(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(pythonDownloadFailure(QString, QString)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ QStringList TrackersAdditionDlg::newTrackers() const
|
||||||
void TrackersAdditionDlg::on_uTorrentListButton_clicked()
|
void TrackersAdditionDlg::on_uTorrentListButton_clicked()
|
||||||
{
|
{
|
||||||
uTorrentListButton->setEnabled(false);
|
uTorrentListButton->setEnabled(false);
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(QString("http://www.torrentz.com/announce_%1").arg(m_torrent->hash()));
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(QString("http://www.torrentz.com/announce_%1").arg(m_torrent->hash()), true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(parseUTorrentList(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(parseUTorrentList(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(getTrackerError(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(getTrackerError(QString, QString)));
|
||||||
//Just to show that it takes times
|
//Just to show that it takes times
|
||||||
|
|
|
@ -66,7 +66,7 @@ RssFeed::RssFeed(RssManager* manager, RssFolder* parent, const QString& url):
|
||||||
connect(manager->rssParser(), SIGNAL(feedParsingFinished(QString,QString)), SLOT(handleFeedParsingFinished(QString,QString)));
|
connect(manager->rssParser(), SIGNAL(feedParsingFinished(QString,QString)), SLOT(handleFeedParsingFinished(QString,QString)));
|
||||||
|
|
||||||
// Download the RSS Feed icon
|
// Download the RSS Feed icon
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(iconUrl());
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(iconUrl(), true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||||
m_iconUrl = handler->url();
|
m_iconUrl = handler->url();
|
||||||
|
@ -167,7 +167,7 @@ bool RssFeed::refresh()
|
||||||
}
|
}
|
||||||
m_loading = true;
|
m_loading = true;
|
||||||
// Download the RSS again
|
// Download the RSS again
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url);
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url, true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||||
m_url = handler->url(); // sync URL encoding
|
m_url = handler->url(); // sync URL encoding
|
||||||
|
|
|
@ -474,7 +474,7 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
|
||||||
trackerItem = new QListWidgetItem();
|
trackerItem = new QListWidgetItem();
|
||||||
trackerItem->setData(Qt::DecorationRole, GuiIconProvider::instance()->getIcon("network-server"));
|
trackerItem->setData(Qt::DecorationRole, GuiIconProvider::instance()->getIcon("network-server"));
|
||||||
|
|
||||||
Net::DownloadHandler *h = Net::DownloadManager::instance()->downloadUrl(QString("http://%1/favicon.ico").arg(host));
|
Net::DownloadHandler *h = Net::DownloadManager::instance()->downloadUrl(QString("http://%1/favicon.ico").arg(host), true);
|
||||||
connect(h, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFavicoDownload(QString, QString)));
|
connect(h, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFavicoDownload(QString, QString)));
|
||||||
connect(h, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleFavicoFailure(QString, QString)));
|
connect(h, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleFavicoFailure(QString, QString)));
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ void TrackerFiltersList::handleFavicoDownload(const QString& url, const QString&
|
||||||
if (url.endsWith(".ico", Qt::CaseInsensitive)) {
|
if (url.endsWith(".ico", Qt::CaseInsensitive)) {
|
||||||
Logger::instance()->addMessage(tr("Couldn't decode favicon for URL `%1`. Trying to download favicon in PNG format.").arg(url),
|
Logger::instance()->addMessage(tr("Couldn't decode favicon for URL `%1`. Trying to download favicon in PNG format.").arg(url),
|
||||||
Log::WARNING);
|
Log::WARNING);
|
||||||
Net::DownloadHandler *h = Net::DownloadManager::instance()->downloadUrl(url.left(url.size() - 4) + ".png");
|
Net::DownloadHandler *h = Net::DownloadManager::instance()->downloadUrl(url.left(url.size() - 4) + ".png", true);
|
||||||
connect(h, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFavicoDownload(QString, QString)));
|
connect(h, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFavicoDownload(QString, QString)));
|
||||||
connect(h, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleFavicoFailure(QString, QString)));
|
connect(h, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleFavicoFailure(QString, QString)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,7 +413,7 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file) {
|
||||||
|
|
||||||
void engineSelectDlg::downloadFromUrl(const QString &url)
|
void engineSelectDlg::downloadFromUrl(const QString &url)
|
||||||
{
|
{
|
||||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(url);
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(url, true);
|
||||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
|
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
|
||||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue