Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2000993
D217.1749455633.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
14 KB
Referenced Files
None
Subscribers
None
D217.1749455633.diff
View Options
diff --git a/src/contents/ui/FileHandler.qml b/src/contents/ui/FileHandler.qml
--- a/src/contents/ui/FileHandler.qml
+++ b/src/contents/ui/FileHandler.qml
@@ -30,7 +30,9 @@
* according to whether the file is encrypted or not.
*/
property var mxcUri: ""
- property var url: mxcUri ? fileHandler.matrixSdk.mxcUriToHttp(fileHandler.mxcUri) : ""
+ property var httpVer: MK.MatrixSdk.EndpointV1 // Prefer v1
+ property var url: fileHandler.mxcToHttp(httpVer, mxcUri)
+ property var saveFileUrl: ""
property var mediaId: mxcUri && fileHandler.getMediaId(fileHandler.mxcUri)
property var sha256: ""
property var key: ""
@@ -79,9 +81,16 @@
}
function downloadFile(saveFileUrl) {
- fileHandler.kazvIOManager.startNewDownloadJob(fileHandler.url,saveFileUrl,
+ fileHandler.saveFileUrl = saveFileUrl
+ let token = ""
+ if (httpVer === MK.MatrixSdk.EndpointV1) {
+ token = matrixSdk.token
+ }
+ fileHandler.kazvIOManager.startNewDownloadJob(fileHandler.url,
+ fileHandler.saveFileUrl,
fileHandler.mediaId,
fileHandler.sha256,
+ token,
fileHandler.key,
fileHandler.iv)
fileHandler.updateKazvIOJob(fileHandler.mediaId)
@@ -90,9 +99,14 @@
}
function cacheFile() {
+ let token = ""
+ if (fileHandler.httpVer === MK.MatrixSdk.EndpointV1) {
+ token = matrixSdk.token
+ }
fileHandler.cachedFile = fileHandler.kazvIOManager.cacheFile(fileHandler.url,
fileHandler.mediaId,
fileHandler.sha256,
+ token,
fileHandler.key,
fileHandler.iv)
fileHandler.updateKazvIOJob(fileHandler.mediaId)
@@ -107,11 +121,34 @@
}
if (kazvIOJob) {
fileHandler.kazvIOJob.result.connect(function (ec) {
+ if (ec === MK.KazvIOBaseJob.KIOError && fileHandler.httpVer === MK.MatrixSdk.EndpointV1) {
+ fileHandler.httpVer = MK.MatrixSdk.EndpointV3;
+ if (autoCache) {
+ fileHandler.cacheFile();
+ } else {
+ fileHandler.kazvIOManager.deleteDownloadJob(mediaId)
+ fileHandler.downloadFile(saveFileUrl);
+ }
+ return;
+ }
fileHandler.result = ec
})
}
}
+ function mxcToHttp(httpVer, mxcUri) {
+ if (!mxcUri) {
+ return "";
+ }
+ if (httpVer === MK.MatrixSdk.EndpointV3) {
+ return matrixSdk.mxcUriToHttp(mxcUri);
+ } else if (httpVer === MK.MatrixSdk.EndpointV1) {
+ return matrixSdk.mxcUriToHttpV1(mxcUri);
+ } else {
+ return "";
+ }
+ }
+
Component.onCompleted: {
// Check if there is an encryted file or unencrypted file
if (encryptedFileMxcUri &&
diff --git a/src/kazv-io-job.hpp b/src/kazv-io-job.hpp
--- a/src/kazv-io-job.hpp
+++ b/src/kazv-io-job.hpp
@@ -22,6 +22,8 @@
#include <memory>
#include <optional>
+using namespace Qt::Literals::StringLiterals;
+
struct KazvIOBaseJobPrivate;
class KazvIOBaseJob : public QObject
@@ -119,8 +121,11 @@
public:
KazvIODownloadJob(const QString &hash, std::optional<Kazv::AES256CTRDesc> aes = std::nullopt, QObject *parent = 0);
- KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl, const bool showProgressBar, const QString &hash,
- std::optional<Kazv::AES256CTRDesc> aes = std::nullopt, QObject *parent = 0);
+ KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl,
+ const bool showProgressBar, const QString &hash,
+ const QString &token = u""_s,
+ std::optional<Kazv::AES256CTRDesc> aes = std::nullopt,
+ QObject *parent = 0);
~KazvIODownloadJob();
Q_INVOKABLE QString fileName();
diff --git a/src/kazv-io-job.cpp b/src/kazv-io-job.cpp
--- a/src/kazv-io-job.cpp
+++ b/src/kazv-io-job.cpp
@@ -4,10 +4,12 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+#include <client.hpp>
#include <kazv-defs.hpp>
#include "kazv-io-job.hpp"
#include "matrix-room.hpp"
#include "kazv-log.hpp"
+#include "client/actions/content.hpp"
#include <QObject>
#include <QPointer>
@@ -164,15 +166,34 @@
m_d->hash = hash;
}
-KazvIODownloadJob::KazvIODownloadJob(const QString &fileName, const QUrl &serverUrl, bool showProgressBar,
- const QString &hash, std::optional<Kazv::AES256CTRDesc> aes, QObject *parent)
+KazvIODownloadJob::KazvIODownloadJob(const QString &fileName,
+ const QUrl &serverUrl, bool showProgressBar, const QString &hash,
+ const QString &token, std::optional<Kazv::AES256CTRDesc> aes,
+ QObject *parent)
: KazvIOBaseJob(aes, parent)
, m_d(new KazvIODownloadJobPrivate)
{
- if (setFile(fileName)) {
- auto flag = showProgressBar ? KIO::DefaultFlags : KIO::HideProgressInfo;
- setJob(KIO::get(serverUrl, KIO::NoReload, flag));
+ if (!setFile(fileName)) {
+ return;
}
+ auto flag = showProgressBar ? KIO::DefaultFlags : KIO::HideProgressInfo;
+ auto kioJob = KIO::get(serverUrl, KIO::NoReload, flag);
+ if (!token.isEmpty()) {
+ auto [serverName, mediaId] =
+ [&serverUrl]() -> std::pair<std::string, std::string>{
+ auto splited = serverUrl.path().split(u"/"_s);
+ return {splited.last(2).first().toStdString(),
+ splited.last(2).last().toStdString()};
+ }();
+ auto getContentJobV1 = Kazv::GetContentJobV1{
+ serverUrl.toString().toStdString(),
+ token.toStdString(), serverName, mediaId};
+ kioJob->addMetaData(u"customHTTPHeader"_s,
+ QStringLiteral("Authorization: ") .append(QString::fromStdString(
+ getContentJobV1.requestHeader()->at("Authorization"))));
+ }
+
+ setJob(kioJob);
m_d->hash = hash;
}
diff --git a/src/kazv-io-manager.hpp b/src/kazv-io-manager.hpp
--- a/src/kazv-io-manager.hpp
+++ b/src/kazv-io-manager.hpp
@@ -21,6 +21,8 @@
#include <memory>
+using namespace Qt::Literals::StringLiterals;
+
struct KazvIOManagerPrivate;
class KazvIOManager : public QObject
@@ -35,8 +37,8 @@
QPointer<KazvIODownloadJob> makeDownloadJob(
const QUrl &serverUrl, const QUrl &localFileUrl,
const bool showPrograssBar, const QString &hash,
- const QString &key = QStringLiteral(""),
- const QString &iv = QStringLiteral("")) const;
+ const QString &token = u""_s, const QString &key = u""_s,
+ const QString &iv = u""_s) const;
public:
explicit KazvIOManager(QObject *parent = 0);
@@ -47,11 +49,13 @@
* Multiple calls do not repeat downloads
* Returns the local url of the cached file.
*/
- Q_INVOKABLE QUrl cacheFile(const QUrl &fileUrl, const QString &id, const QString &hash = QStringLiteral(""),
- const QString &key = QStringLiteral(""), const QString &iv = QStringLiteral(""));
- Q_INVOKABLE KazvIOBaseJob *startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileName,
- const QString &jobId, const QString &hash,
- const QString &key = QStringLiteral(""), const QString &iv = QStringLiteral(""));
+ Q_INVOKABLE QUrl cacheFile(const QUrl &fileUrl, const QString &id,
+ const QString &token = u""_s, const QString &hash = u""_s,
+ const QString &key = u""_s, const QString &iv = u""_s);
+ Q_INVOKABLE KazvIOBaseJob *startNewDownloadJob(const QUrl &serverUrl,
+ const QUrl &localFileName, const QString &jobId, const QString &hash,
+ const QString &token = u""_s, const QString &key = u""_s,
+ const QString &iv = u""_s);
Q_INVOKABLE KazvIOBaseJob *startNewUploadJob(
const QUrl &serverUrl, const QUrl &localFileName, const QString &token,
const QString &roomId, MatrixRoomList *roomList, const bool encrypted,
diff --git a/src/kazv-io-manager.cpp b/src/kazv-io-manager.cpp
--- a/src/kazv-io-manager.cpp
+++ b/src/kazv-io-manager.cpp
@@ -61,30 +61,31 @@
QPointer<KazvIODownloadJob> KazvIOManager::makeDownloadJob(
const QUrl &serverUrl, const QUrl &localFileUrl,
- const bool showPrograssBar, const QString &hash,
+ const bool showPrograssBar, const QString &hash, const QString &token,
const QString &key, const QString &iv) const
{
QPointer<KazvIODownloadJob> job{};
if (key.isEmpty()) {
- job = new KazvIODownloadJob{localFileUrl.toLocalFile(),
- serverUrl, showPrograssBar, hash, std::nullopt};
+ job = new KazvIODownloadJob{localFileUrl.toLocalFile(), serverUrl,
+ showPrograssBar, hash, token, std::nullopt};
} else {
auto aes = Kazv::AES256CTRDesc{key.toStdString(), iv.toStdString()};
- job = new KazvIODownloadJob{localFileUrl.toLocalFile(),
- serverUrl, showPrograssBar, hash, aes};
+ job = new KazvIODownloadJob{localFileUrl.toLocalFile(), serverUrl,
+ showPrograssBar, hash, token, aes};
}
return job;
}
-QUrl KazvIOManager::cacheFile(const QUrl &fileUrl, const QString &id, const QString &hash,
- const QString &key, const QString &iv)
+QUrl KazvIOManager::cacheFile(const QUrl &fileUrl, const QString &id,
+ const QString &hash, const QString &token, const QString &key,
+ const QString &iv)
{
const QString filePath = m_d->cacheDir.filePath(id);
QDir dir(m_d->cacheDir.path());
if (!dir.exists(id) && this->getCacheJob(id) == nullptr) {
auto job = this->makeDownloadJob(fileUrl,
QUrl::fromLocalFile(filePath),
- /* showProgressBar = */ false, hash, key, iv);
+ /* showProgressBar = */ false, hash, token, key, iv);
m_d->cacheJobs[id] = job;
connect(job, &KazvIOBaseJob::result, this, [this, id](auto /* result */) {
m_d->cacheJobs[id]->deleteLater();
@@ -94,11 +95,12 @@
return QUrl::fromLocalFile(filePath);
}
-KazvIOBaseJob *KazvIOManager::startNewDownloadJob(const QUrl &serverUrl, const QUrl &localFileUrl,
- const QString &jobId, const QString &hash, const QString &key, const QString &iv)
+KazvIOBaseJob *KazvIOManager::startNewDownloadJob(const QUrl &serverUrl,
+ const QUrl &localFileUrl, const QString &jobId, const QString &hash,
+ const QString &token, const QString &key, const QString &iv)
{
auto downloadJob = this->makeDownloadJob(serverUrl, localFileUrl,
- /* showProgressBar = */ true, hash, key, iv);
+ /* showProgressBar = */ true, hash, token, key, iv);
m_d->downloadJobs[jobId].reset(downloadJob);
QQmlEngine::setObjectOwnership(downloadJob.data(), QQmlEngine::CppOwnership);
diff --git a/src/matrix-sdk.hpp b/src/matrix-sdk.hpp
--- a/src/matrix-sdk.hpp
+++ b/src/matrix-sdk.hpp
@@ -83,6 +83,13 @@
Q_ENUM(LoadSessionResult);
+ enum EndpointVer {
+ EndpointV3, // Classical endpoint series
+ EndpointV1, // Endpoints that needs authorization
+ };
+
+ Q_ENUM(EndpointVer);
+
explicit MatrixSdk(QObject *parent = 0);
~MatrixSdk() override;
@@ -95,6 +102,8 @@
Q_INVOKABLE QString mxcUriToHttp(QString mxcUri) const;
+ Q_INVOKABLE QString mxcUriToHttpV1(QString mxcUri) const;
+
Q_INVOKABLE MatrixDeviceList *devicesOfUser(QString userId) const;
Kazv::RandomInterface &randomGenerator() const;
diff --git a/src/matrix-sdk.cpp b/src/matrix-sdk.cpp
--- a/src/matrix-sdk.cpp
+++ b/src/matrix-sdk.cpp
@@ -371,6 +371,11 @@
return QString::fromStdString(m_d->clientOnSecondaryRoot.mxcUriToHttp(mxcUri.toStdString()));
}
+QString MatrixSdk::mxcUriToHttpV1(QString mxcUri) const
+{
+ return QString::fromStdString(m_d->clientOnSecondaryRoot.mxcUriToHttpV1(mxcUri.toStdString()));
+}
+
MatrixDeviceList *MatrixSdk::devicesOfUser(QString userId) const
{
return new MatrixDeviceList(m_d->clientOnSecondaryRoot.devicesOfUser(userId.toStdString()));
diff --git a/src/tests/kazv-io-job-test.cpp b/src/tests/kazv-io-job-test.cpp
--- a/src/tests/kazv-io-job-test.cpp
+++ b/src/tests/kazv-io-job-test.cpp
@@ -40,20 +40,25 @@
const QString downloadEndpoint =
u"/_matrix/client/v1/media/download/serverName/download"_s;
+ const QString downloadAuthEndpoint =
+ u"/_matrix/client/v1/media/download/serverName/auth"_s;
const QString downloadPauseEndpoint =
u"/_matrix/client/v1/media/download/serverName/pause"_s;
const QString downloadCancelEndpoint =
u"/_matrix/client/v1/media/download/serverName/cancel"_s;
const QString uploadEndpoint = u"/_matrix/media/v3/upload"_s;
+ const QString token = u"token"_s;
const char *downloadFileContent = "download";
const char *uploadFileContent = "upload";
const char *responseErrorContent = "ResponseError";
QString serverUrl;
+ bool hasAuth{false};
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void testDownload();
+ void testDownloadAuth();
void testUpload();
void testDownloadPause();
void testUploadPause();
@@ -96,6 +101,10 @@
res.write(downloadFile.readAll(), "application/octet-stream"_ba);
downloadFile.close();
});
+ httpServer.route(downloadAuthEndpoint, [this](const QHttpServerRequest &req) {
+ hasAuth = !req.headers().value(u"Authorization"_s).isNull();
+ return QHttpServerResponse(QHttpServerResponder::StatusCode::Ok);
+ });
httpServer.route(downloadPauseEndpoint, [this](QHttpServerResponderRef res) {
downloadFile.open();
QSignalSpy qs{this, &KazvIOJobTest::readyResume};
@@ -160,6 +169,18 @@
savedFile.close();
}
+void KazvIOJobTest::testDownloadAuth()
+{
+ // QTemporaryFile cannot be written by QSaveFile, use QTemporaryDir instead.
+ QTemporaryDir dir{};
+ auto fileName = dir.filePath(u"savedFile"_s);
+ auto url = QUrl{serverUrl + downloadAuthEndpoint};
+
+ KazvIODownloadJob job{fileName, url, false, hashStr, token};
+ QTRY_VERIFY(job.isResulted());
+ QVERIFY(hasAuth);
+}
+
void KazvIOJobTest::testUpload()
{
QTemporaryFile file;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 9, 12:53 AM (16 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
213113
Default Alt Text
D217.1749455633.diff (14 KB)
Attached To
Mode
D217: Add fallback endpoint for download
Attached
Detach File
Event Timeline
Log In to Comment