aboutsummaryrefslogtreecommitdiff
path: root/lib/jobs
diff options
context:
space:
mode:
authorarawaaa <77910862+arawaaa@users.noreply.github.com>2021-12-27 17:35:28 -0600
committerGitHub <noreply@github.com>2021-12-27 17:35:28 -0600
commit7ec3ba834dd313c4408622da30e04cdc6f4cf7c7 (patch)
tree679d7dc5939a229ad46676cd1d7aeaea7a25abce /lib/jobs
parent17bf4d180297c7e87363e179b8afa79ddb15dca7 (diff)
parent674e984e459375974f619d0e778d43a2cc928dc3 (diff)
downloadlibquotient-7ec3ba834dd313c4408622da30e04cdc6f4cf7c7.tar.gz
libquotient-7ec3ba834dd313c4408622da30e04cdc6f4cf7c7.zip
Merge branch 'dev' into pinned
Diffstat (limited to 'lib/jobs')
-rw-r--r--lib/jobs/basejob.cpp174
-rw-r--r--lib/jobs/basejob.h94
-rw-r--r--lib/jobs/mediathumbnailjob.cpp8
-rw-r--r--lib/jobs/requestdata.cpp5
-rw-r--r--lib/jobs/requestdata.h5
-rw-r--r--lib/jobs/syncjob.cpp2
6 files changed, 156 insertions, 132 deletions
diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp
index 48c2996d..971fea7b 100644
--- a/lib/jobs/basejob.cpp
+++ b/lib/jobs/basejob.cpp
@@ -5,6 +5,7 @@
#include "basejob.h"
#include "connectiondata.h"
+#include "quotient_common.h"
#include <QtCore/QRegularExpression>
#include <QtCore/QTimer>
@@ -15,8 +16,6 @@
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
-#include <array>
-
using namespace Quotient;
using std::chrono::seconds, std::chrono::milliseconds;
using namespace std::chrono_literals;
@@ -25,7 +24,7 @@ BaseJob::StatusCode BaseJob::Status::fromHttpCode(int httpCode)
{
// Based on https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
if (httpCode / 10 == 41) // 41x errors
- return httpCode == 410 ? IncorrectRequestError : NotFoundError;
+ return httpCode == 410 ? IncorrectRequest : NotFound;
switch (httpCode) {
case 401:
return Unauthorised;
@@ -33,19 +32,19 @@ BaseJob::StatusCode BaseJob::Status::fromHttpCode(int httpCode)
case 403: case 407: // clang-format on
return ContentAccessError;
case 404:
- return NotFoundError;
+ return NotFound;
// clang-format off
case 400: case 405: case 406: case 426: case 428: case 505: // clang-format on
case 494: // Unofficial nginx "Request header too large"
case 497: // Unofficial nginx "HTTP request sent to HTTPS port"
- return IncorrectRequestError;
+ return IncorrectRequest;
case 429:
- return TooManyRequestsError;
+ return TooManyRequests;
case 501:
case 510:
- return RequestNotImplementedError;
+ return RequestNotImplemented;
case 511:
- return NetworkAuthRequiredError;
+ return NetworkAuthRequired;
default:
return NetworkError;
}
@@ -63,12 +62,6 @@ QDebug BaseJob::Status::dumpToLog(QDebug dbg) const
return dbg << ": " << message;
}
-template <typename... Ts>
-constexpr auto make_array(Ts&&... items)
-{
- return std::array<std::common_type_t<Ts...>, sizeof...(Ts)>({items...});
-}
-
class BaseJob::Private {
public:
struct JobTimeoutConfig {
@@ -78,8 +71,8 @@ public:
// Using an idiom from clang-tidy:
// http://clang.llvm.org/extra/clang-tidy/checks/modernize-pass-by-value.html
- Private(HttpVerb v, QString endpoint, const QUrlQuery& q, Data&& data,
- bool nt)
+ Private(HttpVerb v, QByteArray endpoint, const QUrlQuery& q,
+ RequestData&& data, bool nt)
: verb(v)
, apiEndpoint(std::move(endpoint))
, requestQuery(q)
@@ -113,10 +106,10 @@ public:
// Contents for the network request
HttpVerb verb;
- QString apiEndpoint;
+ QByteArray apiEndpoint;
QHash<QByteArray, QByteArray> requestHeaders;
QUrlQuery requestQuery;
- Data requestData;
+ RequestData requestData;
bool needsToken;
bool inBackground = false;
@@ -173,14 +166,36 @@ public:
}
};
-BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
+inline bool isHex(QChar c)
+{
+ return c.isDigit() || (c >= u'A' && c <= u'F') || (c >= u'a' && c <= u'f');
+}
+
+QByteArray BaseJob::encodeIfParam(const QString& paramPart)
+{
+ const auto percentIndex = paramPart.indexOf('%');
+ if (percentIndex != -1 && paramPart.size() > percentIndex + 2
+ && isHex(paramPart[percentIndex + 1])
+ && isHex(paramPart[percentIndex + 2])) {
+ qCWarning(JOBS)
+ << "Developers, upfront percent-encoding of job parameters is "
+ "deprecated since libQuotient 0.7; the string involved is"
+ << paramPart;
+ return QUrl(paramPart, QUrl::TolerantMode).toEncoded();
+ }
+ return QUrl::toPercentEncoding(paramPart);
+}
+
+BaseJob::BaseJob(HttpVerb verb, const QString& name, QByteArray endpoint,
bool needsToken)
- : BaseJob(verb, name, endpoint, Query {}, Data {}, needsToken)
+ : BaseJob(verb, name, std::move(endpoint), QUrlQuery {}, RequestData {},
+ needsToken)
{}
-BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
- const Query& query, Data&& data, bool needsToken)
- : d(new Private(verb, endpoint, query, std::move(data), needsToken))
+BaseJob::BaseJob(HttpVerb verb, const QString& name, QByteArray endpoint,
+ const QUrlQuery& query, RequestData&& data, bool needsToken)
+ : d(new Private(verb, std::move(endpoint), query, std::move(data),
+ needsToken))
{
setObjectName(name);
connect(&d->timer, &QTimer::timeout, this, &BaseJob::timeout);
@@ -201,13 +216,6 @@ QUrl BaseJob::requestUrl() const { return d->reply ? d->reply->url() : QUrl(); }
bool BaseJob::isBackground() const { return d->inBackground; }
-const QString& BaseJob::apiEndpoint() const { return d->apiEndpoint; }
-
-void BaseJob::setApiEndpoint(const QString& apiEndpoint)
-{
- d->apiEndpoint = apiEndpoint;
-}
-
const BaseJob::headers_t& BaseJob::requestHeaders() const
{
return d->requestHeaders;
@@ -224,16 +232,19 @@ void BaseJob::setRequestHeaders(const BaseJob::headers_t& headers)
d->requestHeaders = headers;
}
-const QUrlQuery& BaseJob::query() const { return d->requestQuery; }
+QUrlQuery BaseJob::query() const { return d->requestQuery; }
void BaseJob::setRequestQuery(const QUrlQuery& query)
{
d->requestQuery = query;
}
-const BaseJob::Data& BaseJob::requestData() const { return d->requestData; }
+const RequestData& BaseJob::requestData() const { return d->requestData; }
-void BaseJob::setRequestData(Data&& data) { std::swap(d->requestData, data); }
+void BaseJob::setRequestData(RequestData&& data)
+{
+ std::swap(d->requestData, data);
+}
const QByteArrayList& BaseJob::expectedContentTypes() const
{
@@ -263,17 +274,17 @@ const QNetworkReply* BaseJob::reply() const { return d->reply.data(); }
QNetworkReply* BaseJob::reply() { return d->reply.data(); }
-QUrl BaseJob::makeRequestUrl(QUrl baseUrl, const QString& path,
+QUrl BaseJob::makeRequestUrl(QUrl baseUrl, const QByteArray& encodedPath,
const QUrlQuery& query)
{
- auto pathBase = baseUrl.path();
- // QUrl::adjusted(QUrl::StripTrailingSlashes) doesn't help with root '/'
- while (pathBase.endsWith('/'))
- pathBase.chop(1);
- if (!path.startsWith('/')) // Normally API files do start with '/'
- pathBase.push_back('/'); // so this shouldn't be needed these days
-
- baseUrl.setPath(pathBase + path, QUrl::TolerantMode);
+ // Make sure the added path is relative even if it's not (the official
+ // API definitions have the leading slash though it's not really correct).
+ const auto pathUrl =
+ QUrl::fromEncoded(encodedPath.mid(encodedPath.startsWith('/')),
+ QUrl::StrictMode);
+ Q_ASSERT_X(pathUrl.isValid(), __FUNCTION__,
+ qPrintable(pathUrl.errorString()));
+ baseUrl = baseUrl.resolved(pathUrl);
baseUrl.setQuery(query);
return baseUrl;
}
@@ -288,7 +299,8 @@ void BaseJob::Private::sendRequest()
req.setRawHeader("Authorization",
QByteArray("Bearer ") + connection->accessToken());
req.setAttribute(QNetworkRequest::BackgroundRequestAttribute, inBackground);
- req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ req.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
+ QNetworkRequest::NoLessSafeRedirectPolicy);
req.setMaximumRedirectsAllowed(10);
req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
req.setAttribute(
@@ -353,7 +365,7 @@ void BaseJob::initiate(ConnectionData* connData, bool inBackground)
qCCritical(d->logCat)
<< "Developers, ensure the Connection is valid before using it";
Q_ASSERT(false);
- setStatus(IncorrectRequestError, tr("Invalid server connection"));
+ setStatus(IncorrectRequest, tr("Invalid server connection"));
}
// The status is no good, finalise
QTimer::singleShot(0, this, &BaseJob::finishJob);
@@ -403,42 +415,42 @@ BaseJob::Status BaseJob::Private::parseJson()
void BaseJob::gotReply()
{
- setStatus(checkReply(reply()));
-
- if (status().good()
- && d->expectedContentTypes == QByteArrayList { "application/json" }) {
+ // Defer actually updating the status until it's finalised
+ auto statusSoFar = checkReply(reply());
+ if (statusSoFar.good()
+ && d->expectedContentTypes == QByteArrayList { "application/json" }) //
+ {
d->rawResponse = reply()->readAll();
- setStatus(d->parseJson());
- if (status().good() && !expectedKeys().empty()) {
+ statusSoFar = d->parseJson();
+ if (statusSoFar.good() && !expectedKeys().empty()) {
const auto& responseObject = jsonData();
QByteArrayList missingKeys;
for (const auto& k: expectedKeys())
if (!responseObject.contains(k))
missingKeys.push_back(k);
if (!missingKeys.empty())
- setStatus(IncorrectResponse, tr("Required JSON keys missing: ")
- + missingKeys.join());
+ statusSoFar = { IncorrectResponse,
+ tr("Required JSON keys missing: ")
+ + missingKeys.join() };
}
+ setStatus(statusSoFar);
if (!status().good()) // Bad JSON in a "good" reply: bail out
return;
- } // else {
+ }
// If the endpoint expects anything else than just (API-related) JSON
// reply()->readAll() is not performed and the whole reply processing
// is left to derived job classes: they may read it piecemeal or customise
// per content type in prepareResult(), or even have read it already
// (see, e.g., DownloadFileJob).
- // }
-
- if (status().good())
+ if (statusSoFar.good()) {
setStatus(prepareResult());
- else {
- d->rawResponse = reply()->readAll();
- qCDebug(d->logCat).noquote()
- << "Error body (truncated if long):" << rawDataSample(500);
- // Parse the error payload and update the status if needed
- if (const auto newStatus = prepareError(); !newStatus.good())
- setStatus(newStatus);
+ return;
}
+
+ d->rawResponse = reply()->readAll();
+ qCDebug(d->logCat).noquote()
+ << "Error body (truncated if long):" << rawDataSample(500);
+ setStatus(prepareError(statusSoFar));
}
bool checkContentType(const QByteArray& type, const QByteArrayList& patterns)
@@ -503,7 +515,7 @@ BaseJob::Status BaseJob::checkReply(const QNetworkReply* reply) const
BaseJob::Status BaseJob::prepareResult() { return Success; }
-BaseJob::Status BaseJob::prepareError()
+BaseJob::Status BaseJob::prepareError(Status currentStatus)
{
// Try to make sense of the error payload but be prepared for all kinds
// of unexpected stuff (raw HTML, plain text, foreign JSON among those)
@@ -513,10 +525,10 @@ BaseJob::Status BaseJob::prepareError()
// By now, if d->parseJson() above succeeded then jsonData() will return
// a valid JSON object - or an empty object otherwise (in which case most
- // of if's below will fall through to `return NoError` at the end
+ // of if's below will fall through retaining the current status)
const auto& errorJson = jsonData();
const auto errCode = errorJson.value("errcode"_ls).toString();
- if (error() == TooManyRequestsError || errCode == "M_LIMIT_EXCEEDED") {
+ if (error() == TooManyRequests || errCode == "M_LIMIT_EXCEEDED") {
QString msg = tr("Too many requests");
int64_t retryAfterMs = errorJson.value("retry_after_ms"_ls).toInt(-1);
if (retryAfterMs >= 0)
@@ -526,16 +538,16 @@ BaseJob::Status BaseJob::prepareError()
d->connection->limitRate(milliseconds(retryAfterMs));
- return { TooManyRequestsError, msg };
+ return { TooManyRequests, msg };
}
if (errCode == "M_CONSENT_NOT_GIVEN") {
d->errorUrl = QUrl(errorJson.value("consent_uri"_ls).toString());
- return { UserConsentRequiredError };
+ return { UserConsentRequired };
}
if (errCode == "M_UNSUPPORTED_ROOM_VERSION"
|| errCode == "M_INCOMPATIBLE_ROOM_VERSION")
- return { UnsupportedRoomVersionError,
+ return { UnsupportedRoomVersion,
errorJson.contains("room_version"_ls)
? tr("Requested room version: %1")
.arg(errorJson.value("room_version"_ls).toString())
@@ -548,9 +560,9 @@ BaseJob::Status BaseJob::prepareError()
// Not localisable on the client side
if (errorJson.contains("error"_ls)) // Keep the code, update the message
- return { d->status.code, errorJson.value("error"_ls).toString() };
+ return { currentStatus.code, errorJson.value("error"_ls).toString() };
- return NoError; // Retain the status if the error payload is not recognised
+ return currentStatus; // The error payload is not recognised
}
QJsonValue BaseJob::takeValueFromJson(const QString& key)
@@ -717,27 +729,27 @@ QString BaseJob::statusCaption() const
return tr("Request was abandoned");
case NetworkError:
return tr("Network problems");
- case TimeoutError:
+ case Timeout:
return tr("Request timed out");
case Unauthorised:
return tr("Unauthorised request");
case ContentAccessError:
return tr("Access error");
- case NotFoundError:
+ case NotFound:
return tr("Not found");
- case IncorrectRequestError:
+ case IncorrectRequest:
return tr("Invalid request");
- case IncorrectResponseError:
+ case IncorrectResponse:
return tr("Response could not be parsed");
- case TooManyRequestsError:
+ case TooManyRequests:
return tr("Too many requests");
- case RequestNotImplementedError:
+ case RequestNotImplemented:
return tr("Function not implemented by the server");
- case NetworkAuthRequiredError:
+ case NetworkAuthRequired:
return tr("Network authentication required");
- case UserConsentRequiredError:
+ case UserConsentRequired:
return tr("User consent required");
- case UnsupportedRoomVersionError:
+ case UnsupportedRoomVersion:
return tr("The server does not support the needed room version");
default:
return tr("Request failed");
@@ -799,7 +811,7 @@ void BaseJob::abandon()
void BaseJob::timeout()
{
- setStatus(TimeoutError, "The job has timed out");
+ setStatus(Timeout, "The job has timed out");
finishJob();
}
diff --git a/lib/jobs/basejob.h b/lib/jobs/basejob.h
index ca91a781..ddf243ed 100644
--- a/lib/jobs/basejob.h
+++ b/lib/jobs/basejob.h
@@ -7,8 +7,10 @@
#include "requestdata.h"
#include "../logging.h"
#include "../converters.h"
+#include "../quotient_common.h"
#include <QtCore/QObject>
+#include <QtCore/QStringBuilder>
class QNetworkReply;
class QSslError;
@@ -23,7 +25,18 @@ class BaseJob : public QObject {
Q_PROPERTY(QUrl requestUrl READ requestUrl CONSTANT)
Q_PROPERTY(int maxRetries READ maxRetries WRITE setMaxRetries)
Q_PROPERTY(int statusCode READ error NOTIFY statusChanged)
+
+ static QByteArray encodeIfParam(const QString& paramPart);
+ template <int N>
+ static inline auto encodeIfParam(const char (&constPart)[N])
+ {
+ return constPart;
+ }
+
public:
+#define WITH_DEPRECATED_ERROR_VERSION(Recommended) \
+ Recommended, DECL_DEPRECATED_ENUMERATOR(Recommended##Error, Recommended)
+
/*! The status code of a job
*
* Every job is created in Unprepared status; upon calling prepare()
@@ -34,7 +47,7 @@ public:
*/
enum StatusCode {
Success = 0,
- NoError = Success, // To be compatible with Qt conventions
+ NoError = Success,
Pending = 1,
WarningLevel = 20, //< Warnings have codes starting from this
UnexpectedResponseType = 21,
@@ -43,28 +56,18 @@ public:
Abandoned = 50, //< A tiny period between abandoning and object deletion
ErrorLevel = 100, //< Errors have codes starting from this
NetworkError = 101,
- Timeout,
- TimeoutError = Timeout,
+ WITH_DEPRECATED_ERROR_VERSION(Timeout),
Unauthorised,
ContentAccessError,
- NotFoundError,
- IncorrectRequest,
- IncorrectRequestError = IncorrectRequest,
- IncorrectResponse,
- IncorrectResponseError = IncorrectResponse,
- JsonParseError //< \deprecated Use IncorrectResponse instead
- = IncorrectResponse,
- TooManyRequests,
- TooManyRequestsError = TooManyRequests,
+ WITH_DEPRECATED_ERROR_VERSION(NotFound),
+ WITH_DEPRECATED_ERROR_VERSION(IncorrectRequest),
+ WITH_DEPRECATED_ERROR_VERSION(IncorrectResponse),
+ WITH_DEPRECATED_ERROR_VERSION(TooManyRequests),
RateLimited = TooManyRequests,
- RequestNotImplemented,
- RequestNotImplementedError = RequestNotImplemented,
- UnsupportedRoomVersion,
- UnsupportedRoomVersionError = UnsupportedRoomVersion,
- NetworkAuthRequired,
- NetworkAuthRequiredError = NetworkAuthRequired,
- UserConsentRequired,
- UserConsentRequiredError = UserConsentRequired,
+ WITH_DEPRECATED_ERROR_VERSION(RequestNotImplemented),
+ WITH_DEPRECATED_ERROR_VERSION(UnsupportedRoomVersion),
+ WITH_DEPRECATED_ERROR_VERSION(NetworkAuthRequired),
+ WITH_DEPRECATED_ERROR_VERSION(UserConsentRequired),
CannotLeaveRoom,
UserDeactivated,
FileError,
@@ -72,21 +75,19 @@ public:
};
Q_ENUM(StatusCode)
- /**
- * A simple wrapper around QUrlQuery that allows its creation from
- * a list of string pairs
- */
- class Query : public QUrlQuery {
- public:
- using QUrlQuery::QUrlQuery;
- Query() = default;
- Query(const std::initializer_list<QPair<QString, QString>>& l)
- {
- setQueryItems(l);
- }
- };
+#undef WITH_DEPRECATED_ERROR_VERSION
- using Data = RequestData;
+ template <typename... StrTs>
+ static QByteArray makePath(StrTs&&... parts)
+ {
+ return (QByteArray() % ... % encodeIfParam(parts));
+ }
+
+ using Data
+#ifndef Q_CC_MSVC
+ Q_DECL_DEPRECATED_X("Use Quotient::RequestData instead")
+#endif
+ = RequestData;
/*!
* This structure stores the status of a server call job. The status
@@ -136,10 +137,11 @@ public:
};
public:
- BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
+ BaseJob(HttpVerb verb, const QString& name, QByteArray endpoint,
+ bool needsToken = true);
+ BaseJob(HttpVerb verb, const QString& name, QByteArray endpoint,
+ const QUrlQuery& query, RequestData&& data = {},
bool needsToken = true);
- BaseJob(HttpVerb verb, const QString& name, const QString& endpoint,
- const Query& query, Data&& data = {}, bool needsToken = true);
QUrl requestUrl() const;
bool isBackground() const;
@@ -194,7 +196,7 @@ public:
* If there's no top-level JSON object in the response or if there's
* no node with the key \p keyName, \p defaultValue is returned.
*/
- template <typename T, typename StrT> // Waiting for QStringViews...
+ template <typename T, typename StrT>
T loadFromJson(const StrT& keyName, T&& defaultValue = {}) const
{
const auto& jv = jsonData().value(keyName);
@@ -336,16 +338,18 @@ Q_SIGNALS:
protected:
using headers_t = QHash<QByteArray, QByteArray>;
+ Q_DECL_DEPRECATED_X("Deprecated due to being unused")
const QString& apiEndpoint() const;
+ Q_DECL_DEPRECATED_X("Deprecated due to being unused")
void setApiEndpoint(const QString& apiEndpoint);
const headers_t& requestHeaders() const;
void setRequestHeader(const headers_t::key_type& headerName,
const headers_t::mapped_type& headerValue);
void setRequestHeaders(const headers_t& headers);
- const QUrlQuery& query() const;
+ QUrlQuery query() const;
void setRequestQuery(const QUrlQuery& query);
- const Data& requestData() const;
- void setRequestData(Data&& data);
+ const RequestData& requestData() const;
+ void setRequestData(RequestData&& data);
const QByteArrayList& expectedContentTypes() const;
void addExpectedContentType(const QByteArray& contentType);
void setExpectedContentTypes(const QByteArrayList& contentTypes);
@@ -361,7 +365,7 @@ protected:
* The function ensures exactly one '/' between the path component of
* \p baseUrl and \p path. The query component of \p baseUrl is ignored.
*/
- static QUrl makeRequestUrl(QUrl baseUrl, const QString& path,
+ static QUrl makeRequestUrl(QUrl baseUrl, const QByteArray &encodedPath,
const QUrlQuery& query = {});
/*! Prepares the job for execution
@@ -395,10 +399,12 @@ protected:
* was not good (usually because of an unsuccessful HTTP code).
* The base implementation assumes Matrix JSON error object in the body;
* overrides are strongly recommended to call it for all stock Matrix
- * responses as early as possible but in addition can process custom errors,
+ * responses as early as possible and only then process custom errors,
* with JSON or non-JSON payload.
+ *
+ * \return updated (if necessary) job status
*/
- virtual Status prepareError();
+ virtual Status prepareError(Status currentStatus);
/*! \brief Get direct access to the JSON response object in the job
*
diff --git a/lib/jobs/mediathumbnailjob.cpp b/lib/jobs/mediathumbnailjob.cpp
index 7dbf4ab3..6fe8ef26 100644
--- a/lib/jobs/mediathumbnailjob.cpp
+++ b/lib/jobs/mediathumbnailjob.cpp
@@ -17,13 +17,17 @@ MediaThumbnailJob::MediaThumbnailJob(const QString& serverName,
const QString& mediaId, QSize requestedSize)
: GetContentThumbnailJob(serverName, mediaId, requestedSize.width(),
requestedSize.height(), "scale")
-{}
+{
+ setLoggingCategory(THUMBNAILJOB);
+}
MediaThumbnailJob::MediaThumbnailJob(const QUrl& mxcUri, QSize requestedSize)
: MediaThumbnailJob(mxcUri.authority(),
mxcUri.path().mid(1), // sans leading '/'
requestedSize)
-{}
+{
+ setLoggingCategory(THUMBNAILJOB);
+}
QImage MediaThumbnailJob::thumbnail() const { return _thumbnail; }
diff --git a/lib/jobs/requestdata.cpp b/lib/jobs/requestdata.cpp
index 047e2920..2c001ccc 100644
--- a/lib/jobs/requestdata.cpp
+++ b/lib/jobs/requestdata.cpp
@@ -3,6 +3,7 @@
#include "requestdata.h"
+#include <QtCore/QIODevice>
#include <QtCore/QBuffer>
#include <QtCore/QByteArray>
#include <QtCore/QJsonArray>
@@ -31,4 +32,8 @@ RequestData::RequestData(const QJsonObject& jo) : _source(fromJson(jo)) {}
RequestData::RequestData(const QJsonArray& ja) : _source(fromJson(ja)) {}
+RequestData::RequestData(QIODevice* source)
+ : _source(std::unique_ptr<QIODevice>(source))
+{}
+
RequestData::~RequestData() = default;
diff --git a/lib/jobs/requestdata.h b/lib/jobs/requestdata.h
index 4958e0f9..4f05e5ff 100644
--- a/lib/jobs/requestdata.h
+++ b/lib/jobs/requestdata.h
@@ -24,8 +24,7 @@ public:
RequestData(const QByteArray& a = {});
RequestData(const QJsonObject& jo);
RequestData(const QJsonArray& ja);
- RequestData(QIODevice* source) : _source(std::unique_ptr<QIODevice>(source))
- {}
+ RequestData(QIODevice* source);
RequestData(RequestData&&) = default;
RequestData& operator=(RequestData&&) = default;
~RequestData();
@@ -36,5 +35,3 @@ private:
std::unique_ptr<QIODevice> _source;
};
} // namespace Quotient
-/// \deprecated Use namespace Quotient instead
-namespace QMatrixClient = Quotient;
diff --git a/lib/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp
index 59a34ef3..9b1b46f0 100644
--- a/lib/jobs/syncjob.cpp
+++ b/lib/jobs/syncjob.cpp
@@ -10,7 +10,7 @@ static size_t jobId = 0;
SyncJob::SyncJob(const QString& since, const QString& filter, int timeout,
const QString& presence)
: BaseJob(HttpVerb::Get, QStringLiteral("SyncJob-%1").arg(++jobId),
- QStringLiteral("_matrix/client/r0/sync"))
+ "_matrix/client/r0/sync")
{
setLoggingCategory(SYNCJOB);
QUrlQuery query;