feat(net): ApiUpload ^& fix unfired finished signals

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2023-06-25 12:02:46 -07:00
parent 3105f314cb
commit c8ff812ab8
No known key found for this signature in database
GPG Key ID: E10E321EB160949B
8 changed files with 330 additions and 227 deletions

View File

@ -1,6 +1,7 @@
#include "FileResolvingTask.h" #include "FileResolvingTask.h"
#include "Json.h" #include "Json.h"
#include "net/ApiUpload.h"
#include "net/Upload.h" #include "net/Upload.h"
#include "net/ApiDownload.h" #include "net/ApiDownload.h"
@ -34,7 +35,7 @@ void Flame::FileResolvingTask::executeTask()
return l; return l;
})); }));
QByteArray data = Json::toText(object); QByteArray data = Json::toText(object);
auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result.get(), data); auto dl = Net::ApiUpload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result.get(), data);
m_dljob->addNetAction(dl); m_dljob->addNetAction(dl);
auto step_progress = std::make_shared<TaskStepProgress>(); auto step_progress = std::make_shared<TaskStepProgress>();

View File

@ -8,6 +8,7 @@
#include "Application.h" #include "Application.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "Json.h" #include "Json.h"
#include "net/ApiUpload.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include "net/ApiDownload.h" #include "net/ApiDownload.h"
#include "net/Upload.h" #include "net/Upload.h"
@ -27,7 +28,7 @@ Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, QByteArra
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw)); netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
@ -176,7 +177,7 @@ Task::Ptr FlameAPI::getProjects(QStringList addonIds, QByteArray* response) cons
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw)); netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });
@ -199,7 +200,7 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) c
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw)); netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });

View File

@ -6,9 +6,10 @@
#include "Application.h" #include "Application.h"
#include "Json.h" #include "Json.h"
#include "net/ApiDownload.h"
#include "net/ApiUpload.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include "net/Upload.h" #include "net/Upload.h"
#include "net/ApiDownload.h"
Task::Ptr ModrinthAPI::currentVersion(QString hash, QString hash_format, QByteArray* response) Task::Ptr ModrinthAPI::currentVersion(QString hash, QString hash_format, QByteArray* response)
{ {
@ -34,7 +35,7 @@ Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_f
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), response, body_raw)); netJob->addNetAction(Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
@ -65,7 +66,7 @@ Task::Ptr ModrinthAPI::latestVersion(QString hash,
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray( netJob->addNetAction(Net::ApiUpload::makeByteArray(
QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hash_format), response, body_raw)); QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hash_format), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
@ -100,7 +101,8 @@ Task::Ptr ModrinthAPI::latestVersions(const QStringList& hashes,
QJsonDocument body(body_obj); QJsonDocument body(body_obj);
auto body_raw = body.toJson(); auto body_raw = body.toJson();
netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), response, body_raw)); netJob->addNetAction(
Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), response, body_raw));
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
@ -114,9 +116,7 @@ Task::Ptr ModrinthAPI::getProjects(QStringList addonIds, QByteArray* response) c
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(searchUrl), response)); netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(searchUrl), response));
QObject::connect(netJob.get(), &NetJob::finished, [response, netJob] { QObject::connect(netJob.get(), &NetJob::finished, [response, netJob] { delete response; });
delete response;
});
return netJob; return netJob;
} }

View File

@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "net/ApiUpload.h"
#include "ByteArraySink.h"
#include "ChecksumValidator.h"
#include "MetaCacheSink.h"
#include "net/NetAction.h"
namespace Net {
Upload::Ptr ApiUpload::makeByteArray(QUrl url, QByteArray* output, QByteArray m_post_data)
{
auto up = makeShared<ApiUpload>();
up->m_url = std::move(url);
up->m_sink.reset(new ByteArraySink(output));
up->m_post_data = std::move(m_post_data);
return up;
}
void ApiUpload::init()
{
qDebug() << "Setting up api upload";
auto api_headers = new ApiHeaderProxy();
addHeaderProxy(api_headers);
}
} // namespace Net

36
launcher/net/ApiUpload.h Normal file
View File

@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "ApiHeaderProxy.h"
#include "Upload.h"
namespace Net {
class ApiUpload : public Upload {
public:
virtual ~ApiUpload() = default;
static Upload::Ptr makeByteArray(QUrl url, QByteArray* output, QByteArray m_post_data);
void init() override;
};
} // namespace Net

View File

@ -46,7 +46,10 @@
#include "ChecksumValidator.h" #include "ChecksumValidator.h"
#include "MetaCacheSink.h" #include "MetaCacheSink.h"
#if defined(LAUNCHER_APPLICATION)
#include "Application.h" #include "Application.h"
#endif
#include "BuildConfig.h" #include "BuildConfig.h"
#include "net/Logging.h" #include "net/Logging.h"
@ -57,6 +60,7 @@
namespace Net { namespace Net {
#if defined(LAUNCHER_APPLICATION)
auto Download::makeCached(QUrl url, MetaEntryPtr entry, Options options) -> Download::Ptr auto Download::makeCached(QUrl url, MetaEntryPtr entry, Options options) -> Download::Ptr
{ {
auto dl = makeShared<Download>(); auto dl = makeShared<Download>();
@ -68,6 +72,7 @@ auto Download::makeCached(QUrl url, MetaEntryPtr entry, Options options) -> Down
dl->m_sink.reset(cachedNode); dl->m_sink.reset(cachedNode);
return dl; return dl;
} }
#endif
auto Download::makeByteArray(QUrl url, QByteArray* output, Options options) -> Download::Ptr auto Download::makeByteArray(QUrl url, QByteArray* output, Options options) -> Download::Ptr
{ {
@ -110,8 +115,8 @@ void Download::executeTask()
m_state = m_sink->init(request); m_state = m_sink->init(request);
switch (m_state) { switch (m_state) {
case State::Succeeded: case State::Succeeded:
emit succeeded();
qCDebug(taskDownloadLogC) << getUid().toString() << "Download cache hit " << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download cache hit " << m_url.toString();
emitSucceeded();
return; return;
case State::Running: case State::Running:
qCDebug(taskDownloadLogC) << getUid().toString() << "Downloading " << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Downloading " << m_url.toString();
@ -125,7 +130,13 @@ void Download::executeTask()
return; return;
} }
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); #if defined (LAUNCHER_APPLICATION)
auto user_agent = APPLICATION->getUserAgent();
#else
auto user_agent = BuildConfig.USER_AGENT;
#endif
request.setHeader(QNetworkRequest::UserAgentHeader, user_agent.toUtf8());
for ( auto& header_proxy : m_headerProxies ) { for ( auto& header_proxy : m_headerProxies ) {
header_proxy->writeHeaders(request); header_proxy->writeHeaders(request);
@ -162,7 +173,7 @@ void Download::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed); auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
auto bytes_received_since = bytesReceived - m_last_progress_bytes; auto bytes_received_since = bytesReceived - m_last_progress_bytes;
auto dl_speed_bps = (double)bytes_received_since / elapsed_ms.count() * 1000; auto dl_speed_bps = (double)bytes_received_since / elapsed_ms.count() * 1000;
auto remaing_time_s = (bytesTotal - bytesReceived) / dl_speed_bps; auto remaining_time_s = (bytesTotal - bytesReceived) / dl_speed_bps;
//: Current amount of bytes downloaded, out of the total amount of bytes in the download //: Current amount of bytes downloaded, out of the total amount of bytes in the download
QString dl_progress = QString dl_progress =
@ -170,7 +181,7 @@ void Download::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
QString dl_speed_str; QString dl_speed_str;
if (elapsed_ms.count() > 0) { if (elapsed_ms.count() > 0) {
auto str_eta = bytesTotal > 0 ? Time::humanReadableDuration(remaing_time_s) : tr("unknown"); auto str_eta = bytesTotal > 0 ? Time::humanReadableDuration(remaining_time_s) : tr("unknown");
//: Download speed, in bytes per second (remaining download time in parenthesis) //: Download speed, in bytes per second (remaining download time in parenthesis)
dl_speed_str = dl_speed_str =
tr("%1 /s (%2)").arg(StringUtils::humanReadableFileSize(dl_speed_bps)).arg(str_eta); tr("%1 /s (%2)").arg(StringUtils::humanReadableFileSize(dl_speed_bps)).arg(str_eta);
@ -282,19 +293,19 @@ void Download::downloadFinished()
qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed but we are allowed to proceed:" << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed but we are allowed to proceed:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit succeeded(); emitSucceeded();
return; return;
} else if (m_state == State::Failed) { } else if (m_state == State::Failed) {
qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed in previous step:" << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed in previous step:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit failed(""); emitFailed("");
return; return;
} else if (m_state == State::AbortedByUser) { } else if (m_state == State::AbortedByUser) {
qCDebug(taskDownloadLogC) << getUid().toString() << "Download aborted in previous step:" << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download aborted in previous step:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit aborted(); emitAborted();
return; return;
} }
@ -311,13 +322,13 @@ void Download::downloadFinished()
qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed to finalize:" << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download failed to finalize:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit failed(""); emitFailed("");
return; return;
} }
m_reply.reset(); m_reply.reset();
qCDebug(taskDownloadLogC) << getUid().toString() << "Download succeeded:" << m_url.toString(); qCDebug(taskDownloadLogC) << getUid().toString() << "Download succeeded:" << m_url.toString();
emit succeeded(); emitSucceeded();
} }
void Download::downloadReadyRead() void Download::downloadReadyRead()

View File

@ -39,29 +39,34 @@
#include "Upload.h" #include "Upload.h"
#include <utility> #include <utility>
#include "ByteArraySink.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "ByteArraySink.h"
#if defined(LAUNCHER_APPLICATION)
#include "Application.h" #include "Application.h"
#endif
#include "net/Logging.h" #include "net/Logging.h"
namespace Net { namespace Net {
bool Upload::abort() bool Upload::abort()
{ {
if (m_reply) { if (m_reply) {
m_reply->abort(); m_reply->abort();
} else { } else {
m_state = State::AbortedByUser; m_state = State::AbortedByUser;
} }
return true; return true;
} }
void Upload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { void Upload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
setProgress(bytesReceived, bytesTotal); setProgress(bytesReceived, bytesTotal);
} }
void Upload::downloadError(QNetworkReply::NetworkError error) { void Upload::downloadError(QNetworkReply::NetworkError error)
{
if (error == QNetworkReply::OperationCanceledError) { if (error == QNetworkReply::OperationCanceledError) {
qCCritical(taskUploadLogC) << getUid().toString() << "Aborted " << m_url.toString(); qCCritical(taskUploadLogC) << getUid().toString() << "Aborted " << m_url.toString();
m_state = State::AbortedByUser; m_state = State::AbortedByUser;
@ -70,20 +75,22 @@ namespace Net {
qCCritical(taskUploadLogC) << getUid().toString() << "Failed " << m_url.toString() << " with reason " << error; qCCritical(taskUploadLogC) << getUid().toString() << "Failed " << m_url.toString() << " with reason " << error;
m_state = State::Failed; m_state = State::Failed;
} }
} }
void Upload::sslErrors(const QList<QSslError> &errors) { void Upload::sslErrors(const QList<QSslError>& errors)
{
int i = 1; int i = 1;
for (const auto& error : errors) { for (const auto& error : errors) {
qCCritical(taskUploadLogC) << getUid().toString() << "Upload" << m_url.toString() << "SSL Error #" << i << " : " << error.errorString(); qCCritical(taskUploadLogC) << getUid().toString() << "Upload" << m_url.toString() << "SSL Error #" << i << " : "
<< error.errorString();
auto cert = error.certificate(); auto cert = error.certificate();
qCCritical(taskUploadLogC) << getUid().toString() << "Certificate in question:\n" << cert.toText(); qCCritical(taskUploadLogC) << getUid().toString() << "Certificate in question:\n" << cert.toText();
i++; i++;
} }
} }
bool Upload::handleRedirect() bool Upload::handleRedirect()
{ {
QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl(); QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl();
if (!redirect.isValid()) { if (!redirect.isValid()) {
if (!m_reply->hasRawHeader("Location")) { if (!m_reply->hasRawHeader("Location")) {
@ -133,9 +140,10 @@ namespace Net {
qCDebug(taskUploadLogC) << getUid().toString() << "Following redirect to " << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Following redirect to " << m_url.toString();
startAction(m_network); startAction(m_network);
return true; return true;
} }
void Upload::downloadFinished() { void Upload::downloadFinished()
{
// handle HTTP redirection first // handle HTTP redirection first
// very unlikely for post requests, still can happen // very unlikely for post requests, still can happen
if (handleRedirect()) { if (handleRedirect()) {
@ -148,19 +156,19 @@ namespace Net {
qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed but we are allowed to proceed:" << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed but we are allowed to proceed:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit succeeded(); emitSucceeded();
return; return;
} else if (m_state == State::Failed) { } else if (m_state == State::Failed) {
qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed in previous step:" << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed in previous step:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit failed(""); emitFailed("");
return; return;
} else if (m_state == State::AbortedByUser) { } else if (m_state == State::AbortedByUser) {
qCDebug(taskUploadLogC) << getUid().toString() << "Upload aborted in previous step:" << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Upload aborted in previous step:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit aborted(); emitAborted();
return; return;
} }
@ -177,27 +185,29 @@ namespace Net {
qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed to finalize:" << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Upload failed to finalize:" << m_url.toString();
m_sink->abort(); m_sink->abort();
m_reply.reset(); m_reply.reset();
emit failed(""); emitFailed("");
return; return;
} }
m_reply.reset(); m_reply.reset();
qCDebug(taskUploadLogC) << getUid().toString() << "Upload succeeded:" << m_url.toString(); qCDebug(taskUploadLogC) << getUid().toString() << "Upload succeeded:" << m_url.toString();
emit succeeded(); emitSucceeded();
} }
void Upload::downloadReadyRead() { void Upload::downloadReadyRead()
{
if (m_state == State::Running) { if (m_state == State::Running) {
auto data = m_reply->readAll(); auto data = m_reply->readAll();
m_state = m_sink->write(data); m_state = m_sink->write(data);
} }
} }
void Upload::executeTask() { void Upload::executeTask()
{
setStatus(tr("Uploading %1").arg(m_url.toString())); setStatus(tr("Uploading %1").arg(m_url.toString()));
if (m_state == State::AbortedByUser) { if (m_state == State::AbortedByUser) {
qCWarning(taskUploadLogC) << getUid().toString() << "Attempt to start an aborted Upload:" << m_url.toString(); qCWarning(taskUploadLogC) << getUid().toString() << "Attempt to start an aborted Upload:" << m_url.toString();
emit aborted(); emitAborted();
return; return;
} }
QNetworkRequest request(m_url); QNetworkRequest request(m_url);
@ -219,18 +229,18 @@ namespace Net {
return; return;
} }
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); #if defined(LAUNCHER_APPLICATION)
// TODO remove duplication auto user_agent = APPLICATION->getUserAgent();
if (APPLICATION->capabilities() & Application::SupportsFlame && request.url().host() == QUrl(BuildConfig.FLAME_BASE_URL).host()) { #else
request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8()); auto user_agent = BuildConfig.USER_AGENT;
} else if (request.url().host() == QUrl(BuildConfig.MODRINTH_PROD_URL).host() || #endif
request.url().host() == QUrl(BuildConfig.MODRINTH_STAGING_URL).host()) { request.setHeader(QNetworkRequest::UserAgentHeader, user_agent.toUtf8());
QString token = APPLICATION->getModrinthAPIToken();
if (!token.isNull()) for (auto& header_proxy : m_headerProxies) {
request.setRawHeader("Authorization", token.toUtf8()); header_proxy->writeHeaders(request);
} }
//TODO other types of post requests ? // TODO other types of post requests ?
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply* rep = m_network->post(request, m_post_data); QNetworkReply* rep = m_network->post(request, m_post_data);
@ -244,13 +254,14 @@ namespace Net {
#endif #endif
connect(rep, &QNetworkReply::sslErrors, this, &Upload::sslErrors); connect(rep, &QNetworkReply::sslErrors, this, &Upload::sslErrors);
connect(rep, &QNetworkReply::readyRead, this, &Upload::downloadReadyRead); connect(rep, &QNetworkReply::readyRead, this, &Upload::downloadReadyRead);
} }
Upload::Ptr Upload::makeByteArray(QUrl url, QByteArray *output, QByteArray m_post_data) { Upload::Ptr Upload::makeByteArray(QUrl url, QByteArray* output, QByteArray m_post_data)
{
auto up = makeShared<Upload>(); auto up = makeShared<Upload>();
up->m_url = std::move(url); up->m_url = std::move(url);
up->m_sink.reset(new ByteArraySink(output)); up->m_sink.reset(new ByteArraySink(output));
up->m_post_data = std::move(m_post_data); up->m_post_data = std::move(m_post_data);
return up; return up;
} }
} // Net } // namespace Net

View File

@ -42,32 +42,32 @@
namespace Net { namespace Net {
class Upload : public NetAction { class Upload : public NetAction {
Q_OBJECT Q_OBJECT
public: public:
using Ptr = shared_qobject_ptr<Upload>; using Ptr = shared_qobject_ptr<Upload>;
static Upload::Ptr makeByteArray(QUrl url, QByteArray *output, QByteArray m_post_data); static Upload::Ptr makeByteArray(QUrl url, QByteArray* output, QByteArray m_post_data);
auto abort() -> bool override; auto abort() -> bool override;
auto canAbort() const -> bool override { return true; }; auto canAbort() const -> bool override { return true; };
virtual void init() override {}; virtual void init() override{};
protected slots: protected slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
void downloadError(QNetworkReply::NetworkError error) override; void downloadError(QNetworkReply::NetworkError error) override;
void sslErrors(const QList<QSslError> & errors) override; void sslErrors(const QList<QSslError>& errors) override;
void downloadFinished() override; void downloadFinished() override;
void downloadReadyRead() override; void downloadReadyRead() override;
public slots: public slots:
void executeTask() override; void executeTask() override;
private:
protected:
std::unique_ptr<Sink> m_sink; std::unique_ptr<Sink> m_sink;
QByteArray m_post_data; QByteArray m_post_data;
bool handleRedirect(); bool handleRedirect();
}; };
} // Net
} // namespace Net