Files
qt5-legatus-legacy/Lts/Proxies/Buildings/BuildingControlUnit/handle_http_request.cpp
T
2026-08-13 18:33:10 +02:00

194 lines
6.0 KiB
C++
Executable File

/**
* @RDE_HEADER@
* One EGCU HandleHttpRequest
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-02-07
*/
#include "handle_http_request.h"
#include <QAuthenticator>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
namespace BuildingControlUnit
{
HandleHttpRequest::HandleHttpRequest(bool useQueue, QObject *parent)
: QObject(parent)
, m_nam(new QNetworkAccessManager(this))
, m_bUseQueue(useQueue)
, m_logger(getLogger("HandleHttpRequest"))
{
INFO_LOG(m_logger) << "Using Queue: " << m_bUseQueue;
connect(m_nam, &QNetworkAccessManager::finished,
this, &HandleHttpRequest::onReplyFinished);
connect(m_nam, &QNetworkAccessManager::authenticationRequired,
this, &HandleHttpRequest::onAuthenticationRequired);
}
/*
void HandleHttpRequest::enqueue(const QString &path, const QString &query)
{
QUrl url;
url.setScheme(QStringLiteral("http"));
url.setHost(m_config.hostname);
url.setPort(m_config.port);
url.setUserName(m_config.username);
url.setPassword(m_config.password);
url.setPath(path);
url.setQuery(query);
m_requests.enqueue(QNetworkRequest(url));
INFO_LOG(m_logger) << "Added '" << m_requests.back().url().toString() << " to queue";
trySendNextRequest();
}
*/
void HandleHttpRequest::init(const QString &username, const QString &passwd)
{
m_username = username;
m_passwd = passwd;
}
void HandleHttpRequest::enqueue(const QUrl &url, HandleHttpQueueMessageStatus status)
{
QString host = url.host();
if (!m_queueMap.contains(host))//If host already in map
{
m_queueMap.insert(host, HandleHttpQueue());
}
if ((HandleHttpQueueMessageStatus::MS_Cyclic == status) &&
m_queueMap[host].uniquenessChecker.contains(url.toString()))
{
WARNING_LOG(m_logger) << "Discarding duplicate url \"" << url.toString() << "\" due to slow message handling.";
}
else
{
NetworkRequest networkRequest;
networkRequest.request = QNetworkRequest(url);
m_queueMap[host].uniquenessChecker.insert(url.toString());
m_queueMap[host].requests.enqueue(networkRequest);
DEBUG_LOG(m_logger) << "Added '" << url.toString() << " to queue for host: " << host
<< " Queue has " << m_queueMap[host].requests.count() << " elements";
trySendNextRequest();
}
}
void HandleHttpRequest::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
{
if (!reply || !authenticator)
{
ERROR_LOG(m_logger) << "Internal error - Nullptr exception!";
}
else if (!m_queueMap.contains(reply->url().host()))
{
WARNING_LOG(m_logger) << "Internal error - got auth reply from unknown host!";
}
else
{
if (m_bUseQueue && reply != m_queueMap[reply->url().host()].activeReply)
WARNING_LOG(m_logger) << "Internal error - got auth reply from unknown request!";
// fail on second attempt when user/password is wrong
if (m_queueMap[reply->url().host()].bAuthAlreadyRequested)
return;
DEBUG_LOG(m_logger) << "Authentication request";
authenticator->setUser(m_username);
authenticator->setPassword(m_passwd);
m_queueMap[reply->url().host()].bAuthAlreadyRequested = true;
}
}
void HandleHttpRequest::onReplyFinished(QNetworkReply *reply)
{
if ( reply->error() > 0)
{
m_queueMap.remove(reply->url().host());
return;
}
if (!reply)
{
ERROR_LOG(m_logger) << "Internal error - Nullptr exception!";
}
else if (!m_queueMap.contains(reply->url().host()))
{
reply->deleteLater();
WARNING_LOG(m_logger) << "Internal error - got reply from unknown host!";
}
else if (m_bUseQueue && reply != m_queueMap[reply->url().host()].activeReply)
{
reply->deleteLater();
WARNING_LOG(m_logger) << "Internal error - got reply from unknown request!";
}
else
{
const int responseCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (responseCode == 200)
{
if ( m_newConnection)
{
m_newConnection = false;
DEBUG_LOG(m_logger) << "emit newEgcuConnection host=" << reply->url().host();
emit newEgcuConnection(reply->url().host());
}
DEBUG_LOG(m_logger) << "Request successfull";
}
else
WARNING_LOG(m_logger) << "Invalid request for host " << reply->url().host() << ", response code: " << responseCode << ", query: " << reply->url().toString();
QByteArray replyData = reply->readAll();
DEBUG_LOG(m_logger) << "Got reply (" << reply->url().toString() << "): " << replyData
<< " host=" << reply->url().host();
emit egcuReply(reply->url().host(), replyData);
m_queueMap[reply->url().host()].activeReply = nullptr;
reply->deleteLater();
QTimer::singleShot(0, this, &HandleHttpRequest::trySendNextRequest);
}
}
void HandleHttpRequest::sendNextRequest(HandleHttpQueue& queue)
{
if (m_bUseQueue && queue.activeReply != nullptr)
{
WARNING_LOG(m_logger) << "Internal error - active reply not yet finished!";
}
else if (!queue.requests.isEmpty())
{
queue.bAuthAlreadyRequested = false;
const NetworkRequest networkRequest = queue.requests.dequeue();
const QNetworkRequest request = networkRequest.request;
queue.uniquenessChecker.remove(request.url().toString());
if ( networkRequest.time.secsTo(QTime::currentTime()) < 5)
{
queue.activeReply = m_nam->get(request);
DEBUG_LOG(m_logger) << "Send request " << request.url().toString() << " and waiting for reply (" << queue.activeReply << ")";
}
else
{
DEBUG_LOG(m_logger) << "remove request " << request.url().toString()
<< " because it's too old" << networkRequest.time.secsTo(QTime::currentTime());
sendNextRequest(queue);
m_newConnection = true;
}
}
}
void HandleHttpRequest::trySendNextRequest()
{
// current active request -> wait for it to finish
for (HandleHttpQueue& queue : m_queueMap)
{
if (!(m_bUseQueue && queue.activeReply != nullptr))
{
sendNextRequest(queue);
}
}
}
} // namespace BuildingControlUnit