#include "HttpHelper.h" #include #include "ConfigHelper.h" #include #include #include #include #include #include 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 callback) { postRequest(url, jsonBody, QString(), callback); } void HttpHelper::postRequest(const QString& url, const QJsonObject& jsonBody, const QString& bearerToken, std::function 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 callback) { getRequest(url, QString(), callback); } void HttpHelper::getRequest(const QString& url, const QString& bearerToken, std::function 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(); }