diff options
Diffstat (limited to 'api/logic')
44 files changed, 802 insertions, 740 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt index 2a73566d..1048e091 100644 --- a/api/logic/CMakeLists.txt +++ b/api/logic/CMakeLists.txt @@ -82,21 +82,25 @@ set(PATHMATCHER_SOURCES set(NET_SOURCES # network stuffs + net/ByteArraySink.h + net/ChecksumValidator.h + net/Download.cpp + net/Download.h + net/FileSink.cpp + net/FileSink.h + net/HttpMetaCache.cpp + net/HttpMetaCache.h + net/MetaCacheSink.cpp + net/MetaCacheSink.h net/NetAction.h - net/MD5EtagDownload.h - net/MD5EtagDownload.cpp - net/ByteArrayDownload.h - net/ByteArrayDownload.cpp - net/CacheDownload.h - net/CacheDownload.cpp - net/NetJob.h net/NetJob.cpp - net/HttpMetaCache.h - net/HttpMetaCache.cpp - net/PasteUpload.h + net/NetJob.h net/PasteUpload.cpp - net/URLConstants.h + net/PasteUpload.h + net/Sink.h net/URLConstants.cpp + net/URLConstants.h + net/Validator.h ) # Game launch logic diff --git a/api/logic/minecraft/AssetsUtils.cpp b/api/logic/minecraft/AssetsUtils.cpp index 7a525abe..bb630528 100644 --- a/api/logic/minecraft/AssetsUtils.cpp +++ b/api/logic/minecraft/AssetsUtils.cpp @@ -25,7 +25,9 @@ #include "AssetsUtils.h" #include "FileSystem.h" -#include "net/MD5EtagDownload.h" +#include "net/Download.h" +#include "net/ChecksumValidator.h" + namespace AssetsUtils { @@ -191,7 +193,12 @@ NetActionPtr AssetObject::getDownloadAction() QFileInfo objectFile(getLocalPath()); if ((!objectFile.isFile()) || (objectFile.size() != size)) { - auto objectDL = MD5EtagDownload::make(getUrl(), objectFile.filePath()); + auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath()); + if(hash.size()) + { + auto rawHash = QByteArray::fromHex(hash.toLatin1()); + objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash)); + } objectDL->m_total_progress = size; return objectDL; } diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp index 922db84e..584c7ac5 100644 --- a/api/logic/minecraft/Library.cpp +++ b/api/logic/minecraft/Library.cpp @@ -1,5 +1,6 @@ #include "Library.h" -#include <net/CacheDownload.h> +#include <net/Download.h> +#include <net/ChecksumValidator.h> #include <minecraft/forge/ForgeXzDownload.h> #include <Env.h> #include <FileSystem.h> @@ -74,7 +75,7 @@ QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, Q bool isLocal = (hint() == "local"); bool isForge = (hint() == "forge-pack-xz"); - auto add_download = [&](QString storage, QString dl) + auto add_download = [&](QString storage, QString url, QString sha1 = QString()) { auto entry = cache->resolveEntry("libraries", storage); if (!entry->isStale()) @@ -95,7 +96,16 @@ QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, Q } else { - out.append(CacheDownload::make(dl, entry)); + if(sha1.size()) + { + auto rawSha1 = QByteArray::fromHex(sha1.toLatin1()); + auto dl = Net::Download::makeCached(url, entry); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + out.append(dl); + } + + else + out.append(Net::Download::makeCached(url, entry)); } return true; }; @@ -105,7 +115,7 @@ QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, Q if(m_mojangDownloads->artifact) { auto artifact = m_mojangDownloads->artifact; - add_download(artifact->path, artifact->url); + add_download(artifact->path, artifact->url, artifact->sha1); } if(m_nativeClassifiers.contains(system)) { @@ -118,17 +128,17 @@ QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, Q nat64Classifier.replace("${arch}", "64"); auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier); if(nat32info) - add_download(nat32info->path, nat32info->url); + add_download(nat32info->path, nat32info->url, nat32info->sha1); auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier); if(nat64info) - add_download(nat64info->path, nat64info->url); + add_download(nat64info->path, nat64info->url, nat64info->sha1); } else { auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier); if(info) { - add_download(info->path, info->url); + add_download(info->path, info->url, info->sha1); } } } diff --git a/api/logic/minecraft/MinecraftVersionList.cpp b/api/logic/minecraft/MinecraftVersionList.cpp index a5cc3a39..4e4eafbc 100644 --- a/api/logic/minecraft/MinecraftVersionList.cpp +++ b/api/logic/minecraft/MinecraftVersionList.cpp @@ -68,6 +68,7 @@ slots: protected: NetJobPtr specificVersionDownloadJob; + QByteArray versionIndexData; std::shared_ptr<MinecraftVersion> updatedVersion; MinecraftVersionList *m_list; }; @@ -410,7 +411,7 @@ MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, void MCVListVersionUpdateTask::executeTask() { auto job = new NetJob("Version index"); - job->addNetAction(ByteArrayDownload::make(QUrl(updatedVersion->getUrl()))); + job->addNetAction(Net::Download::makeByteArray(QUrl(updatedVersion->getUrl()), &versionIndexData)); specificVersionDownloadJob.reset(job); connect(specificVersionDownloadJob.get(), SIGNAL(succeeded()), SLOT(json_downloaded())); connect(specificVersionDownloadJob.get(), SIGNAL(failed(QString)), SIGNAL(failed(QString))); @@ -420,12 +421,11 @@ void MCVListVersionUpdateTask::executeTask() void MCVListVersionUpdateTask::json_downloaded() { - NetActionPtr DlJob = specificVersionDownloadJob->first(); - auto data = std::dynamic_pointer_cast<ByteArrayDownload>(DlJob)->m_data; specificVersionDownloadJob.reset(); QJsonParseError jsonError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + QJsonDocument jsonDoc = QJsonDocument::fromJson(versionIndexData, &jsonError); + versionIndexData.clear(); if (jsonError.error != QJsonParseError::NoError) { diff --git a/api/logic/minecraft/forge/ForgeInstaller.cpp b/api/logic/minecraft/forge/ForgeInstaller.cpp index 353328ab..4d004bf5 100644 --- a/api/logic/minecraft/forge/ForgeInstaller.cpp +++ b/api/logic/minecraft/forge/ForgeInstaller.cpp @@ -397,7 +397,7 @@ protected: if (entry->isStale()) { NetJob *fjob = new NetJob("Forge download"); - fjob->addNetAction(CacheDownload::make(forgeVersion->url(), entry)); + fjob->addNetAction(Net::Download::makeCached(forgeVersion->url(), entry)); connect(fjob, &NetJob::progress, this, &Task::setProgress); connect(fjob, &NetJob::status, this, &Task::setStatus); connect(fjob, &NetJob::failed, [this](QString reason) diff --git a/api/logic/minecraft/forge/ForgeVersionList.cpp b/api/logic/minecraft/forge/ForgeVersionList.cpp index de185e5f..fe024780 100644 --- a/api/logic/minecraft/forge/ForgeVersionList.cpp +++ b/api/logic/minecraft/forge/ForgeVersionList.cpp @@ -131,10 +131,8 @@ void ForgeListLoadTask::executeTask() forgeListEntry->setStale(true); gradleForgeListEntry->setStale(true); - job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL), - forgeListEntry)); - job->addNetAction(gradleListDownload = CacheDownload::make( - QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry)); + job->addNetAction(listDownload = Net::Download::makeCached(QUrl(URLConstants::FORGE_LEGACY_URL),forgeListEntry)); + job->addNetAction(gradleListDownload = Net::Download::makeCached(QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry)); connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed())); connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed())); @@ -154,15 +152,14 @@ bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out) { QByteArray data; { - auto dlJob = listDownload; - auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath(); + auto filename = listDownload->getTargetFilepath(); QFile listFile(filename); if (!listFile.open(QIODevice::ReadOnly)) { return false; } data = listFile.readAll(); - dlJob.reset(); + listDownload.reset(); } QJsonParseError jsonError; @@ -266,15 +263,14 @@ bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out) QMap<int, std::shared_ptr<ForgeVersion>> lookup; QByteArray data; { - auto dlJob = gradleListDownload; - auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath(); + auto filename = gradleListDownload->getTargetFilepath(); QFile listFile(filename); if (!listFile.open(QIODevice::ReadOnly)) { return false; } data = listFile.readAll(); - dlJob.reset(); + gradleListDownload.reset(); } QJsonParseError jsonError; diff --git a/api/logic/minecraft/forge/ForgeVersionList.h b/api/logic/minecraft/forge/ForgeVersionList.h index 62c08b2a..7b30bbb4 100644 --- a/api/logic/minecraft/forge/ForgeVersionList.h +++ b/api/logic/minecraft/forge/ForgeVersionList.h @@ -81,8 +81,8 @@ protected: NetJobPtr listJob; ForgeVersionList *m_list; - CacheDownloadPtr listDownload; - CacheDownloadPtr gradleListDownload; + Net::Download::Ptr listDownload; + Net::Download::Ptr gradleListDownload; private: bool parseForgeList(QList<BaseVersionPtr> &out); diff --git a/api/logic/minecraft/legacy/LegacyUpdate.cpp b/api/logic/minecraft/legacy/LegacyUpdate.cpp index 6539b2d3..a0d1933f 100644 --- a/api/logic/minecraft/legacy/LegacyUpdate.cpp +++ b/api/logic/minecraft/legacy/LegacyUpdate.cpp @@ -114,7 +114,7 @@ void LegacyUpdate::fmllibsStart() auto entry = metacache->resolveEntry("fmllibs", lib.filename); QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename; - dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry)); + dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry)); } connect(dljob, &NetJob::succeeded, this, &LegacyUpdate::fmllibsFinished); @@ -372,7 +372,7 @@ void LegacyUpdate::jarStart() auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", URLConstants::getJarPath(version_id)); - dljob->addNetAction(CacheDownload::make(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry)); + dljob->addNetAction(Net::Download::makeCached(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry)); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); connect(dljob, SIGNAL(failed(QString)), SLOT(jarFailed(QString))); connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); diff --git a/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp index b0c9736a..f8bf095f 100644 --- a/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp +++ b/api/logic/minecraft/liteloader/LiteLoaderVersionList.cpp @@ -146,8 +146,7 @@ void LLListLoadTask::executeTask() // verify by poking the server. liteloaderEntry->setStale(true); - job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::LITELOADER_URL), - liteloaderEntry)); + job->addNetAction(listDownload = Net::Download::makeCached(QUrl(URLConstants::LITELOADER_URL), liteloaderEntry)); connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed())); @@ -167,8 +166,7 @@ void LLListLoadTask::listDownloaded() { QByteArray data; { - auto dlJob = listDownload; - auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath(); + auto filename = listDownload->getTargetFilepath(); QFile listFile(filename); if (!listFile.open(QIODevice::ReadOnly)) { @@ -177,7 +175,7 @@ void LLListLoadTask::listDownloaded() } data = listFile.readAll(); listFile.close(); - dlJob.reset(); + listDownload.reset(); } QJsonParseError jsonError; diff --git a/api/logic/minecraft/liteloader/LiteLoaderVersionList.h b/api/logic/minecraft/liteloader/LiteLoaderVersionList.h index 1dba4b6a..ae8bee92 100644 --- a/api/logic/minecraft/liteloader/LiteLoaderVersionList.h +++ b/api/logic/minecraft/liteloader/LiteLoaderVersionList.h @@ -112,7 +112,7 @@ slots: protected: NetJobPtr listJob; - CacheDownloadPtr listDownload; + Net::Download::Ptr listDownload; LiteLoaderVersionList *m_list; }; diff --git a/api/logic/minecraft/onesix/OneSixUpdate.cpp b/api/logic/minecraft/onesix/OneSixUpdate.cpp index 1c2cd196..d3cd197d 100644 --- a/api/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/api/logic/minecraft/onesix/OneSixUpdate.cpp @@ -31,6 +31,7 @@ #include "minecraft/MinecraftProfile.h" #include "minecraft/Library.h" #include "net/URLConstants.h" +#include "net/ChecksumValidator.h" #include "minecraft/AssetsUtils.h" #include "Exception.h" #include "MMCZip.h" @@ -96,7 +97,13 @@ void OneSixUpdate::assetIndexStart() auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); entry->setStale(true); - job->addNetAction(CacheDownload::make(indexUrl, entry)); + auto hexSha1 = assets->sha1.toLatin1(); + qDebug() << "Asset index SHA1:" << hexSha1; + auto dl = Net::Download::makeCached(indexUrl, entry); + auto rawSha1 = QByteArray::fromHex(assets->sha1.toLatin1()); + dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1)); + job->addNetAction(dl); + jarlibDownloadJob.reset(job); connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished())); @@ -180,7 +187,7 @@ void OneSixUpdate::jarlibStart() auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", localPath); - job->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); + job->addNetAction(Net::Download::makeCached(QUrl(urlstr), entry)); jarlibDownloadJob.reset(job); } @@ -293,7 +300,7 @@ void OneSixUpdate::fmllibsStart() auto entry = metacache->resolveEntry("fmllibs", lib.filename); QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename; - dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry)); + dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry)); } connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished())); diff --git a/api/logic/net/ByteArrayDownload.cpp b/api/logic/net/ByteArrayDownload.cpp deleted file mode 100644 index 21990eeb..00000000 --- a/api/logic/net/ByteArrayDownload.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ByteArrayDownload.h" -#include "Env.h" -#include <QDebug> - -ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction() -{ - m_url = url; - m_status = Job_NotStarted; -} - -void ByteArrayDownload::start() -{ - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - auto worker = ENV.qnam(); - QNetworkReply *rep = worker->get(request); - - m_reply.reset(rep); - connect(rep, SIGNAL(downloadProgress(qint64, qint64)), - SLOT(downloadProgress(qint64, qint64))); - connect(rep, SIGNAL(finished()), SLOT(downloadFinished())); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), - SLOT(downloadError(QNetworkReply::NetworkError))); - connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead())); -} - -void ByteArrayDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void ByteArrayDownload::downloadError(QNetworkReply::NetworkError error) -{ - // error happened during download. - qCritical() << "Error getting URL:" << m_url.toString().toLocal8Bit() - << "Network error: " << error; - m_status = Job_Failed; - m_errorString = m_reply->errorString(); -} - -void ByteArrayDownload::downloadFinished() -{ - QVariant redirect = m_reply->header(QNetworkRequest::LocationHeader); - QString redirectURL; - if(redirect.isValid()) - { - redirectURL = redirect.toString(); - } - // FIXME: This is a hack for https://bugreports.qt-project.org/browse/QTBUG-41061 - else if(m_reply->hasRawHeader("Location")) - { - auto data = m_reply->rawHeader("Location"); - if(data.size() > 2 && data[0] == '/' && data[1] == '/') - redirectURL = m_reply->url().scheme() + ":" + data; - } - if (!redirectURL.isEmpty()) - { - m_url = QUrl(redirect.toString()); - qDebug() << "Following redirect to " << m_url.toString(); - start(); - return; - } - - // if the download succeeded - if (m_status != Job_Failed) - { - // nothing went wrong... - m_status = Job_Finished; - m_data = m_reply->readAll(); - m_content_type = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); - m_reply.reset(); - emit succeeded(m_index_within_job); - return; - } - // else the download failed - else - { - m_reply.reset(); - emit failed(m_index_within_job); - return; - } -} - -void ByteArrayDownload::downloadReadyRead() -{ - // ~_~ -} diff --git a/api/logic/net/ByteArrayDownload.h b/api/logic/net/ByteArrayDownload.h deleted file mode 100644 index e2fc2911..00000000 --- a/api/logic/net/ByteArrayDownload.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include "NetAction.h" - -#include "multimc_logic_export.h" - -typedef std::shared_ptr<class ByteArrayDownload> ByteArrayDownloadPtr; -class MULTIMC_LOGIC_EXPORT ByteArrayDownload : public NetAction -{ - Q_OBJECT -public: - ByteArrayDownload(QUrl url); - static ByteArrayDownloadPtr make(QUrl url) - { - return ByteArrayDownloadPtr(new ByteArrayDownload(url)); - } - virtual ~ByteArrayDownload() {}; -public: - /// if not saving to file, downloaded data is placed here - QByteArray m_data; - - QString m_errorString; - -public -slots: - virtual void start(); - -protected -slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void downloadError(QNetworkReply::NetworkError error); - void downloadFinished(); - void downloadReadyRead(); -}; diff --git a/api/logic/net/ByteArraySink.h b/api/logic/net/ByteArraySink.h new file mode 100644 index 00000000..3deef1ed --- /dev/null +++ b/api/logic/net/ByteArraySink.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Sink.h" + +namespace Net { +/* + * Sink object for downloads that uses an external QByteArray it doesn't own as a target. + */ +class ByteArraySink : public Sink +{ +public: + ByteArraySink(QByteArray *output) + :m_output(output) + { + // nil + }; + + virtual ~ByteArraySink() + { + // nil + } + +public: + JobStatus init(QNetworkRequest & request) override + { + m_output->clear(); + if(initAllValidators(request)) + return Job_InProgress; + return Job_Failed; + }; + + JobStatus write(QByteArray & data) override + { + m_output->append(data); + if(writeAllValidators(data)) + return Job_InProgress; + return Job_Failed; + } + + JobStatus abort() override + { + m_output->clear(); + failAllValidators(); + return Job_Failed; + } + + JobStatus finalize(QNetworkReply &reply) override + { + if(finalizeAllValidators(reply)) + return Job_Finished; + return Job_Failed; + } + +private: + QByteArray * m_output; +}; +} diff --git a/api/logic/net/CacheDownload.cpp b/api/logic/net/CacheDownload.cpp deleted file mode 100644 index 1ac55180..00000000 --- a/api/logic/net/CacheDownload.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "CacheDownload.h" - -#include <QCryptographicHash> -#include <QFileInfo> -#include <QDateTime> -#include <QDebug> -#include "Env.h" -#include <FileSystem.h> - -CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry) - : NetAction(), md5sum(QCryptographicHash::Md5) -{ - m_url = url; - m_entry = entry; - m_target_path = entry->getFullPath(); - m_status = Job_NotStarted; -} - -void CacheDownload::start() -{ - m_status = Job_InProgress; - if (!m_entry->isStale()) - { - m_status = Job_Finished; - emit succeeded(m_index_within_job); - return; - } - // create a new save file - m_output_file.reset(new QSaveFile(m_target_path)); - - // if there already is a file and md5 checking is in effect and it can be opened - if (!FS::ensureFilePathExists(m_target_path)) - { - qCritical() << "Could not create folder for " + m_target_path; - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } - if (!m_output_file->open(QIODevice::WriteOnly)) - { - qCritical() << "Could not open " + m_target_path + " for writing"; - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - - // check file consistency first. - QFile current(m_target_path); - if(current.exists() && current.size() != 0) - { - if (m_entry->getRemoteChangedTimestamp().size()) - request.setRawHeader(QString("If-Modified-Since").toLatin1(), - m_entry->getRemoteChangedTimestamp().toLatin1()); - if (m_entry->getETag().size()) - request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1()); - } - - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); - - auto worker = ENV.qnam(); - QNetworkReply *rep = worker->get(request); - |
