Skip to content

Commit e17451f

Browse files
committed
Refactor WebSocket
1 parent 3e7bc78 commit e17451f

File tree

9 files changed

+145
-542
lines changed

9 files changed

+145
-542
lines changed

libsrc/webserver/CMakeLists.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS WebSockets REQUIRED)
12

23
file(GLOB_RECURSE webFiles RELATIVE ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/assets/webconfig/*)
34
file(RELATIVE_PATH webConfigPath ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/assets/webconfig)
@@ -28,13 +29,13 @@ add_library(webserver
2829
${CMAKE_SOURCE_DIR}/libsrc/webserver/StaticFileServing.cpp
2930
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebJsonRpc.h
3031
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebJsonRpc.cpp
31-
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebSocketClient.h
32-
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebSocketClient.cpp
33-
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebSocketUtils.h
32+
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebSocketJsonHandler.h
33+
${CMAKE_SOURCE_DIR}/libsrc/webserver/WebSocketJsonHandler.cpp
3434
${CMAKE_BINARY_DIR}/WebConfig.qrc
35-
)
35+
)
3636

3737
target_link_libraries(webserver
38+
Qt${QT_VERSION_MAJOR}::WebSockets
3839
hyperion
3940
hyperion-utils
4041
hyperion-api

libsrc/webserver/QtHttpClientWrapper.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "QtHttpReply.h"
66
#include "QtHttpServer.h"
77
#include "QtHttpHeader.h"
8-
#include "WebSocketClient.h"
8+
#include "WebSocketJsonHandler.h"
99
#include "WebJsonRpc.h"
1010

1111
#include <QCryptographicHash>
@@ -29,6 +29,8 @@ QtHttpClientWrapper::QtHttpClientWrapper (QTcpSocket * sock, const bool& localCo
2929
, m_webJsonRpc (nullptr)
3030
{
3131
connect (m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived);
32+
connect(&m_websocketServer, &QWebSocketServer::newConnection,
33+
this, &QtHttpClientWrapper::onNewWebSocketConnection);
3234
}
3335

3436
QString QtHttpClientWrapper::getGuid (void)
@@ -50,6 +52,11 @@ void QtHttpClientWrapper::onClientDataReceived (void)
5052
{
5153
if (m_sockClient != Q_NULLPTR)
5254
{
55+
if (!m_sockClient->isTransactionStarted())
56+
{
57+
m_sockClient->startTransaction();
58+
}
59+
5360
while (m_sockClient->bytesAvailable () != 0)
5461
{
5562
QByteArray line = m_sockClient->readLine ();
@@ -162,22 +169,25 @@ void QtHttpClientWrapper::onClientDataReceived (void)
162169
{
163170
case RequestParsed: // a valid request has ben fully parsed
164171
{
165-
// Catch websocket header "Upgrade"
166-
if(m_currentRequest->getHeader(QtHttpHeader::Upgrade).toLower() == "websocket")
167-
{
172+
const auto& upgradeValue = m_currentRequest->getHeader(QtHttpHeader::Upgrade).toLower();
173+
if (upgradeValue.compare(QByteArrayLiteral("websocket"), Qt::CaseInsensitive) == 0) {
174+
175+
qDebug() << "WebSocket upgrade detected, passing to QWebSocketServer";
176+
168177
if(m_websocketClient == Q_NULLPTR)
169178
{
170179
// disconnect this slot from socket for further requests
171180
disconnect(m_sockClient, &QTcpSocket::readyRead, this, &QtHttpClientWrapper::onClientDataReceived);
172-
// disabling packet bunching
173-
m_sockClient->setSocketOption(QAbstractSocket::LowDelayOption, 1);
174-
m_sockClient->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
175-
m_websocketClient = new WebSocketClient(m_currentRequest, m_sockClient, m_localConnection, this);
181+
m_sockClient->rollbackTransaction();
182+
m_websocketServer.handleConnection(m_sockClient);
183+
emit m_sockClient->readyRead();
184+
return;
176185
}
177186

178187
break;
179188
}
180189

190+
m_sockClient->commitTransaction();
181191
// add post data to request and catch /jsonrpc subroute url
182192
if ( m_currentRequest->getCommand() == "POST")
183193
{
@@ -227,6 +237,8 @@ void QtHttpClientWrapper::onClientDataReceived (void)
227237
case ParsingError: // there was an error durin one of parsing steps
228238
{
229239
m_sockClient->readAll (); // clear remaining buffer to ignore content
240+
m_sockClient->commitTransaction();
241+
230242
QtHttpReply reply (m_serverHandle);
231243
reply.setStatusCode (QtHttpReply::BadRequest);
232244
reply.appendRawData (QByteArrayLiteral ("<h1>Bad Request (HTTP parsing error) !</h1>"));
@@ -365,3 +377,19 @@ void QtHttpClientWrapper::closeConnection()
365377
}
366378
m_sockClient->close ();
367379
}
380+
381+
void QtHttpClientWrapper::onNewWebSocketConnection() {
382+
383+
// Handle the pending connection
384+
QWebSocket* webSocket = m_websocketServer.nextPendingConnection();
385+
if (webSocket) {
386+
qDebug() << "New WebSocket connection established";
387+
388+
// Manage the WebSocketJsonHandler for this connection
389+
WebSocketJsonHandler* handler = new WebSocketJsonHandler(webSocket);
390+
connect(webSocket, &QWebSocket::disconnected, handler, &QObject::deleteLater);
391+
}
392+
else {
393+
qWarning() << "No pending WebSocket connection!";
394+
}
395+
}

libsrc/webserver/QtHttpClientWrapper.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <QObject>
55
#include <QString>
6+
#include <QWebSocketServer>
7+
#include <QCoreApplication>
68

79
class QTcpSocket;
810

@@ -39,8 +41,17 @@ class QtHttpClientWrapper : public QObject {
3941
///
4042
void closeConnection();
4143

44+
QWebSocketServer m_websocketServer{
45+
QCoreApplication::applicationName() + QLatin1Char('/') + QCoreApplication::applicationVersion(),
46+
QWebSocketServer::NonSecureMode
47+
};
48+
49+
signals:
50+
void newWebSocketConnection();
51+
4252
private slots:
4353
void onClientDataReceived (void);
54+
void onNewWebSocketConnection();
4455

4556
protected:
4657
ParsingStatus sendReplyToClient (QtHttpReply * reply);

libsrc/webserver/QtHttpServer.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ QtHttpServer::QtHttpServer (QObject * parent)
4040
, m_netOrigin (NetOrigin::getInstance())
4141
{
4242
m_sockServer = new QtHttpServerWrapper (this);
43-
connect (m_sockServer, &QtHttpServerWrapper::newConnection, this, &QtHttpServer::onClientConnected);
43+
connect (m_sockServer, &QtHttpServerWrapper::newConnection, this, &QtHttpServer::onClientConnected, Qt::UniqueConnection);
4444
}
4545

4646
void QtHttpServer::start (quint16 port)
@@ -81,27 +81,27 @@ void QtHttpServer::onClientConnected (void)
8181
{
8282
if (QTcpSocket * sock = m_sockServer->nextPendingConnection ())
8383
{
84-
if(m_netOrigin->accessAllowed(sock->peerAddress(), sock->localAddress()))
84+
if (m_netOrigin->accessAllowed(sock->peerAddress(), sock->localAddress()))
8585
{
86-
connect (sock, &QTcpSocket::disconnected, this, &QtHttpServer::onClientDisconnected);
86+
connect(sock, &QTcpSocket::disconnected, this, &QtHttpServer::onClientDisconnected);
8787

8888
if (m_useSsl)
8989
{
90-
if (QSslSocket * ssl = qobject_cast<QSslSocket *> (sock))
90+
if (QSslSocket* ssl = qobject_cast<QSslSocket*> (sock))
9191
{
92-
connect (ssl, SslErrorSignal (&QSslSocket::sslErrors), this, &QtHttpServer::onClientSslErrors);
93-
connect (ssl, &QSslSocket::encrypted, this, &QtHttpServer::onClientSslEncrypted);
94-
connect (ssl, &QSslSocket::peerVerifyError, this, &QtHttpServer::onClientSslPeerVerifyError);
95-
connect (ssl, &QSslSocket::modeChanged, this, &QtHttpServer::onClientSslModeChanged);
96-
ssl->setLocalCertificateChain (m_sslCerts);
97-
ssl->setPrivateKey (m_sslKey);
98-
ssl->setPeerVerifyMode (QSslSocket::AutoVerifyPeer);
99-
ssl->startServerEncryption ();
92+
connect(ssl, SslErrorSignal(&QSslSocket::sslErrors), this, &QtHttpServer::onClientSslErrors);
93+
connect(ssl, &QSslSocket::encrypted, this, &QtHttpServer::onClientSslEncrypted);
94+
connect(ssl, &QSslSocket::peerVerifyError, this, &QtHttpServer::onClientSslPeerVerifyError);
95+
connect(ssl, &QSslSocket::modeChanged, this, &QtHttpServer::onClientSslModeChanged);
96+
ssl->setLocalCertificateChain(m_sslCerts);
97+
ssl->setPrivateKey(m_sslKey);
98+
ssl->setPeerVerifyMode(QSslSocket::AutoVerifyPeer);
99+
ssl->startServerEncryption();
100100
}
101101
}
102102

103-
QtHttpClientWrapper * wrapper = new QtHttpClientWrapper (sock, m_netOrigin->isLocalAddress(sock->peerAddress(), sock->localAddress()), this);
104-
m_socksClientsHash.insert (sock, wrapper);
103+
QtHttpClientWrapper* wrapper = new QtHttpClientWrapper(sock, m_netOrigin->isLocalAddress(sock->peerAddress(), sock->localAddress()), this);
104+
m_socksClientsHash.insert(sock, wrapper);
105105
emit clientConnected (wrapper->getGuid ());
106106
}
107107
else

0 commit comments

Comments
 (0)