aboutsummaryrefslogtreecommitdiff
path: root/src/client/QXmppHttpFileSharingProvider.cpp
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2022-10-02 21:39:45 +0200
committerLinus Jahn <lnj@kaidan.im>2022-10-02 23:01:13 +0200
commit8b0bc1fd585ca12776aa7e8e23d292c5056c7098 (patch)
tree49f166b2abea83bf2dc4b8ab0d3167c7d24aca38 /src/client/QXmppHttpFileSharingProvider.cpp
parente06057c4699fd439529aa91f3b36e40df7a8c05b (diff)
HttpFileSharingProvider: Report errors from the output device, clean up
Diffstat (limited to 'src/client/QXmppHttpFileSharingProvider.cpp')
-rw-r--r--src/client/QXmppHttpFileSharingProvider.cpp56
1 files changed, 33 insertions, 23 deletions
diff --git a/src/client/QXmppHttpFileSharingProvider.cpp b/src/client/QXmppHttpFileSharingProvider.cpp
index 5a8904f7..5b7304c5 100644
--- a/src/client/QXmppHttpFileSharingProvider.cpp
+++ b/src/client/QXmppHttpFileSharingProvider.cpp
@@ -55,13 +55,15 @@ auto QXmppHttpFileSharingProvider::downloadFile(const std::any &source,
{
~State() override = default;
+ std::function<void(DownloadResult)> reportFinished;
+ std::optional<QXmppError> error;
QNetworkReply *reply = nullptr;
bool finished = false;
bool cancelled = false;
void cancel() override
{
- if (!cancelled) {
+ if (!cancelled && !finished) {
cancelled = true;
reply->abort();
}
@@ -76,46 +78,54 @@ auto QXmppHttpFileSharingProvider::downloadFile(const std::any &source,
}
auto state = std::make_shared<State>();
+ state->reportFinished = std::move(reportFinished);
state->reply = d->netManager->get(QNetworkRequest(httpSource.url()));
- QObject::connect(state->reply, &QNetworkReply::finished, [state, reportFinished = std::move(reportFinished)]() mutable {
- Q_ASSERT(state);
-
+ QObject::connect(state->reply, &QNetworkReply::finished, [state]() mutable {
if (!state->finished) {
- if (state->reply->error() != QNetworkReply::NoError) {
- reportFinished(QXmppError::fromNetworkReply(*state->reply));
+ if (state->error) {
+ state->reportFinished(std::move(*state->error));
} else if (state->cancelled) {
- reportFinished(Cancelled());
+ state->reportFinished(Cancelled());
} else {
- reportFinished(Success());
+ state->reportFinished(Success());
}
state->finished = true;
+ state->reply->deleteLater();
}
- state->reply->deleteLater();
-
- // reduce ref count
- state.reset();
});
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
- QObject::connect(state->reply, &QNetworkReply::readyRead, [file = std::move(target), reply = state->reply]() {
- file->write(reply->readAll());
- });
+ QObject::connect(state->reply, &QNetworkReply::readyRead, [state, file = std::move(target)]() {
#else
auto file = std::shared_ptr<QIODevice>(std::move(target));
- QObject::connect(state->reply, &QNetworkReply::readyRead, [file, reply = state->reply]() {
- file->write(reply->readAll());
- });
+ QObject::connect(state->reply, &QNetworkReply::readyRead, [state, file]() {
#endif
+ auto data = state->reply->readAll();
+ if (file->write(data) != data.size()) {
+ state->error = QXmppError::fromIoDevice(*file);
+ }
+ });
- QObject::connect(state->reply, &QNetworkReply::downloadProgress, [stateRef = std::weak_ptr(state), reportProgress = std::move(reportProgress)](qint64 bytesReceived, qint64 bytesTotal) {
- if (auto state = stateRef.lock()) {
- if (!state->finished) {
- reportProgress(bytesReceived, bytesTotal);
- }
+ QObject::connect(state->reply, &QNetworkReply::downloadProgress, [state, reportProgress = std::move(reportProgress)](qint64 bytesReceived, qint64 bytesTotal) {
+ if (!state->finished) {
+ reportProgress(bytesReceived, bytesTotal);
}
});
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ QObject::connect(state->reply, &QNetworkReply::errorOccurred,
+#else
+ QObject::connect(state->reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
+#endif
+ [state](QNetworkReply::NetworkError) {
+ // Qt doc: the finished() signal will "probably" follow
+ // => we can't be sure that finished() is going to be called
+ state->reportFinished(QXmppError::fromNetworkReply(*state->reply));
+ state->finished = true;
+ state->reply->deleteLater();
+ });
+
return std::dynamic_pointer_cast<QXmppFileSharingProvider::Download>(state);
}