Page MenuHomePhorge

qt-job.cpp
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

qt-job.cpp

/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <kazv-defs.hpp>
#include <QNetworkAccessManager>
#include <QPointer>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrlQuery>
#include "kazv-log.hpp"
#include "qt-job.hpp"
struct QtJob::Private
{
QPointer<QNetworkAccessManager> manager;
BaseJob job;
std::function<void(Response)> callback;
QByteArray receivedData{};
QPointer<QNetworkReply> reply{};
QNetworkRequest createRequest() const
{
auto query = job.requestQuery();
auto qQuery = QUrlQuery();
for (auto &&[k, v] : query) {
qQuery.addQueryItem(QString::fromStdString(k), QString::fromStdString(v));
}
auto url = QUrl(QString::fromStdString(job.url()));
url.setQuery(qQuery);
auto request = QNetworkRequest(url);
auto header = job.requestHeader();
for (auto &&[k, v] : *header) {
request.setRawHeader(QByteArray::fromStdString(k), QByteArray::fromStdString(v));
}
return request;
}
Header getHeaders(QList<QNetworkReply::RawHeaderPair> headers)
{
typename Header::value_type res;
for (auto &&[name, value] : headers) {
res[name.toStdString()] = value.toStdString();
}
return res;
}
Body getBody(std::string str)
{
BaseJob::ReturnType returnType = job.returnType();
Body body;
if (returnType == BaseJob::ReturnType::Json) {
try {
body = BaseJob::JsonBody(std::move(json::parse(str)));
} catch (const json::exception &e) {
// the response is not valid json
body = std::move(str);
qCWarning(kazvLog) << "body is not correct json: " << e.what();
}
} else {
body = std::move(str);
}
return body;
}
};
static QByteArray methodFor(BaseJob::Get)
{
return "GET";
}
static QByteArray methodFor(BaseJob::Post)
{
return "POST";
}
static QByteArray methodFor(BaseJob::Put)
{
return "PUT";
}
static QByteArray methodFor(BaseJob::Delete)
{
return "DELETE";
}
static QByteArray methodFor(BaseJob::Method m)
{
return std::visit(
[](auto &&m) { return methodFor(m); },
m
);
}
QtJob::QtJob(QObject *parent, QNetworkAccessManager *manager, BaseJob job, std::function<void(Response)> callback)
: QObject(parent)
, m_d(new Private{manager, std::move(job), std::move(callback)})
{
auto request = m_d->createRequest();
auto body = QByteArray::fromStdString(std::get<BytesBody>(m_d->job.requestBody()));
auto method = methodFor(m_d->job.requestMethod());
qCInfo(kazvLog) << "QtJob: Requesting" << method << request.url();
m_d->reply = m_d->manager->sendCustomRequest(request, method, body);
connect(m_d->reply.data(), &QNetworkReply::readyRead, this, &QtJob::injectData);
connect(m_d->reply.data(), &QNetworkReply::finished, this, &QtJob::callCallback);
connect(m_d->reply.data(), &QNetworkReply::finished, this, &QtJob::finished);
}
QtJob::~QtJob() = default;
void QtJob::injectData()
{
auto size = m_d->reply->bytesAvailable();
auto thisRead = m_d->reply->read(size);
m_d->receivedData += thisRead;
}
void QtJob::callCallback()
{
auto statusCode = m_d->reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
auto header = m_d->getHeaders(m_d->reply->rawHeaderPairs());
auto body = m_d->getBody(std::move(m_d->receivedData).toStdString());
auto response = Response{
static_cast<Response::StatusCode>(statusCode),
body,
header,
{} // extraData, will be added in genResponse
};
auto transformedResponse = std::move(m_d->job).genResponse(response);
qCInfo(kazvLog) << "QtJob::callCallback: Returned" << statusCode;
std::move(m_d->callback)(std::move(transformedResponse));
deleteLater();
}

File Metadata

Mime Type
text/x-c
Expires
Tue, Nov 26, 2:04 PM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40356
Default Alt Text
qt-job.cpp (3 KB)

Event Timeline