135 lines
4.0 KiB
C++
135 lines
4.0 KiB
C++
#include "HttpHelper.h"
|
|
#include <QNetworkProxy>
|
|
#include "ConfigHelper.h"
|
|
#include <QFile>
|
|
#include <QDir>
|
|
#include <QApplication>
|
|
#include <QJsonParseError>
|
|
#include <QTimer>
|
|
#include <QUrl>
|
|
|
|
namespace {
|
|
|
|
int requestTimeoutMs()
|
|
{
|
|
bool timeoutOk = false;
|
|
int timeoutMs = ConfigHelper::instance().getValue("Update", "request_timeout_ms").toInt(&timeoutOk);
|
|
if (!timeoutOk || timeoutMs < 1000)
|
|
timeoutMs = 5000;
|
|
return timeoutMs;
|
|
}
|
|
|
|
void applyCommonHeaders(QNetworkRequest& req, const QString& bearerToken)
|
|
{
|
|
const QString clientToken = ConfigHelper::instance().getValue(QStringLiteral("Server"), QStringLiteral("client_token")).trimmed();
|
|
if (!clientToken.isEmpty())
|
|
req.setRawHeader("X-Client-Token", clientToken.toUtf8());
|
|
|
|
const QString token = bearerToken.trimmed();
|
|
if (!token.isEmpty())
|
|
req.setRawHeader("Authorization", QByteArray("Bearer ") + token.toUtf8());
|
|
}
|
|
|
|
void readJsonReply(QNetworkReply* reply, int* retCode, QJsonObject* retObj)
|
|
{
|
|
*retCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
const QByteArray respData = reply->readAll();
|
|
if (!respData.isEmpty()) {
|
|
qDebug() << "Server raw response:" << respData;
|
|
QJsonParseError parseError;
|
|
const QJsonDocument document = QJsonDocument::fromJson(respData, &parseError);
|
|
if (parseError.error == QJsonParseError::NoError && document.isObject())
|
|
*retObj = document.object();
|
|
}
|
|
if (reply->error() != QNetworkReply::NoError)
|
|
{
|
|
qDebug() << "Network error code:" << reply->error();
|
|
qDebug() << "HTTP status:" << *retCode << "detail:" << reply->errorString();
|
|
}
|
|
}
|
|
|
|
void waitForReply(const QString& url, QNetworkReply* reply)
|
|
{
|
|
QEventLoop loop;
|
|
QTimer timer;
|
|
timer.setSingleShot(true);
|
|
QObject::connect(&timer, &QTimer::timeout, [&]() {
|
|
if (reply && reply->isRunning()) {
|
|
qDebug() << "Request timeout, abort:" << url;
|
|
reply->abort();
|
|
}
|
|
});
|
|
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
|
timer.start(requestTimeoutMs());
|
|
loop.exec();
|
|
timer.stop();
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void HttpHelper::postRequest(const QString& url, const QJsonObject& jsonBody,
|
|
std::function<void(int code, const QJsonObject& resp)> callback)
|
|
{
|
|
postRequest(url, jsonBody, QString(), callback);
|
|
}
|
|
|
|
void HttpHelper::postRequest(const QString& url, const QJsonObject& jsonBody,
|
|
const QString& bearerToken,
|
|
std::function<void(int code, const QJsonObject& resp)> callback)
|
|
{
|
|
QNetworkAccessManager* manager = new QNetworkAccessManager();
|
|
manager->setProxy(QNetworkProxy::NoProxy);
|
|
|
|
QNetworkRequest req{QUrl(url)};
|
|
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
applyCommonHeaders(req, bearerToken);
|
|
|
|
QByteArray data = QJsonDocument(jsonBody).toJson(QJsonDocument::Compact);
|
|
qDebug() << "=== POST Request ===";
|
|
qDebug() << "Url:" << url;
|
|
qDebug() << "Body:" << data;
|
|
|
|
QNetworkReply* reply = manager->post(req, data);
|
|
waitForReply(url, reply);
|
|
|
|
int retCode = 0;
|
|
QJsonObject retObj;
|
|
readJsonReply(reply, &retCode, &retObj);
|
|
|
|
callback(retCode, retObj);
|
|
|
|
reply->deleteLater();
|
|
manager->deleteLater();
|
|
}
|
|
|
|
void HttpHelper::getRequest(const QString& url,
|
|
std::function<void(int code, const QJsonObject& resp)> callback)
|
|
{
|
|
getRequest(url, QString(), callback);
|
|
}
|
|
|
|
void HttpHelper::getRequest(const QString& url, const QString& bearerToken,
|
|
std::function<void(int code, const QJsonObject& resp)> callback)
|
|
{
|
|
QNetworkAccessManager* manager = new QNetworkAccessManager();
|
|
manager->setProxy(QNetworkProxy::NoProxy);
|
|
|
|
QNetworkRequest req{QUrl(url)};
|
|
applyCommonHeaders(req, bearerToken);
|
|
|
|
qDebug() << "=== GET Request ===";
|
|
qDebug() << "Url:" << url;
|
|
|
|
QNetworkReply* reply = manager->get(req);
|
|
waitForReply(url, reply);
|
|
|
|
int retCode = 0;
|
|
QJsonObject retObj;
|
|
readJsonReply(reply, &retCode, &retObj);
|
|
|
|
callback(retCode, retObj);
|
|
|
|
reply->deleteLater();
|
|
manager->deleteLater();
|
|
}
|