diff options
Diffstat (limited to 'src/downloadmanager.cpp')
| -rw-r--r-- | src/downloadmanager.cpp | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 6fb88c3b..5ccbdb4d 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -435,6 +435,23 @@ bool DownloadManager::addDownload(const QStringList& URLs, QString gameName, int QString fileName = QFileInfo(URLs.first()).fileName(); if (fileName.isEmpty()) { fileName = "unknown"; + } else { + fileName = QUrl::fromPercentEncoding(fileName.toUtf8()); + } + + // Temporary URLs for S3-compatible storage are signed for a single method, removing + // the ability to make HEAD requests to such URLs. We can use the + // response-content-disposition GET parameter, setting the Content-Disposition header, + // to predetermine intended file name without a subrequest. + if (fileName.contains("response-content-disposition=")) { + std::regex exp("filename=\"(.+)\""); + std::cmatch result; + if (std::regex_search(fileName.toStdString().c_str(), result, exp)) { + fileName = MOBase::sanitizeFileName(QString::fromUtf8(result.str(1).c_str())); + if (fileName.isEmpty()) { + fileName = "unknown"; + } + } } QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit()); @@ -446,6 +463,9 @@ bool DownloadManager::addDownload(const QStringList& URLs, QString gameName, int QNetworkRequest request(preferredUrl); request.setHeader(QNetworkRequest::UserAgentHeader, m_NexusInterface->getAccessManager()->userAgent()); + request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, + QNetworkRequest::AlwaysNetwork); request.setHttp2Configuration(h2Conf); return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, gameName, modID, fileID, fileInfo); @@ -597,7 +617,10 @@ void DownloadManager::startDownload(QNetworkReply* reply, DownloadInfo* newDownl if (newDownload->m_State != STATE_DOWNLOADING && newDownload->m_State != STATE_READY && newDownload->m_State != STATE_FETCHINGMODINFO && reply->isFinished()) { - downloadFinished(indexByInfo(newDownload)); + int index = indexByInfo(newDownload); + if (index >= 0) { + downloadFinished(index); + } return; } } else @@ -945,8 +968,7 @@ void DownloadManager::resumeDownloadInt(int index) // Check for finished download; if (info->m_TotalSize <= info->m_Output.size() && info->m_Reply != nullptr && - info->m_Reply->isOpen() && info->m_Reply->isFinished() && - info->m_State != STATE_ERROR) { + info->m_Reply->isFinished() && info->m_State != STATE_ERROR) { setState(info, STATE_DOWNLOADING); downloadFinished(index); return; @@ -1508,7 +1530,7 @@ QString DownloadManager::getDownloadFileName(const QString& baseName, bool renam QString DownloadManager::getFileNameFromNetworkReply(QNetworkReply* reply) { if (reply->hasRawHeader("Content-Disposition")) { - std::regex exp("filename=\"(.*)\""); + std::regex exp("filename=\"(.+)\""); std::cmatch result; if (std::regex_search(reply->rawHeader("Content-Disposition").constData(), result, @@ -2142,10 +2164,14 @@ void DownloadManager::nxmRequestFailed(QString gameName, int modID, int fileID, void DownloadManager::downloadFinished(int index) { DownloadInfo* info; - if (index) + if (index > 0) info = m_ActiveDownloads[index]; - else + else { info = findDownload(this->sender(), &index); + if (info == nullptr && index == 0) { + info = m_ActiveDownloads[index]; + } + } if (info != nullptr) { QNetworkReply* reply = info->m_Reply; |
