summaryrefslogtreecommitdiff
path: root/src/downloadmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/downloadmanager.cpp')
-rw-r--r--src/downloadmanager.cpp38
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;