diff options
| author | Petr Mrázek <peterix@gmail.com> | 2016-04-10 15:53:05 +0200 |
|---|---|---|
| committer | Petr Mrázek <peterix@gmail.com> | 2016-05-01 00:00:14 +0200 |
| commit | b6d455a02bd338e9dc0faa09d4d8177ecd8d569a (patch) | |
| tree | 41982bca1ede50049f2f8c7109dd18edeefde6d0 /libraries/logic/net | |
| parent | 47e37635f50c09b4f9a9ee7699e3120bab3e4088 (diff) | |
| download | PrismLauncher-b6d455a02bd338e9dc0faa09d4d8177ecd8d569a.tar.gz PrismLauncher-b6d455a02bd338e9dc0faa09d4d8177ecd8d569a.tar.bz2 PrismLauncher-b6d455a02bd338e9dc0faa09d4d8177ecd8d569a.zip | |
NOISSUE reorganize and document libraries
Diffstat (limited to 'libraries/logic/net')
| -rw-r--r-- | libraries/logic/net/ByteArrayDownload.cpp | 105 | ||||
| -rw-r--r-- | libraries/logic/net/ByteArrayDownload.h | 48 | ||||
| -rw-r--r-- | libraries/logic/net/CacheDownload.cpp | 192 | ||||
| -rw-r--r-- | libraries/logic/net/CacheDownload.h | 63 | ||||
| -rw-r--r-- | libraries/logic/net/HttpMetaCache.cpp | 273 | ||||
| -rw-r--r-- | libraries/logic/net/HttpMetaCache.h | 125 | ||||
| -rw-r--r-- | libraries/logic/net/MD5EtagDownload.cpp | 155 | ||||
| -rw-r--r-- | libraries/logic/net/MD5EtagDownload.h | 52 | ||||
| -rw-r--r-- | libraries/logic/net/NetAction.h | 96 | ||||
| -rw-r--r-- | libraries/logic/net/NetJob.cpp | 125 | ||||
| -rw-r--r-- | libraries/logic/net/NetJob.h | 117 | ||||
| -rw-r--r-- | libraries/logic/net/PasteUpload.cpp | 99 | ||||
| -rw-r--r-- | libraries/logic/net/PasteUpload.h | 50 | ||||
| -rw-r--r-- | libraries/logic/net/URLConstants.cpp | 16 | ||||
| -rw-r--r-- | libraries/logic/net/URLConstants.h | 40 |
15 files changed, 0 insertions, 1556 deletions
diff --git a/libraries/logic/net/ByteArrayDownload.cpp b/libraries/logic/net/ByteArrayDownload.cpp deleted file mode 100644 index 21990eeb..00000000 --- a/libraries/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/libraries/logic/net/ByteArrayDownload.h b/libraries/logic/net/ByteArrayDownload.h deleted file mode 100644 index e2fc2911..00000000 --- a/libraries/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/libraries/logic/net/CacheDownload.cpp b/libraries/logic/net/CacheDownload.cpp deleted file mode 100644 index 1ac55180..00000000 --- a/libraries/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); - - 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 CacheDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void CacheDownload::downloadError(QNetworkReply::NetworkError error) -{ - // error happened during download. - qCritical() << "Failed " << m_url.toString() << " with reason " << error; - m_status = Job_Failed; -} -void CacheDownload::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) - { - m_output_file->cancelWriting(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } - - // if we wrote any data to the save file, we try to commit the data to the real file. - if (wroteAnyData) - { - // nothing went wrong... - if (m_output_file->commit()) - { - m_status = Job_Finished; - m_entry->setMD5Sum(md5sum.result().toHex().constData()); - } - else - { - qCritical() << "Failed to commit changes to " << m_target_path; - m_output_file->cancelWriting(); - m_reply.reset(); - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } - } - else - { - m_status = Job_Finished; - } - - // then get rid of the save file - m_output_file.reset(); - - QFileInfo output_file_info(m_target_path); - - m_entry->setETag(m_reply->rawHeader("ETag").constData()); - if (m_reply->hasRawHeader("Last-Modified")) - { - m_entry->setRemoteChangedTimestamp(m_reply->rawHeader("Last-Modified").constData()); - } - m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); - m_entry->setStale(false); - ENV.metacache()->updateEntry(m_entry); - - m_reply.reset(); - emit succeeded(m_index_within_job); - return; -} - -void CacheDownload::downloadReadyRead() -{ - QByteArray ba = m_reply->readAll(); - md5sum.addData(ba); - if (m_output_file->write(ba) != ba.size()) - { - qCritical() << "Failed writing into " + m_target_path; - m_status = Job_Failed; - m_output_file->cancelWriting(); - m_output_file.reset(); - emit failed(m_index_within_job); - wroteAnyData = false; - return; - } - wroteAnyData = true; -} diff --git a/libraries/logic/net/CacheDownload.h b/libraries/logic/net/CacheDownload.h deleted file mode 100644 index d83b2a0f..00000000 --- a/libraries/logic/net/CacheDownload.h +++ /dev/null @@ -1,63 +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 "HttpMetaCache.h" -#include <QCryptographicHash> -#include <QSaveFile> - -#include "multimc_logic_export.h" - -typedef std::shared_ptr<class CacheDownload> CacheDownloadPtr; -class MULTIMC_LOGIC_EXPORT CacheDownload : public NetAction -{ - Q_OBJECT -private: - MetaEntryPtr m_entry; - /// if saving to file, use the one specified in this string - QString m_target_path; - - /// this is the output file, if any - std::unique_ptr<QSaveFile> m_output_file; - - /// the hash-as-you-download - QCryptographicHash md5sum; - - bool wroteAnyData = false; - -public: - explicit CacheDownload(QUrl url, MetaEntryPtr entry); - static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry) - { - return CacheDownloadPtr(new CacheDownload(url, entry)); - } - virtual ~CacheDownload(){}; - QString getTargetFilepath() - { - return m_target_path; - } -protected -slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead(); - -public -slots: - virtual void start(); -}; diff --git a/libraries/logic/net/HttpMetaCache.cpp b/libraries/logic/net/HttpMetaCache.cpp deleted file mode 100644 index ea3e2834..00000000 --- a/libraries/logic/net/HttpMetaCache.cpp +++ /dev/null @@ -1,273 +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 "Env.h" -#include "HttpMetaCache.h" -#include "FileSystem.h" - -#include <QFileInfo> -#include <QFile> -#include <QDateTime> -#include <QCryptographicHash> - -#include <QDebug> - -#include <QJsonDocument> -#include <QJsonArray> -#include <QJsonObject> - -QString MetaEntry::getFullPath() -{ - // FIXME: make local? - return FS::PathCombine(basePath, relativePath); -} - -HttpMetaCache::HttpMetaCache(QString path) : QObject() -{ - m_index_file = path; - saveBatchingTimer.setSingleShot(true); - saveBatchingTimer.setTimerType(Qt::VeryCoarseTimer); - connect(&saveBatchingTimer, SIGNAL(timeout()), SLOT(SaveNow())); -} - -HttpMetaCache::~HttpMetaCache() -{ - saveBatchingTimer.stop(); - SaveNow(); -} - -MetaEntryPtr HttpMetaCache::getEntry(QString base, QString resource_path) -{ - // no base. no base path. can't store - if (!m_entries.contains(base)) - { - // TODO: log problem - return MetaEntryPtr(); - } - EntryMap &map = m_entries[base]; - if (map.entry_list.contains(resource_path)) - { - return map.entry_list[resource_path]; - } - return MetaEntryPtr(); -} - -MetaEntryPtr HttpMetaCache::resolveEntry(QString base, QString resource_path, QString expected_etag) -{ - auto entry = getEntry(base, resource_path); - // it's not present? generate a default stale entry - if (!entry) - { - return staleEntry(base, resource_path); - } - - auto &selected_base = m_entries[base]; - QString real_path = FS::PathCombine(selected_base.base_path, resource_path); - QFileInfo finfo(real_path); - - // is the file really there? if not -> stale - if (!finfo.isFile() || !finfo.isReadable()) - { - // if the file doesn't exist, we disown the entry - selected_base.entry_list.remove(resource_path); - return staleEntry(base, resource_path); - } - - if (!expected_etag.isEmpty() && expected_etag != entry->etag) - { - // if the etag doesn't match expected, we disown the entry - selected_base.entry_list.remove(resource_path); - return staleEntry(base, resource_path); - } - - // if the file changed, check md5sum - qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch(); - if (file_last_changed != entry->local_changed_timestamp) - { - QFile input(real_path); - input.open(QIODevice::ReadOnly); - QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5) - .toHex() - .constData(); - if (entry->md5sum != md5sum) - { - selected_base.entry_list.remove(resource_path); - return staleEntry(base, resource_path); - } - // md5sums matched... keep entry and save the new state to file - entry->local_changed_timestamp = file_last_changed; - SaveEventually(); - } - - // entry passed all the checks we cared about. - entry->basePath = getBasePath(base); - return entry; -} - -bool HttpMetaCache::updateEntry(MetaEntryPtr stale_entry) -{ - if (!m_entries.contains(stale_entry->baseId)) - { - qCritical() << "Cannot add entry with unknown base: " - << stale_entry->baseId.toLocal8Bit(); - return false; - } - if (stale_entry->stale) - { - qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit(); - return false; - } - m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry; - SaveEventually(); - return true; -} - -bool HttpMetaCache::evictEntry(MetaEntryPtr entry) -{ - if(entry) - { - entry->stale = true; - SaveEventually(); - return true; - } - return false; -} - -MetaEntryPtr HttpMetaCache::staleEntry(QString base, QString resource_path) -{ - auto foo = new MetaEntry(); - foo->baseId = base; - foo->basePath = getBasePath(base); - foo->relativePath = resource_path; - foo->stale = true; - return MetaEntryPtr(foo); -} - -void HttpMetaCache::addBase(QString base, QString base_root) -{ - // TODO: report error - if (m_entries.contains(base)) - return; - // TODO: check if the base path is valid - EntryMap foo; - foo.base_path = base_root; - m_entries[base] = foo; -} - -QString HttpMetaCache::getBasePath(QString base) -{ - if (m_entries.contains(base)) - { - return m_entries[base].base_path; - } - return QString(); -} - -void HttpMetaCache::Load() -{ - if(m_index_file.isNull()) - return; - - QFile index(m_index_file); - if (!index.open(QIODevice::ReadOnly)) - return; - - QJsonDocument json = QJsonDocument::fromJson(index.readAll()); - if (!json.isObject()) - return; - auto root = json.object(); - // check file version first - auto version_val = root.value("version"); - if (!version_val.isString()) - return; - if (version_val.toString() != "1") - return; - - // read the entry array - auto entries_val = root.value("entries"); - if (!entries_val.isArray()) - return; - QJsonArray array = entries_val.toArray(); - for (auto element : array) - { - if (!element.isObject()) - return; - auto element_obj = element.toObject(); - QString base = element_obj.value("base").toString(); - if (!m_entries.contains(base)) - continue; - auto &entrymap = m_entries[base]; - auto foo = new MetaEntry(); - foo->baseId = base; - QString path = foo->relativePath = element_obj.value("path").toString(); - foo->md5sum = element_obj.value("md5sum").toString(); - foo->etag = element_obj.value("etag").toString(); - foo->local_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble(); - foo->remote_changed_timestamp = - element_obj.value("remote_changed_timestamp").toString(); - // presumed innocent until closer examination - foo->stale = false; - entrymap.entry_list[path] = MetaEntryPtr(foo); - } -} - -void HttpMetaCache::SaveEventually() -{ - // reset the save timer - saveBatchingTimer.stop(); - saveBatchingTimer.start(30000); -} - -void HttpMetaCache::SaveNow() -{ - if(m_index_file.isNull()) - return; - QJsonObject toplevel; - toplevel.insert("version", QJsonValue(QString("1"))); - QJsonArray entriesArr; - for (auto group : m_entries) - { - for (auto entry : group.entry_list) - { - // do not save stale entries. they are dead. - if(entry->stale) - { - continue; - } - QJsonObject entryObj; - entryObj.insert("base", QJsonValue(entry->baseId)); - entryObj.insert("path", QJsonValue(entry->relativePath)); - entryObj.insert("md5sum", QJsonValue(entry->md5sum)); - entryObj.insert("etag", QJsonValue(entry->etag)); - entryObj.insert("last_changed_timestamp", - QJsonValue(double(entry->local_changed_timestamp))); - if (!entry->remote_changed_timestamp.isEmpty()) - entryObj.insert("remote_changed_timestamp", - QJsonValue(entry->remote_changed_timestamp)); - entriesArr.append(entryObj); - } - } - toplevel.insert("entries", entriesArr); - - QJsonDocument doc(toplevel); - try - { - FS::write(m_index_file, doc.toJson()); - } - catch (Exception & e) - { - qWarning() << e.what(); - } -} diff --git a/libraries/logic/net/HttpMetaCache.h b/libraries/logic/net/HttpMetaCache.h deleted file mode 100644 index 7b626c70..00000000 --- a/libraries/logic/net/HttpMetaCache.h +++ /dev/null @@ -1,125 +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 <QString> -#include <QMap> -#include <qtimer.h> -#include <memory> - -#include "multimc_logic_export.h" - -class HttpMetaCache; - -class MULTIMC_LOGIC_EXPORT MetaEntry -{ -friend class HttpMetaCache; -protected: - MetaEntry() {} -public: - bool isStale() - { - return stale; - } - void setStale(bool stale) - { - this->stale = stale; - } - QString getFullPath(); - QString getRemoteChangedTimestamp() - { - return remote_changed_timestamp; - } - void setRemoteChangedTimestamp(QString remote_changed_timestamp) - { - this->remote_changed_timestamp = remote_changed_timestamp; - } - void setLocalChangedTimestamp(qint64 timestamp) - { - local_changed_timestamp = timestamp; - } - QString getETag() - { - return etag; - } - void setETag(QString etag) - { - this->etag = etag; - } - QString getMD5Sum() - { - return md5sum; - } - void setMD5Sum(QString md5sum) - { - this->md5sum = md5sum; - } -protected: - QString baseId; - QString basePath; - QString relativePath; - QString md5sum; - QString etag; - qint64 local_changed_timestamp = 0; - QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time - bool stale = true; -}; - -typedef std::shared_ptr<MetaEntry> MetaEntryPtr; - -class MULTIMC_LOGIC_EXPORT HttpMetaCache : public QObject -{ - Q_OBJECT -public: - // supply path to the cache index file - HttpMetaCache(QString path = QString()); - ~HttpMetaCache(); - - // get the entry solely from the cache - // you probably don't want this, unless you have some specific caching needs. - MetaEntryPtr getEntry(QString base, QString resource_path); - - // get the entry from cache and verify that it isn't stale (within reason) - MetaEntryPtr resolveEntry(QString base, QString resource_path, - QString expected_etag = QString()); - - // add a previously resolved stale entry - bool updateEntry(MetaEntryPtr stale_entry); - - // evict selected entry from cache - bool evictEntry(MetaEntryPtr entry); - - void addBase(QString base, QString base_root); - - // (re)start a timer that calls SaveNow later. - void SaveEventually(); - void Load(); - QString getBasePath(QString base); -public -slots: - void SaveNow(); - -private: - // create a new stale entry, given the parameters - MetaEntryPtr staleEntry(QString base, QString resource_path); - struct EntryMap - { - QString base_path; - QMap<QString, MetaEntryPtr> entry_list; - }; - QMap<QString, EntryMap> m_entries; - QString m_index_file; - QTimer saveBatchingTimer; -}; diff --git a/libraries/logic/net/MD5EtagDownload.cpp b/libraries/logic/net/MD5EtagDownload.cpp deleted file mode 100644 index 3b4d5dcd..00000000 --- a/libraries/logic/net/MD5EtagDownload.cpp +++ /dev/null @@ -1,155 +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 "Env.h" -#include "MD5EtagDownload.h" -#include <FileSystem.h> -#include <QCryptographicHash> -#include <QDebug> - -MD5EtagDownload::MD5EtagDownload(QUrl url, QString target_path) : NetAction() -{ - m_url = url; - m_target_path = target_path; - m_status = Job_NotStarted; -} - -void MD5EtagDownload::start() -{ - QString filename = m_target_path; - m_output_file.setFileName(filename); - // if there already is a file and md5 checking is in effect and it can be opened - if (m_output_file.exists() && m_output_file.open(QIODevice::ReadOnly)) - { - // get the md5 of the local file. - m_local_md5 = - QCryptographicHash::hash(m_output_file.readAll(), QCryptographicHash::Md5) - .toHex() - .constData(); - m_output_file.close(); - // if we are expecting some md5sum, compare it with the local one - if (!m_expected_md5.isEmpty()) - { - // skip if they match - if(m_local_md5 == m_expected_md5) - { - qDebug() << "Skipping " << m_url.toString() << ": md5 match."; - emit succeeded(m_index_within_job); - return; - } - } - else - { - // no expected md5. we use the local md5sum as an ETag - } - } - if (!FS::ensureFilePathExists(filename)) - { - emit failed(m_index_within_job); - return; - } - - QNetworkRequest request(m_url); - - qDebug() << "Downloading " << m_url.toString() << " local MD5: " << m_local_md5; - - if(!m_local_md5.isEmpty()) - { - request.setRawHeader(QString("If-None-Match").toLatin1(), m_local_md5.toLatin1()); - } - if(!m_expected_md5.isEmpty()) - qDebug() << "Expecting " << m_expected_md5; - - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - - // Go ahead and try to open the file. - // If we don't do this, empty files won't be created, which breaks the updater. - // Plus, this way, we don't end up starting a download for a file we can't open. - if (!m_output_file.open(QIODevice::WriteOnly)) - { - emit failed(m_index_within_job); - return; - } - - 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 MD5EtagDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void MD5EtagDownload::downloadError(QNetworkReply::NetworkError error) -{ - qCritical() << "Error" << error << ":" << m_reply->errorString() << "while downloading" - << m_reply->url(); - m_status = Job_Failed; -} - -void MD5EtagDownload::downloadFinished() -{ - // if the download succeeded - if (m_status != Job_Failed) - { - // nothing went wrong... - m_status = Job_Finished; - m_output_file.close(); - - // FIXME: compare with the real written data md5sum - // this is just an ETag - qDebug() << "Finished " << m_url.toString() << " got " << m_reply->rawHeader("ETag").constData(); - - m_reply.reset(); - emit succeeded(m_index_within_job); - return; - } - // else the download failed - else - { - m_output_file.close(); - m_output_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } -} - -void MD5EtagDownload::downloadReadyRead() -{ - if (!m_output_file.isOpen()) - { - if (!m_output_file.open(QIODevice::WriteOnly)) - { - /* - * Can't open the file... the job failed - */ - m_reply->abort(); - emit failed(m_index_within_job); - return; - } - } - m_output_file.write(m_reply->readAll()); -} diff --git a/libraries/logic/net/MD5EtagDownload.h b/libraries/logic/net/MD5EtagDownload.h deleted file mode 100644 index cd1cb550..00000000 --- a/libraries/logic/net/MD5EtagDownload.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contr |
