From b871f6d3557c20fc7d1456e5080c33ea90795c84 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Sun, 2 Oct 2022 02:45:09 +0200 Subject: Generate QXmppUpload/Download only by FileSharingManager Previously all the providers had to subclass the QXmppUpload/Download. It should be much easier to do additional tasks (e.g. hashing after downloading) now because the manager (and not the provider) decides when to emit the finished signal. Making the encrypted source provider able to handle arbitrary unencrypted sources should be possible too. --- .../QXmppEncryptedHttpFileSharingProvider.cpp | 88 ++++++++-------------- 1 file changed, 32 insertions(+), 56 deletions(-) (limited to 'src/client/QXmppEncryptedHttpFileSharingProvider.cpp') diff --git a/src/client/QXmppEncryptedHttpFileSharingProvider.cpp b/src/client/QXmppEncryptedHttpFileSharingProvider.cpp index b6e82621..82aa351e 100644 --- a/src/client/QXmppEncryptedHttpFileSharingProvider.cpp +++ b/src/client/QXmppEncryptedHttpFileSharingProvider.cpp @@ -6,8 +6,9 @@ #include "QXmppClient.h" #include "QXmppFileEncryption.h" +#include "QXmppFileMetadata.h" +#include "QXmppFutureUtils_p.h" #include "QXmppHttpUploadManager.h" -#include "QXmppUpload.h" #include "QXmppUtils.h" #include "QcaInitializer_p.h" @@ -16,43 +17,6 @@ using namespace QXmpp; using namespace QXmpp::Private; -class QXmppSfsEncryptedHttpUpload : public QXmppUpload -{ - Q_OBJECT - -public: - QXmppSfsEncryptedHttpUpload(std::shared_ptr &&httpUpload, const QByteArray &key, const QByteArray &iv) - : inner(std::move(httpUpload)) - { - connect(inner.get(), &QXmppHttpUpload::finished, this, [=](const QXmppHttpUpload::Result &result) { - Q_EMIT uploadFinished(std::visit([=](auto &&value) -> QXmpp::Private::UploadResult { - using T = std::decay_t; - if constexpr (std::is_same_v) { - QXmppEncryptedFileSource encryptedSource; - encryptedSource.setKey(key); - encryptedSource.setIv(iv); - encryptedSource.setHttpSources({ QXmppHttpFileSource(value) }); - return std::any(encryptedSource); - } else if constexpr (std::is_same_v) { - return Cancelled {}; - } else if constexpr (std::is_same_v) { - return value; - } - }, - result)); - }); - } - - float progress() override { return inner->progress(); } - void cancel() override { inner->cancel(); } - bool isFinished() override { return inner->isFinished(); } - quint64 bytesTransferred() override { return inner->bytesSent(); } - quint64 bytesTotal() override { return inner->bytesTotal(); } - -private: - std::shared_ptr inner; -}; - /// /// \class QXmppEncryptedHttpFileSharingProvider /// @@ -65,7 +29,6 @@ class QXmppEncryptedHttpFileSharingProviderPrivate { public: QXmpp::Private::QcaInitializer init; - QXmppHttpUploadManager *manager; QXmppHttpFileSharingProvider *httpProvider; }; @@ -77,16 +40,16 @@ public: QXmppEncryptedHttpFileSharingProvider::QXmppEncryptedHttpFileSharingProvider(QXmppClient *client, QNetworkAccessManager *netManager) : d(std::make_unique()) { - qRegisterMetaType(); - Q_ASSERT(client); - d->manager = client->findExtension(); - Q_ASSERT(d->manager); d->httpProvider = new QXmppHttpFileSharingProvider(client, netManager); } QXmppEncryptedHttpFileSharingProvider::~QXmppEncryptedHttpFileSharingProvider() = default; -std::shared_ptr QXmppEncryptedHttpFileSharingProvider::downloadFile(const std::any &source, std::unique_ptr &&target) +auto QXmppEncryptedHttpFileSharingProvider::downloadFile(const std::any &source, + std::unique_ptr target, + std::function reportProgress, + std::function reportFinished) + -> std::shared_ptr { QXmppEncryptedFileSource encryptedSource; try { @@ -97,12 +60,14 @@ std::shared_ptr QXmppEncryptedHttpFileSharingProvider::downloadFi auto httpSource = encryptedSource.httpSources().front(); auto output = std::make_unique(std::move(target), encryptedSource.cipher(), encryptedSource.iv(), encryptedSource.key()); - return d->httpProvider->downloadFile(httpSource, std::move(output)); + return d->httpProvider->downloadFile(httpSource, std::move(output), std::move(reportProgress), std::move(reportFinished)); } -std::shared_ptr QXmppEncryptedHttpFileSharingProvider::uploadFile( - std::unique_ptr data, - const QXmppFileMetadata &info) +auto QXmppEncryptedHttpFileSharingProvider::uploadFile(std::unique_ptr data, + const QXmppFileMetadata &, + std::function reportProgress, + std::function reportFinished) + -> std::shared_ptr { auto cipher = Aes256CbcPkcs7; auto key = Encryption::generateKey(cipher); @@ -111,13 +76,24 @@ std::shared_ptr QXmppEncryptedHttpFileSharingProvider::uploadFile( auto encDevice = std::make_unique(std::move(data), cipher, key, iv); auto encryptedSize = encDevice->size(); - auto upload = d->manager->uploadFile( - std::move(encDevice), - QXmppUtils::generateStanzaHash(10), - QMimeDatabase().mimeTypeForName("application/octet-stream"), - encryptedSize); + QXmppFileMetadata metadata; + metadata.setFilename(QXmppUtils::generateStanzaHash(10)); + metadata.setMediaType(QMimeDatabase().mimeTypeForName("application/octet-stream")); + metadata.setSize(encryptedSize); - return std::make_shared(std::move(upload), key, iv); + return d->httpProvider->uploadFile( + std::move(encDevice), + metadata, + std::move(reportProgress), + [=, reportFinished = std::move(reportFinished)](UploadResult result) { + auto encryptedResult = visitForward(std::move(result), [&](std::any httpSourceAny) { + QXmppEncryptedFileSource encryptedSource; + encryptedSource.setKey(key); + encryptedSource.setIv(iv); + encryptedSource.setHttpSources({ std::any_cast(std::move(httpSourceAny)) }); + + return encryptedSource; + }); + reportFinished(std::move(encryptedResult)); + }); } - -#include "QXmppEncryptedHttpFileSharingProvider.moc" -- cgit v1.2.3