diff --git a/backend/source/backend/dropped_entry.cpp b/backend/source/backend/dropped_entry.cpp index f15b97c1..035ab7b3 100644 --- a/backend/source/backend/dropped_entry.cpp +++ b/backend/source/backend/dropped_entry.cpp @@ -58,5 +58,11 @@ std::optional droppedItemFromPath(std::filesystem::path .name = name ? name->value() : std::string{}, .type = droppedTypeOf(path, status), }; + if (entry.isRegularFile()) + { + std::error_code sizeError{}; + const auto size = std::filesystem::file_size(path, sizeError); + entry.size = sizeError ? 0u : size; + } return SharedData::DroppedItem{.path = *std::move(localPath), .entry = std::move(entry)}; } diff --git a/backend/source/backend/sftp/operation_queue.cpp b/backend/source/backend/sftp/operation_queue.cpp index 6019c4e5..64ac2e08 100644 --- a/backend/source/backend/sftp/operation_queue.cpp +++ b/backend/source/backend/sftp/operation_queue.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -33,6 +34,16 @@ using namespace std::chrono_literals; namespace { + /** + * @brief The size of the file at @p path, 0 when it cannot be read. + */ + std::uintmax_t localFileSize(std::filesystem::path const& path) + { + std::error_code error{}; + const auto size = std::filesystem::file_size(path, error); + return error ? 0u : size; + } + /** * @brief No path instead of an unset one, which the frontend would refuse to read. */ @@ -881,7 +892,8 @@ std::expected OperationQueue::addDownloadOperation( auto opts = resolveDownloadOptions(transferOptions, resolvedTimeout); opts.remotePath = remotePath; opts.localPath = localPath; - opts.bigFileOptimized = isBigFile; + // The caller's size can be missing, the slow path reports no speed. + opts.bigFileOptimized = isBigFile || result->size >= Constants::bigFileCutOff; opts.entry = result.value(); opts.createMissingDirectories = createMissingDirectories; opts.progressCallback = [weak = weak_from_this(), operationId, name = rpcName("onDownloadProgress")]( @@ -1444,7 +1456,8 @@ std::expected OperationQueue::addUploadOperation( auto opts = resolveUploadOptions(transferOptions, resolvedTimeout); opts.remotePath = remotePath; opts.localPath = localPath; - opts.bigFileOptimized = isBigFile; + // A dropped or tracked file comes without a size, the slow path reports no speed. + opts.bigFileOptimized = isBigFile || (!isSymlink && localFileSize(localNativePath) >= Constants::bigFileCutOff); opts.createMissingDirectories = createMissingDirectories; opts.progressCallback = [weak = weak_from_this(), operationId, name = rpcName("onUploadProgress")]( auto min, auto max, auto current, auto bytesPerSecond