This commit is contained in:
LordGrey 2024-12-28 14:05:23 +01:00
parent fb1703f5e2
commit becbbeba27
5 changed files with 56 additions and 39 deletions

View File

@ -27,10 +27,9 @@ QtHttpClientWrapper::QtHttpClientWrapper (QTcpSocket * sock, const bool& localCo
, m_localConnection(localConnection) , m_localConnection(localConnection)
, m_websocketClient(nullptr) , m_websocketClient(nullptr)
, m_webJsonRpc (nullptr) , m_webJsonRpc (nullptr)
, m_websocketServer (nullptr)
{ {
connect (m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived); connect(m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived);
connect(&m_websocketServer, &QWebSocketServer::newConnection,
this, &QtHttpClientWrapper::onNewWebSocketConnection);
} }
QString QtHttpClientWrapper::getGuid (void) QString QtHttpClientWrapper::getGuid (void)
@ -172,14 +171,19 @@ void QtHttpClientWrapper::onClientDataReceived (void)
const auto& upgradeValue = m_currentRequest->getHeader(QtHttpHeader::Upgrade).toLower(); const auto& upgradeValue = m_currentRequest->getHeader(QtHttpHeader::Upgrade).toLower();
if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) { if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) {
qDebug() << "WebSocket upgrade detected, passing to QWebSocketServer";
if(m_websocketClient == Q_NULLPTR) if(m_websocketClient == Q_NULLPTR)
{ {
// disconnect this slot from socket for further requests // disconnect this slot from socket for further requests
disconnect(m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived); disconnect(m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived);
m_sockClient->rollbackTransaction(); m_sockClient->rollbackTransaction();
m_websocketServer.handleConnection(m_sockClient);
QString servername = QCoreApplication::applicationName() + QLatin1Char('/') + HYPERION_VERSION;
QWebSocketServer::SslMode secureMode = m_serverHandle->isSecure() ? QWebSocketServer::SecureMode : QWebSocketServer::NonSecureMode;
m_websocketServer.reset(new QWebSocketServer(servername, secureMode));
connect(m_websocketServer.get(), &QWebSocketServer::newConnection,
this, &QtHttpClientWrapper::onNewWebSocketConnection);
m_websocketServer->handleConnection(m_sockClient);
emit m_sockClient->readyRead(); emit m_sockClient->readyRead();
return; return;
} }
@ -381,10 +385,8 @@ void QtHttpClientWrapper::closeConnection()
void QtHttpClientWrapper::onNewWebSocketConnection() { void QtHttpClientWrapper::onNewWebSocketConnection() {
// Handle the pending connection // Handle the pending connection
QWebSocket* webSocket = m_websocketServer.nextPendingConnection(); QWebSocket* webSocket = m_websocketServer->nextPendingConnection();
if (webSocket) { if (webSocket) {
qDebug() << "New WebSocket connection established";
// Manage the WebSocketJsonHandler for this connection // Manage the WebSocketJsonHandler for this connection
WebSocketJsonHandler* handler = new WebSocketJsonHandler(webSocket); WebSocketJsonHandler* handler = new WebSocketJsonHandler(webSocket);
connect(webSocket, &QWebSocket::disconnected, handler, &QObject::deleteLater); connect(webSocket, &QWebSocket::disconnected, handler, &QObject::deleteLater);

View File

@ -5,6 +5,7 @@
#include <QString> #include <QString>
#include <QWebSocketServer> #include <QWebSocketServer>
#include <QCoreApplication> #include <QCoreApplication>
#include <QScopedPointer>
class QTcpSocket; class QTcpSocket;
@ -41,11 +42,6 @@ public:
/// ///
void closeConnection(); void closeConnection();
QWebSocketServer m_websocketServer{
QCoreApplication::applicationName() + QLatin1Char('/') + QCoreApplication::applicationVersion(),
QWebSocketServer::NonSecureMode
};
signals: signals:
void newWebSocketConnection(); void newWebSocketConnection();
@ -70,6 +66,7 @@ private:
WebSocketClient * m_websocketClient; WebSocketClient * m_websocketClient;
WebJsonRpc * m_webJsonRpc; WebJsonRpc * m_webJsonRpc;
QByteArray m_fragment; QByteArray m_fragment;
QScopedPointer<QWebSocketServer> m_websocketServer;
}; };
#endif // QTHTTPCLIENTWRAPPER_H #endif // QTHTTPCLIENTWRAPPER_H

View File

@ -46,21 +46,22 @@ public:
typedef void (QSslSocket::* SslErrorSignal) (const QList<QSslError> &); typedef void (QSslSocket::* SslErrorSignal) (const QList<QSslError> &);
const QString & getServerName (void) const { return m_serverName; }; const QString & getServerName (void) const { return m_serverName; }
quint16 getServerPort (void) const { return m_sockServer->serverPort(); }; quint16 getServerPort (void) const { return m_sockServer->serverPort(); }
QString getErrorString (void) const { return m_sockServer->errorString(); }; QString getErrorString (void) const { return m_sockServer->errorString(); }
bool isListening() { return m_sockServer->isListening(); }; bool isListening() { return m_sockServer->isListening(); }
bool isSecure() { return m_useSsl; }
public slots: public slots:
void start (quint16 port = 0); void start (quint16 port = 0);
void stop (void); void stop (void);
void setUseSecure (const bool ssl = true); void setUseSecure (bool ssl = true);
void setServerName (const QString & serverName) { m_serverName = serverName; }; void setServerName (const QString & serverName) { m_serverName = serverName; }
void setPrivateKey (const QSslKey & key) { m_sslKey = key; }; void setPrivateKey (const QSslKey & key) { m_sslKey = key; }
void setCertificates (const QList<QSslCertificate> & certs) { m_sslCerts = certs; }; void setCertificates (const QList<QSslCertificate> & certs) { m_sslCerts = certs; }
QSslKey getPrivateKey() { return m_sslKey; }; QSslKey getPrivateKey() { return m_sslKey; }
QList<QSslCertificate> getCertificates() { return m_sslCerts; }; QList<QSslCertificate> getCertificates() { return m_sslCerts; }
signals: signals:
void started (quint16 port); void started (quint16 port);
@ -73,10 +74,10 @@ signals:
private slots: private slots:
void onClientConnected (void); void onClientConnected (void);
void onClientDisconnected (void); void onClientDisconnected (void);
void onClientSslEncrypted (void) { }; void onClientSslEncrypted (void) { }
void onClientSslPeerVerifyError (const QSslError & err) { Q_UNUSED (err) }; void onClientSslPeerVerifyError (const QSslError & err) { Q_UNUSED (err) }
void onClientSslErrors (const QList<QSslError> & errors) { Q_UNUSED (errors) }; void onClientSslErrors (const QList<QSslError> & errors) { Q_UNUSED (errors) }
void onClientSslModeChanged (QSslSocket::SslMode mode) { Q_UNUSED (mode) }; void onClientSslModeChanged (QSslSocket::SslMode mode) { Q_UNUSED (mode) }
private: private:
bool m_useSsl; bool m_useSsl;

View File

@ -5,21 +5,26 @@
#include <utils/JsonUtils.h> #include <utils/JsonUtils.h>
#include <utils/NetOrigin.h> #include <utils/NetOrigin.h>
#define NO_TRACE_SEND
#define NO_TRACE_RECEIVE
WebSocketJsonHandler::WebSocketJsonHandler(QWebSocket* websocket, QObject* parent) WebSocketJsonHandler::WebSocketJsonHandler(QWebSocket* websocket, QObject* parent)
: QObject(parent) : QObject(parent)
, _websocket(websocket) , _websocket(websocket)
, _log(Logger::getInstance("WEBSOCKET")) , _log(Logger::getInstance("WEBSOCKET"))
{ {
connect(_websocket, &QWebSocket::textMessageReceived, this, &WebSocketJsonHandler::onTextMessageReceived); connect(_websocket, &QWebSocket::textMessageReceived, this, &WebSocketJsonHandler::onTextMessageReceived);
connect(_websocket, &QWebSocket::binaryMessageReceived, this, &WebSocketJsonHandler::onBinaryMessageReceived);
connect(_websocket, &QWebSocket::disconnected, this, &WebSocketJsonHandler::onDisconnected); connect(_websocket, &QWebSocket::disconnected, this, &WebSocketJsonHandler::onDisconnected);
const QString client = _websocket->peerAddress().toString(); _peerAddress = _websocket->peerAddress().toString();
Debug(_log, "New WebSocket connection from %s", QSTRING_CSTR(client)); _origin = websocket->origin();
Debug(_log, "New WebSocket connection from %s initiated via: %s", QSTRING_CSTR(_peerAddress), QSTRING_CSTR(_origin));
bool localConnection = NetOrigin::getInstance()->isLocalAddress(_websocket->peerAddress(), _websocket->localAddress()); bool localConnection = NetOrigin::getInstance()->isLocalAddress(_websocket->peerAddress(), _websocket->localAddress());
// Json processor // Json processor
_jsonAPI.reset(new JsonAPI(client, _log, localConnection, this)); _jsonAPI.reset(new JsonAPI(_peerAddress, _log, localConnection, this));
connect(_jsonAPI.get(), &JsonAPI::callbackReady, this, &WebSocketJsonHandler::sendMessage); connect(_jsonAPI.get(), &JsonAPI::callbackReady, this, &WebSocketJsonHandler::sendMessage);
connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebSocketJsonHandler::sendMessage); connect(_jsonAPI->getCallBack().get(), &JsonCallbacks::callbackReady, this, &WebSocketJsonHandler::sendMessage);
@ -30,20 +35,29 @@ WebSocketJsonHandler::WebSocketJsonHandler(QWebSocket* websocket, QObject* paren
void WebSocketJsonHandler::onTextMessageReceived(const QString& message) void WebSocketJsonHandler::onTextMessageReceived(const QString& message)
{ {
qDebug() << "WebSocket message received:" << message; #ifdef RECEIVE_TRACE
_jsonAPI.get()->handleMessage(message); qDebug() << "[" << _peerAddress << "] WebSocket message received:" << message;
#endif
_jsonAPI->handleMessage(message);
}
void WebSocketJsonHandler::onBinaryMessageReceived(const QByteArray& message)
{
#ifdef RECEIVE_TRACE
qDebug() << "[" << _peerAddress << "] WebSocket message received:" << message.toHex();
#endif
Warning(_log,"Unexpected binary message received");
} }
qint64 WebSocketJsonHandler::sendMessage(QJsonObject obj) qint64 WebSocketJsonHandler::sendMessage(QJsonObject obj)
{ {
QString const message = JsonUtils::jsonValueToQString(obj); #ifdef TRACE_SEND
qDebug() << "WebSocket send message: " << message; qDebug() << "[" << _peerAddress << "] WebSocket send message: " << obj;
return _websocket->sendTextMessage(message); #endif
return _websocket->sendTextMessage(JsonUtils::jsonValueToQString(obj));
} }
void WebSocketJsonHandler::onDisconnected() void WebSocketJsonHandler::onDisconnected()
{ {
qDebug() << "WebSocket disconnected"; Debug(_log, "WebSocket disconnected from %s initiated via: %s", QSTRING_CSTR(_peerAddress), QSTRING_CSTR(_origin));
} }

View File

@ -17,6 +17,7 @@ public:
private slots: private slots:
void onTextMessageReceived(const QString& message); void onTextMessageReceived(const QString& message);
void onBinaryMessageReceived(const QByteArray& message);
void onDisconnected(); void onDisconnected();
qint64 sendMessage(QJsonObject obj); qint64 sendMessage(QJsonObject obj);
@ -25,6 +26,8 @@ private:
Logger* _log; Logger* _log;
QScopedPointer<JsonAPI> _jsonAPI; QScopedPointer<JsonAPI> _jsonAPI;
QString _peerAddress;
QString _origin;
}; };
#endif // WEBSOCKETJSONHANDLER_H #endif // WEBSOCKETJSONHANDLER_H