summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Lysenko <lysenkoalexmail@gmail.com>2016-12-30 21:45:11 +0200
committerLars Schmertmann <lars.schmertmann@governikus.de>2017-01-27 11:15:09 +0000
commit6ce818a10c5f6fd2314524f5d701e13752e4a662 (patch)
tree707bfbd9d4985dec30f3210a084f5d1330920d9d
parentdfc91928f15302fa4e6c41802c60caec2c124942 (diff)
downloadqtwebsockets-6ce818a10c5f6fd2314524f5d701e13752e4a662.tar.gz
Add a function to hand off a tcp socket to the websocket server
This method allows a listening port to process connections with different protocols. It lets the websocket server handle a TCP socket, upgrading it to a websocket [ChangeLog][QWebSocketServer] Add support to handle external QTcpSocket Done-with: André Klitzing <aklitzing@gmail.com> Task-number: QTBUG-54276 Change-Id: Ia36b481dc87d6f3806e9f1e61e75e528640f1937 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
-rw-r--r--src/websockets/qwebsocketserver.cpp14
-rw-r--r--src/websockets/qwebsocketserver.h3
-rw-r--r--src/websockets/qwebsocketserver_p.cpp26
-rw-r--r--src/websockets/qwebsocketserver_p.h3
-rw-r--r--tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp34
5 files changed, 69 insertions, 11 deletions
diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp
index f8ecdf2..e4cfe12 100644
--- a/src/websockets/qwebsocketserver.cpp
+++ b/src/websockets/qwebsocketserver.cpp
@@ -612,4 +612,18 @@ QList<QWebSocketProtocol::Version> QWebSocketServer::supportedVersions() const
return d->supportedVersions();
}
+/*!
+ Upgrades a tcp \a socket to websocket.
+
+ The QWebSocketServer object will take ownership of the socket
+ object and delete it when appropriate.
+
+ \since 5.9
+*/
+void QWebSocketServer::handleConnection(QTcpSocket *socket) const
+{
+ Q_D(const QWebSocketServer);
+ d->handleConnection(socket);
+}
+
QT_END_NAMESPACE
diff --git a/src/websockets/qwebsocketserver.h b/src/websockets/qwebsocketserver.h
index 511a55b..f846290 100644
--- a/src/websockets/qwebsocketserver.h
+++ b/src/websockets/qwebsocketserver.h
@@ -54,6 +54,7 @@
QT_BEGIN_NAMESPACE
+class QTcpSocket;
class QWebSocketServerPrivate;
class QWebSocket;
class QWebSocketCorsAuthenticator;
@@ -118,6 +119,8 @@ public:
QList<QWebSocketProtocol::Version> supportedVersions() const;
+ void handleConnection(QTcpSocket *socket) const;
+
Q_SIGNALS:
void acceptError(QAbstractSocket::SocketError socketError);
void serverError(QWebSocketProtocol::CloseCode closeCode);
diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp
index d675056..b7972b0 100644
--- a/src/websockets/qwebsocketserver_p.cpp
+++ b/src/websockets/qwebsocketserver_p.cpp
@@ -384,17 +384,8 @@ void QWebSocketServerPrivate::setError(QWebSocketProtocol::CloseCode code, const
*/
void QWebSocketServerPrivate::onNewConnection()
{
- while (m_pTcpServer->hasPendingConnections()) {
- QTcpSocket *pTcpSocket = m_pTcpServer->nextPendingConnection();
- //use a queued connection because a QSslSocket
- //needs the event loop to process incoming data
- //if not queued, data is incomplete when handshakeReceived is called
- QObjectPrivate::connect(pTcpSocket, &QTcpSocket::readyRead,
- this, &QWebSocketServerPrivate::handshakeReceived,
- Qt::QueuedConnection);
- QObjectPrivate::connect(pTcpSocket, &QTcpSocket::disconnected,
- this, &QWebSocketServerPrivate::onSocketDisconnected);
- }
+ while (m_pTcpServer->hasPendingConnections())
+ handleConnection(m_pTcpServer->nextPendingConnection());
}
/*!
@@ -491,4 +482,17 @@ void QWebSocketServerPrivate::handshakeReceived()
}
}
+void QWebSocketServerPrivate::handleConnection(QTcpSocket *pTcpSocket) const
+{
+ if (Q_LIKELY(pTcpSocket)) {
+ // Use a queued connection because a QSslSocket needs the event loop to process incoming
+ // data. If not queued, data is incomplete when handshakeReceived is called.
+ QObjectPrivate::connect(pTcpSocket, &QTcpSocket::readyRead,
+ this, &QWebSocketServerPrivate::handshakeReceived,
+ Qt::QueuedConnection);
+ QObjectPrivate::connect(pTcpSocket, &QTcpSocket::disconnected,
+ this, &QWebSocketServerPrivate::onSocketDisconnected);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/websockets/qwebsocketserver_p.h b/src/websockets/qwebsocketserver_p.h
index 6aabebd..0ca7495 100644
--- a/src/websockets/qwebsocketserver_p.h
+++ b/src/websockets/qwebsocketserver_p.h
@@ -65,6 +65,7 @@
QT_BEGIN_NAMESPACE
class QTcpServer;
+class QTcpSocket;
class QWebSocketServer;
class QWebSocketServerPrivate : public QObjectPrivate
@@ -120,6 +121,8 @@ public:
void setError(QWebSocketProtocol::CloseCode code, const QString &errorString);
+ void handleConnection(QTcpSocket *pTcpSocket) const;
+
QWebSocketServer * const q_ptr;
private:
diff --git a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
index 7f2bfa4..82e2013 100644
--- a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
+++ b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
@@ -28,6 +28,7 @@
#include <QString>
#include <QtTest>
#include <QNetworkProxy>
+#include <QTcpServer>
#ifndef QT_NO_OPENSSL
#include <QtNetwork/qsslpresharedkeyauthenticator.h>
#include <QtNetwork/qsslcipher.h>
@@ -110,6 +111,7 @@ private Q_SLOTS:
void tst_maxPendingConnections();
void tst_serverDestroyedWhileSocketConnected();
void tst_scheme(); // qtbug-55927
+ void tst_handleConnection();
};
tst_QWebSocketServer::tst_QWebSocketServer()
@@ -563,6 +565,38 @@ void tst_QWebSocketServer::tst_scheme()
#endif
}
+void tst_QWebSocketServer::tst_handleConnection()
+{
+ QWebSocketServer wsServer(QString(), QWebSocketServer::NonSecureMode);
+ QSignalSpy wsServerConnectionSpy(&wsServer, &QWebSocketServer::newConnection);
+
+ QTcpServer tcpServer;
+ connect(&tcpServer, &QTcpServer::newConnection,
+ [&tcpServer, &wsServer]() {
+ wsServer.handleConnection(tcpServer.nextPendingConnection());
+ });
+ QVERIFY(tcpServer.listen());
+
+ QWebSocket webSocket;
+ QSignalSpy wsConnectedSpy(&webSocket, &QWebSocket::connected);
+ webSocket.open(QStringLiteral("ws://localhost:%1").arg(tcpServer.serverPort()));
+ QVERIFY(wsConnectedSpy.wait());
+
+ if (wsServerConnectionSpy.isEmpty())
+ QVERIFY(wsServerConnectionSpy.wait());
+
+ QScopedPointer<QWebSocket> webServerSocket(wsServer.nextPendingConnection());
+ QVERIFY(!webServerSocket.isNull());
+
+ QSignalSpy wsMessageReceivedSpy(webServerSocket.data(), &QWebSocket::textMessageReceived);
+ webSocket.sendTextMessage("dummy");
+ wsMessageReceivedSpy.wait();
+
+ QCOMPARE(wsMessageReceivedSpy.count(), 1);
+ QList<QVariant> arguments = wsMessageReceivedSpy.takeFirst();
+ QCOMPARE(arguments.first().toString(), QString("dummy"));
+}
+
QTEST_MAIN(tst_QWebSocketServer)
#include "tst_qwebsocketserver.moc"