Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsRestClient/lts_rest_client.cpp
T

176 lines
5.2 KiB
C++

/**
* Lightweight REST Client Framework
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Fritsche, ESZS, 2026-08-21
*/
#include "lts_rest_client.h"
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
namespace LtsCommon
{
LtsRestClient::LtsRestClient(const QString &baseUrl, QObject *parent)
: QObject(parent)
, m_baseUrl(baseUrl)
, m_manager(new QNetworkAccessManager(this))
{
}
void LtsRestClient::ping(PingSuccessCallback onSuccess, ErrorCallback onError, int timeoutMs)
{
const QNetworkRequest request((QUrl(m_baseUrl)));
QNetworkReply *reply = m_manager->head(request);
if (!reply)
{
if (onError)
onError(QStringLiteral("Failed to initiate ping."));
return;
}
// 1. Setup the timer (parented to reply for auto-cleanup)
QTimer *timeoutTimer = new QTimer(reply);
timeoutTimer->setSingleShot(true);
// 2. Connect the timeout signal to abort the request
connect(timeoutTimer,
&QTimer::timeout,
this,
[reply]()
{
if (reply && reply->isRunning())
reply->abort(); // Triggers finished() with OperationCanceledError
});
// 3. Connect the finished signal to handle the response
connect(reply,
&QNetworkReply::finished,
this,
[reply, timeoutTimer, onSuccess, onError]()
{
timeoutTimer->stop();
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
if (onError)
{
if (reply->error() == QNetworkReply::OperationCanceledError)
onError(QStringLiteral("Ping timed out."));
else
onError(reply->errorString());
}
return;
}
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (onSuccess)
onSuccess(statusCode);
});
// 4. Start the timer only after all connections are successfully established
timeoutTimer->start(timeoutMs);
}
void LtsRestClient::get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
{
sendRequest(QStringLiteral("GET"), endpoint, QByteArray(), onSuccess, onError);
}
void LtsRestClient::post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
{
sendRequest(QStringLiteral("POST"), endpoint, json.toJson(), onSuccess, onError);
}
void LtsRestClient::put(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
{
sendRequest(QStringLiteral("PUT"), endpoint, json.toJson(), onSuccess, onError);
}
void LtsRestClient::del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
{
sendRequest(QStringLiteral("DELETE"), endpoint, QByteArray(), onSuccess, onError);
}
void LtsRestClient::sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError)
{
QUrl url(m_baseUrl);
url.setPath(url.path() + endpoint);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
QNetworkReply *reply = nullptr;
if (method == QStringLiteral("GET"))
reply = m_manager->get(request);
else if (method == QStringLiteral("POST"))
reply = m_manager->post(request, data);
else if (method == QStringLiteral("PUT"))
reply = m_manager->put(request, data);
else if (method == QStringLiteral("DELETE"))
reply = m_manager->deleteResource(request);
if (!reply)
{
if (onError)
onError(QStringLiteral("Failed to initiate request."));
return;
}
connect(reply,
&QNetworkReply::finished,
this,
[reply, onSuccess, onError]()
{
reply->deleteLater();
// Handle network errors
if (reply->error() != QNetworkReply::NoError)
{
if (onError)
onError(reply->errorString());
return;
}
// Handle HTTP errors
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode >= 400)
{
if (onError)
onError(QStringLiteral("HTTP Error %1").arg(statusCode));
return;
}
// Parse JSON safely
QJsonParseError parseError;
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &parseError);
if (parseError.error != QJsonParseError::NoError)
{
if (onError)
onError(QStringLiteral("JSON Parse Error: ") + parseError.errorString());
return;
}
if (onSuccess)
onSuccess(doc);
});
}
} // namespace LtsCommon