|
|
@ -69,6 +69,8 @@ Net::DownloadHandler::DownloadHandler(QNetworkReply *reply, DownloadManager *man |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reply) |
|
|
|
if (reply) |
|
|
|
assignNetworkReply(reply); |
|
|
|
assignNetworkReply(reply); |
|
|
|
|
|
|
|
m_result.url = url(); |
|
|
|
|
|
|
|
m_result.status = DownloadStatus::Success; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Net::DownloadHandler::~DownloadHandler() |
|
|
|
Net::DownloadHandler::~DownloadHandler() |
|
|
@ -103,8 +105,8 @@ void Net::DownloadHandler::processFinishedDownload() |
|
|
|
if (m_reply->error() != QNetworkReply::NoError) { |
|
|
|
if (m_reply->error() != QNetworkReply::NoError) { |
|
|
|
// Failure
|
|
|
|
// Failure
|
|
|
|
qDebug("Download failure (%s), reason: %s", qUtf8Printable(url), qUtf8Printable(errorCodeToString(m_reply->error()))); |
|
|
|
qDebug("Download failure (%s), reason: %s", qUtf8Printable(url), qUtf8Printable(errorCodeToString(m_reply->error()))); |
|
|
|
emit downloadFailed(m_downloadRequest.url(), errorCodeToString(m_reply->error())); |
|
|
|
setError(errorCodeToString(m_reply->error())); |
|
|
|
this->deleteLater(); |
|
|
|
finish(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -117,49 +119,43 @@ void Net::DownloadHandler::processFinishedDownload() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Success
|
|
|
|
// Success
|
|
|
|
const QByteArray replyData = (m_reply->rawHeader("Content-Encoding") == "gzip") |
|
|
|
m_result.data = (m_reply->rawHeader("Content-Encoding") == "gzip") |
|
|
|
? Utils::Gzip::decompress(m_reply->readAll()) |
|
|
|
? Utils::Gzip::decompress(m_reply->readAll()) |
|
|
|
: m_reply->readAll(); |
|
|
|
: m_reply->readAll(); |
|
|
|
|
|
|
|
|
|
|
|
if (m_downloadRequest.saveToFile()) { |
|
|
|
if (m_downloadRequest.saveToFile()) { |
|
|
|
QString filePath; |
|
|
|
QString filePath; |
|
|
|
if (saveToFile(replyData, filePath)) |
|
|
|
if (saveToFile(m_result.data, filePath)) |
|
|
|
emit downloadFinished(m_downloadRequest.url(), filePath); |
|
|
|
m_result.filePath = filePath; |
|
|
|
else |
|
|
|
else |
|
|
|
emit downloadFailed(m_downloadRequest.url(), tr("I/O Error")); |
|
|
|
setError(tr("I/O Error")); |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
emit downloadFinished(m_downloadRequest.url(), replyData); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this->deleteLater(); |
|
|
|
finish(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Net::DownloadHandler::checkDownloadSize(const qint64 bytesReceived, const qint64 bytesTotal) |
|
|
|
void Net::DownloadHandler::checkDownloadSize(const qint64 bytesReceived, const qint64 bytesTotal) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QString msg = tr("The file size is %1. It exceeds the download limit of %2."); |
|
|
|
if ((bytesTotal > 0) && (bytesTotal <= m_downloadRequest.limit())) { |
|
|
|
|
|
|
|
|
|
|
|
if (bytesTotal > 0) { |
|
|
|
|
|
|
|
// Total number of bytes is available
|
|
|
|
// Total number of bytes is available
|
|
|
|
if (bytesTotal > m_downloadRequest.limit()) { |
|
|
|
disconnect(m_reply, &QNetworkReply::downloadProgress, this, &Net::DownloadHandler::checkDownloadSize); |
|
|
|
m_reply->abort(); |
|
|
|
return; |
|
|
|
emit downloadFailed(m_downloadRequest.url(), msg.arg(Utils::Misc::friendlyUnit(bytesTotal), Utils::Misc::friendlyUnit(m_downloadRequest.limit()))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
disconnect(m_reply, &QNetworkReply::downloadProgress, this, &Net::DownloadHandler::checkDownloadSize); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else if (bytesReceived > m_downloadRequest.limit()) { |
|
|
|
|
|
|
|
|
|
|
|
if ((bytesTotal > m_downloadRequest.limit()) || (bytesReceived > m_downloadRequest.limit())) { |
|
|
|
m_reply->abort(); |
|
|
|
m_reply->abort(); |
|
|
|
emit downloadFailed(m_downloadRequest.url(), msg.arg(Utils::Misc::friendlyUnit(bytesReceived), Utils::Misc::friendlyUnit(m_downloadRequest.limit()))); |
|
|
|
setError(tr("The file size is %1. It exceeds the download limit of %2.") |
|
|
|
|
|
|
|
.arg(Utils::Misc::friendlyUnit(bytesTotal) |
|
|
|
|
|
|
|
, Utils::Misc::friendlyUnit(m_downloadRequest.limit()))); |
|
|
|
|
|
|
|
finish(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Net::DownloadHandler::handleRedirection(const QUrl &newUrl) |
|
|
|
void Net::DownloadHandler::handleRedirection(const QUrl &newUrl) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_redirectionCounter >= MAX_REDIRECTIONS) { |
|
|
|
if (m_redirectionCounter >= MAX_REDIRECTIONS) { |
|
|
|
emit downloadFailed(url(), tr("Exceeded max redirections (%1)").arg(MAX_REDIRECTIONS)); |
|
|
|
setError(tr("Exceeded max redirections (%1)").arg(MAX_REDIRECTIONS)); |
|
|
|
this->deleteLater(); |
|
|
|
finish(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -172,38 +168,35 @@ void Net::DownloadHandler::handleRedirection(const 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(); |
|
|
|
if (m_downloadRequest.handleRedirectToMagnet()) |
|
|
|
m_result.status = DownloadStatus::RedirectedToMagnet; |
|
|
|
emit redirectedToMagnet(m_downloadRequest.url(), newUrlString); |
|
|
|
m_result.magnet = newUrlString; |
|
|
|
else |
|
|
|
|
|
|
|
emit downloadFailed(m_downloadRequest.url(), tr("Unexpected redirect to magnet URI.")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this->deleteLater(); |
|
|
|
finish(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DownloadHandler *redirected = m_manager->download(DownloadRequest(m_downloadRequest).url(newUrlString)); |
|
|
|
DownloadHandler *redirected = m_manager->download(DownloadRequest(m_downloadRequest).url(newUrlString)); |
|
|
|
redirected->m_redirectionCounter = (m_redirectionCounter + 1); |
|
|
|
redirected->m_redirectionCounter = (m_redirectionCounter + 1); |
|
|
|
connect(redirected, &DownloadHandler::destroyed, this, &DownloadHandler::deleteLater); |
|
|
|
connect(redirected, &DownloadHandler::finished, this, [this](const DownloadResult &result) |
|
|
|
connect(redirected, &DownloadHandler::downloadFailed, this, [this](const QString &, const QString &reason) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
emit downloadFailed(url(), reason); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
connect(redirected, &DownloadHandler::redirectedToMagnet, this, [this](const QString &, const QString &magnetUri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
emit redirectedToMagnet(url(), magnetUri); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
connect(redirected, static_cast<void (DownloadHandler::*)(const QString &, const QString &)>(&DownloadHandler::downloadFinished) |
|
|
|
|
|
|
|
, this, [this](const QString &, const QString &fileName) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
emit downloadFinished(url(), fileName); |
|
|
|
m_result = result; |
|
|
|
}); |
|
|
|
m_result.url = url(); |
|
|
|
connect(redirected, static_cast<void (DownloadHandler::*)(const QString &, const QByteArray &)>(&DownloadHandler::downloadFinished) |
|
|
|
finish(); |
|
|
|
, this, [this](const QString &, const QByteArray &data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
emit downloadFinished(url(), data); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Net::DownloadHandler::setError(const QString &error) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_result.errorString = error; |
|
|
|
|
|
|
|
m_result.status = DownloadStatus::Failed; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Net::DownloadHandler::finish() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
emit finished(m_result); |
|
|
|
|
|
|
|
deleteLater(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QString Net::DownloadHandler::errorCodeToString(const QNetworkReply::NetworkError status) |
|
|
|
QString Net::DownloadHandler::errorCodeToString(const QNetworkReply::NetworkError status) |
|
|
|
{ |
|
|
|
{ |
|
|
|
switch (status) { |
|
|
|
switch (status) { |
|
|
|