summaryrefslogtreecommitdiff
path: root/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
diff options
context:
space:
mode:
authorArno Rehn <a.rehn@menlosystems.com>2022-01-02 22:31:03 +0100
committerArno Rehn <a.rehn@menlosystems.com>2022-03-30 17:45:18 +0200
commitcc4c24b99a87629aeb60df5af96d9bb991b56635 (patch)
tree62459a42457b0680022bb1fcb759f9c4e64d2c4b /tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
parent8545bb57efbfabf0dc7bc4b76efd6a99b4022669 (diff)
downloadqtwebsockets-cc4c24b99a87629aeb60df5af96d9bb991b56635.tar.gz
Add support for WebSocket Sub-Protocols
Sub-Protocol support follows RFC 6455 Sections 4.1 and 4.2. See also https://datatracker.ietf.org/doc/html/rfc6455. This patch introduces a new class QWebSocketHandshakeOptions which collects options for the WebSocket handshake. At the moment, this contains only accessors for sub-protocols. In the future, it can be extended with things like WebSocket extensions. [ChangeLog] Add support for WebSocket Sub-Protocols Fixes: QTBUG-38742 Change-Id: Ibdcef17f717f0a76caab54f65c550865df1ec78d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp')
-rw-r--r--tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp69
1 files changed, 68 insertions, 1 deletions
diff --git a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
index 329419c..4f85430 100644
--- a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
+++ b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
@@ -25,9 +25,11 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include <QRegularExpression>
#include <QString>
#include <QtTest>
#include <QtWebSockets/QWebSocket>
+#include <QtWebSockets/QWebSocketHandshakeOptions>
#include <QtWebSockets/QWebSocketServer>
#include <QtWebSockets/qwebsocketprotocol.h>
@@ -72,6 +74,8 @@ EchoServer::EchoServer(QObject *parent, quint64 maxAllowedIncomingMessageSize, q
m_maxAllowedIncomingFrameSize(maxAllowedIncomingFrameSize),
m_clients()
{
+ m_pWebSocketServer->setSupportedSubprotocols({ QStringLiteral("protocol1"),
+ QStringLiteral("protocol2") });
if (m_pWebSocketServer->listen(QHostAddress(QStringLiteral("127.0.0.1")))) {
connect(m_pWebSocketServer, SIGNAL(newConnection()),
this, SLOT(onNewConnection()));
@@ -146,7 +150,9 @@ private Q_SLOTS:
void tst_sendTextMessage();
void tst_sendBinaryMessage();
void tst_errorString();
+ void tst_openRequest_data();
void tst_openRequest();
+ void tst_protocolAccessor();
void tst_moveToThread();
void tst_moveToThreadNoWarning();
#ifndef QT_NO_NETWORKPROXY
@@ -631,8 +637,35 @@ void tst_QWebSocket::tst_errorString()
QCOMPARE(socket.errorString(), QStringLiteral("Host not found"));
}
+void tst_QWebSocket::tst_openRequest_data()
+{
+ QTest::addColumn<QStringList>("subprotocols");
+ QTest::addColumn<QString>("subprotocolHeader");
+ QTest::addColumn<QRegularExpression>("warningExpression");
+
+ QTest::addRow("no subprotocols") << QStringList{} << QString{} << QRegularExpression{};
+ QTest::addRow("single subprotocol") << QStringList{"foobar"} << QStringLiteral("foobar")
+ << QRegularExpression{};
+ QTest::addRow("multiple subprotocols") << QStringList{"foo", "bar"}
+ << QStringLiteral("foo, bar")
+ << QRegularExpression{};
+ QTest::addRow("subprotocol with whitespace")
+ << QStringList{"chat", "foo\r\nbar with space"}
+ << QStringLiteral("chat")
+ << QRegularExpression{".*invalid.*bar with space"};
+
+ QTest::addRow("subprotocol with invalid chars")
+ << QStringList{"chat", "foo{}"}
+ << QStringLiteral("chat")
+ << QRegularExpression{".*invalid.*foo"};
+}
+
void tst_QWebSocket::tst_openRequest()
{
+ QFETCH(QStringList, subprotocols);
+ QFETCH(QString, subprotocolHeader);
+ QFETCH(QRegularExpression, warningExpression);
+
EchoServer echoServer;
QWebSocket socket;
@@ -647,7 +680,13 @@ void tst_QWebSocket::tst_openRequest()
url.setQuery(query);
QNetworkRequest req(url);
req.setRawHeader("X-Custom-Header", "A custom header");
- socket.open(req);
+ QWebSocketHandshakeOptions options;
+ options.setSubprotocols(subprotocols);
+
+ if (!warningExpression.pattern().isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, warningExpression);
+
+ socket.open(req, options);
QTRY_COMPARE(socketConnectedSpy.count(), 1);
QTRY_COMPARE(serverRequestSpy.count(), 1);
@@ -656,6 +695,34 @@ void tst_QWebSocket::tst_openRequest()
QNetworkRequest requestConnected = arguments.at(0).value<QNetworkRequest>();
QCOMPARE(requestConnected.url(), req.url());
QCOMPARE(requestConnected.rawHeader("X-Custom-Header"), req.rawHeader("X-Custom-Header"));
+
+ if (subprotocols.isEmpty())
+ QVERIFY(!requestConnected.hasRawHeader("Sec-WebSocket-Protocol"));
+ else
+ QCOMPARE(requestConnected.rawHeader("Sec-WebSocket-Protocol"), subprotocolHeader);
+
+
+ socket.close();
+}
+
+void tst_QWebSocket::tst_protocolAccessor()
+{
+ EchoServer echoServer;
+
+ QWebSocket socket;
+
+ QUrl url = QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
+ QLatin1Char(':') + QString::number(echoServer.port()));
+
+ QWebSocketHandshakeOptions options;
+ options.setSubprotocols({ "foo", "protocol2" });
+
+ socket.open(url, options);
+
+ QTRY_COMPARE(socket.state(), QAbstractSocket::ConnectedState);
+
+ QCOMPARE(socket.subprotocol(), "protocol2");
+
socket.close();
}