diff options
author | Arno Rehn <a.rehn@menlosystems.com> | 2022-01-02 22:31:03 +0100 |
---|---|---|
committer | Arno Rehn <a.rehn@menlosystems.com> | 2022-03-30 17:45:18 +0200 |
commit | cc4c24b99a87629aeb60df5af96d9bb991b56635 (patch) | |
tree | 62459a42457b0680022bb1fcb759f9c4e64d2c4b /tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp | |
parent | 8545bb57efbfabf0dc7bc4b76efd6a99b4022669 (diff) | |
download | qtwebsockets-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.cpp | 69 |
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(); } |