diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-10-02 21:39:45 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2022-10-02 23:01:13 +0200 |
| commit | 8b0bc1fd585ca12776aa7e8e23d292c5056c7098 (patch) | |
| tree | 49f166b2abea83bf2dc4b8ab0d3167c7d24aca38 /src/client/QXmppHttpFileSharingProvider.cpp | |
| parent | e06057c4699fd439529aa91f3b36e40df7a8c05b (diff) | |
HttpFileSharingProvider: Report errors from the output device, clean up
Diffstat (limited to 'src/client/QXmppHttpFileSharingProvider.cpp')
| -rw-r--r-- | src/client/QXmppHttpFileSharingProvider.cpp | 56 |
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); } |
