From 52bbac5dbe038331ec0ce77144c6b91125dc3c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Tue, 21 Feb 2023 14:02:17 -0500 Subject: [PATCH] profile: avoid incomplete transfer + Forward the onFinished signal to jamiaccount to only mark a profile as sent once finished. + For incoming transfer, only send to upper layer if file is complete. Change-Id: If0160330c65720f235d0fabacaf124a4b52ec823 --- src/data_transfer.cpp | 12 ++++++++---- src/data_transfer.h | 9 ++++++--- src/jamidht/jamiaccount.cpp | 35 +++++++++++++++++++---------------- src/jamidht/jamiaccount.h | 4 +++- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/data_transfer.cpp b/src/data_transfer.cpp index 10f75811c3..4d0371a7e5 100644 --- a/src/data_transfer.cpp +++ b/src/data_transfer.cpp @@ -203,13 +203,13 @@ IncomingFile::process() auto shared = w.lock(); if (!shared) return; - auto correct = shared->sha3Sum_.empty(); auto isEOF = shared->info_.bytesProgress == shared->info_.totalSize; if (shared->stream_ && shared->stream_.is_open()) { isEOF |= shared->stream_.eof(); shared->stream_.close(); } - if (!correct) { + auto correct = isEOF && shared->sha3Sum_.empty(); + if (!correct && !shared->sha3Sum_.empty()) { // Verify shaSum auto sha3Sum = fileutils::sha3File(shared->info_.path); if (shared->sha3Sum_ == sha3Sum) { @@ -306,7 +306,8 @@ TransferManager::transferFile(const std::shared_ptr<ChannelSocket>& channel, const std::string& interactionId, const std::string& path, size_t start, - size_t end) + size_t end, + OnFinishedCb onFinished) { std::lock_guard<std::mutex> lk {pimpl_->mapMutex_}; if (pimpl_->outgoings_.find(channel) != pimpl_->outgoings_.end()) @@ -316,7 +317,10 @@ TransferManager::transferFile(const std::shared_ptr<ChannelSocket>& channel, info.conversationId = pimpl_->to_; info.path = path; auto f = std::make_shared<OutgoingFile>(channel, fileId, interactionId, info, start, end); - f->onFinished([w = weak(), channel](uint32_t) { + f->onFinished([w = weak(), channel, onFinished = std::move(onFinished)](uint32_t code) { + if (code == uint32_t(libjami::DataTransferEventCode::finished) && onFinished) { + onFinished(); + } // schedule destroy outgoing transfer as not needed dht::ThreadPool().computation().run([w, channel] { if (auto sthis_ = w.lock()) { diff --git a/src/data_transfer.h b/src/data_transfer.h index 17aabe28f6..ffb84d360f 100644 --- a/src/data_transfer.h +++ b/src/data_transfer.h @@ -24,10 +24,11 @@ #include "connectivity/multiplexed_socket.h" #include "noncopyable.h" -#include <memory> -#include <string> #include <fstream> +#include <functional> +#include <memory> #include <optional> +#include <string> namespace jami { @@ -52,6 +53,7 @@ struct WaitingRequest }; typedef std::function<void(const std::string&)> InternalCompletionCb; +typedef std::function<void()> OnFinishedCb; class FileInfo { @@ -137,7 +139,8 @@ public: const std::string& interactionId, const std::string& path, size_t start = 0, - size_t end = 0); + size_t end = 0, + OnFinishedCb onFinished = {}); /** * Refuse a transfer diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index cc910d6b34..11ff568589 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -3684,18 +3684,19 @@ JamiAccount::sendProfile(const std::string& convId, const std::string& peerUri, return; } // We need a new channel - transferFile(convId, profilePath(), deviceId, "profile.vcf", ""); - // Mark the VCard as sent - auto sendDir = fmt::format("{}/{}/vcard/{}", - fileutils::get_cache_dir(), - getAccountID(), - peerUri); - auto path = fmt::format("{}/{}", sendDir, deviceId); - fileutils::recursive_mkdir(sendDir); - std::lock_guard<std::mutex> lock(fileutils::getFileLock(path)); - if (fileutils::isFile(path)) - return; - fileutils::ofstream(path); + transferFile(convId, profilePath(), deviceId, "profile.vcf", "", 0, 0, std::move([accId = getAccountID(), peerUri, deviceId]() { + // Mark the VCard as sent + auto sendDir = fmt::format("{}/{}/vcard/{}", + fileutils::get_cache_dir(), + accId, + peerUri); + auto path = fmt::format("{}/{}", sendDir, deviceId); + fileutils::recursive_mkdir(sendDir); + std::lock_guard<std::mutex> lock(fileutils::getFileLock(path)); + if (fileutils::isFile(path)) + return; + fileutils::ofstream(path); + })); } bool @@ -3998,7 +3999,8 @@ JamiAccount::transferFile(const std::string& conversationId, const std::string& fileId, const std::string& interactionId, size_t start, - size_t end) + size_t end, + std::function<void()> onFinished) { auto channelName = conversationId.empty() ? fmt::format("{}profile.vcf", DATA_TRANSFER_URI) : fmt::format("{}{}/{}/{}", @@ -4012,7 +4014,7 @@ JamiAccount::transferFile(const std::string& conversationId, connectionManager_->connectDevice( DeviceId(deviceId), channelName, - [this, conversationId, path = std::move(path), fileId, interactionId, start, end]( + [this, conversationId, path = std::move(path), fileId, interactionId, start, end, onFinished = std::move(onFinished)]( std::shared_ptr<ChannelSocket> socket, const DeviceId&) { if (!socket) return; @@ -4023,10 +4025,11 @@ JamiAccount::transferFile(const std::string& conversationId, fileId, interactionId, start, - end] { + end, + onFinished = std::move(onFinished)] { if (auto shared = w.lock()) if (auto dt = shared->dataTransfer(conversationId)) - dt->transferFile(socket, fileId, interactionId, path, start, end); + dt->transferFile(socket, fileId, interactionId, path, start, end, std::move(onFinished)); }); }); } diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h index a624429193..d3dda1f04a 100644 --- a/src/jamidht/jamiaccount.h +++ b/src/jamidht/jamiaccount.h @@ -58,6 +58,7 @@ #include <pjsip/sip_types.h> #include <chrono> +#include <functional> #include <future> #include <json/json.h> #include <list> @@ -518,7 +519,8 @@ public: const std::string& fileId, const std::string& interactionId, size_t start = 0, - size_t end = 0); + size_t end = 0, + std::function<void()> onFinished = {}); void askForFileChannel(const std::string& conversationId, const std::string& deviceId, -- GitLab