#include "HttpHelper.h" #include #include "ConfigHelper.h" #include #include #include #include void HttpHelper::postRequest(const QString& url, const QJsonObject& jsonBody, std::function callback) { QNetworkAccessManager* manager = new QNetworkAccessManager(); manager->setProxy(QNetworkProxy::NoProxy); QNetworkRequest req(url); req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); // Add auth token header QString token = ConfigHelper::instance().getValue("Server", "client_token"); req.setRawHeader("X-Client-Token", token.toUtf8()); QString identityPath = ConfigHelper::instance().clientIdentityPath(); if (!QFile::exists(identityPath)) identityPath = QDir(QApplication::applicationDirPath()).filePath("config/client_identity.dat"); QFile identity(identityPath); if (identity.open(QIODevice::ReadOnly)) req.setRawHeader("X-Device-Credential", identity.readAll().toBase64()); QByteArray data = QJsonDocument(jsonBody).toJson(QJsonDocument::Compact); qDebug() << "=== POST Request ==="; qDebug() << "Url:" << url; qDebug() << "Body:" << data; QNetworkReply* reply = manager->post(req, data); QEventLoop loop; bool timeoutOk = false; int timeoutMs = ConfigHelper::instance().getValue("Update", "request_timeout_ms").toInt(&timeoutOk); if (!timeoutOk || timeoutMs < 1000) timeoutMs = 5000; 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(timeoutMs); loop.exec(); timer.stop(); int retCode = 0; QJsonObject retObj; retCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); const QByteArray respData = reply->readAll(); if (!respData.isEmpty()) { qDebug() << "Server raw response:" << respData; retObj = QJsonDocument::fromJson(respData).object(); } if (reply->error() != QNetworkReply::NoError) { qDebug() << "Network error code:" << reply->error(); qDebug() << "HTTP status:" << retCode << "detail:" << reply->errorString(); } callback(retCode, retObj); reply->deleteLater(); manager->deleteLater(); }