summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/imports/imports.pro3
-rw-r--r--src/imports/qmlwebsockets/plugins.qmltypes4
-rw-r--r--src/imports/qmlwebsockets/qmldir2
-rw-r--r--src/imports/qmlwebsockets/qmlwebsockets.pro2
-rw-r--r--src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp5
-rw-r--r--src/imports/qmlwebsockets/qqmlwebsocket.cpp2
-rw-r--r--src/imports/qmlwebsockets/qqmlwebsocketserver.cpp2
-rw-r--r--src/imports/qmlwebsockets_compat/qmldir4
-rw-r--r--src/imports/qmlwebsockets_compat/qmlwebsockets_compat.pro7
-rw-r--r--src/websockets/doc/src/qtwebsockets-module.qdoc4
-rw-r--r--src/websockets/qwebsocket_p.cpp110
-rw-r--r--src/websockets/qwebsocket_p.h13
-rw-r--r--tests/auto/qwebsocket/tst_qwebsocket.cpp7
14 files changed, 113 insertions, 54 deletions
diff --git a/.qmake.conf b/.qmake.conf
index d6d6c20..76fcbdf 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -3,4 +3,4 @@ load(qt_build_config)
CONFIG += qt_example_installs
CONFIG += warning_clean
-MODULE_VERSION = 5.4.2
+MODULE_VERSION = 5.5.0
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 6bf8069..bb0d300 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
-SUBDIRS += qmlwebsockets
+SUBDIRS += qmlwebsockets \
+ qmlwebsockets_compat
diff --git a/src/imports/qmlwebsockets/plugins.qmltypes b/src/imports/qmlwebsockets/plugins.qmltypes
index 4404a51..5b8d1f9 100644
--- a/src/imports/qmlwebsockets/plugins.qmltypes
+++ b/src/imports/qmlwebsockets/plugins.qmltypes
@@ -4,13 +4,13 @@ import QtQuick.tooling 1.1
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -notrelocatable Qt.WebSockets 1.0'
+// 'qmlplugindump -notrelocatable QtWebSockets 1.0'
Module {
Component {
name: "QQmlWebSocket"
prototype: "QObject"
- exports: ["Qt.WebSockets/WebSocket 1.0"]
+ exports: ["QtWebSockets/WebSocket 1.0"]
exportMetaObjectRevisions: [0]
Enum {
name: "Status"
diff --git a/src/imports/qmlwebsockets/qmldir b/src/imports/qmlwebsockets/qmldir
index 3202976..130b79f 100644
--- a/src/imports/qmlwebsockets/qmldir
+++ b/src/imports/qmlwebsockets/qmldir
@@ -1,4 +1,4 @@
-module Qt.WebSockets
+module QtWebSockets
plugin declarative_qmlwebsockets
classname QtWebSocketsDeclarativeModule
typeinfo plugins.qmltypes
diff --git a/src/imports/qmlwebsockets/qmlwebsockets.pro b/src/imports/qmlwebsockets/qmlwebsockets.pro
index 58c6df0..dea84a8 100644
--- a/src/imports/qmlwebsockets/qmlwebsockets.pro
+++ b/src/imports/qmlwebsockets/qmlwebsockets.pro
@@ -1,6 +1,6 @@
QT = core websockets qml
-TARGETPATH = Qt/WebSockets
+TARGETPATH = QtWebSockets
HEADERS += qmlwebsockets_plugin.h \
qqmlwebsocket.h \
diff --git a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp
index fea105e..684d711 100644
--- a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp
+++ b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp
@@ -42,9 +42,10 @@ QT_BEGIN_NAMESPACE
void QtWebSocketsDeclarativeModule::registerTypes(const char *uri)
{
- Q_ASSERT(uri == QLatin1String("Qt.WebSockets"));
+ // ### Qt 6: Remove support for the "Qt.WebSockets" QML module.
+ Q_ASSERT(uri == QLatin1String("QtWebSockets") || uri == QLatin1String("Qt.WebSockets"));
- // @uri Qt.WebSockets
+ // @uri QtWebSockets
qmlRegisterType<QQmlWebSocket>(uri, 1 /*major*/, 0 /*minor*/, "WebSocket");
qmlRegisterType<QQmlWebSocketServer>(uri, 1 /*major*/, 0 /*minor*/, "WebSocketServer");
}
diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.cpp b/src/imports/qmlwebsockets/qqmlwebsocket.cpp
index 08d39f6..568f8ce 100644
--- a/src/imports/qmlwebsockets/qqmlwebsocket.cpp
+++ b/src/imports/qmlwebsockets/qqmlwebsocket.cpp
@@ -36,7 +36,7 @@
\instantiates QQmlWebSocket
\since 5.3
- \inqmlmodule Qt.WebSockets
+ \inqmlmodule QtWebSockets
\ingroup websockets-qml
\brief QML interface to QWebSocket.
diff --git a/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp b/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp
index 6425fe2..9c302ea 100644
--- a/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp
+++ b/src/imports/qmlwebsockets/qqmlwebsocketserver.cpp
@@ -41,7 +41,7 @@ QT_USE_NAMESPACE
\instantiates QQmlWebSocketServer
\since 5.3
- \inqmlmodule Qt.WebSockets
+ \inqmlmodule QtWebSockets
\ingroup websockets-qml
\brief QML interface to QWebSocketServer.
*/
diff --git a/src/imports/qmlwebsockets_compat/qmldir b/src/imports/qmlwebsockets_compat/qmldir
new file mode 100644
index 0000000..8541103
--- /dev/null
+++ b/src/imports/qmlwebsockets_compat/qmldir
@@ -0,0 +1,4 @@
+module Qt.WebSockets
+plugin ../../QtWebSockets/declarative_qmlwebsockets
+classname QtWebSocketsDeclarativeModule
+typeinfo ../../QtWebSockets/plugins.qmltypes
diff --git a/src/imports/qmlwebsockets_compat/qmlwebsockets_compat.pro b/src/imports/qmlwebsockets_compat/qmlwebsockets_compat.pro
new file mode 100644
index 0000000..a6610b6
--- /dev/null
+++ b/src/imports/qmlwebsockets_compat/qmlwebsockets_compat.pro
@@ -0,0 +1,7 @@
+### Qt 6: Remove support for the old "Qt.WebSockets" QML module.
+
+QT = core websockets qml
+
+TARGETPATH = Qt/WebSockets
+
+load(qml_module)
diff --git a/src/websockets/doc/src/qtwebsockets-module.qdoc b/src/websockets/doc/src/qtwebsockets-module.qdoc
index dc7009b..2c5892d 100644
--- a/src/websockets/doc/src/qtwebsockets-module.qdoc
+++ b/src/websockets/doc/src/qtwebsockets-module.qdoc
@@ -48,7 +48,7 @@
*/
/*!
- \qmlmodule Qt.WebSockets 1.0
+ \qmlmodule QtWebSockets 1.0
\title Qt WebSockets QML Types
\ingroup qmlmodules
\brief Provides QML types for WebSockets communication.
@@ -57,6 +57,6 @@
The QML types are accessed by using:
\code
- import Qt.WebSockets 1.0
+ import QtWebSockets 1.0
\endcode
*/
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index 45913e5..ab2fec5 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -137,7 +137,8 @@ QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol:
m_dataProcessor(),
m_configuration(),
m_pMaskGenerator(&m_defaultMaskGenerator),
- m_defaultMaskGenerator()
+ m_defaultMaskGenerator(),
+ m_handshakeState(NothingDoneState)
{
}
@@ -362,7 +363,7 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask)
if (!resourceName.endsWith(QChar::fromLatin1('?'))) {
resourceName.append(QChar::fromLatin1('?'));
}
- resourceName.append(url.query());
+ resourceName.append(url.query(QUrl::FullyEncoded));
}
if (resourceName.isEmpty())
resourceName = QStringLiteral("/");
@@ -898,46 +899,66 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket)
Q_Q(QWebSocket);
if (Q_UNLIKELY(!pSocket))
return;
+ // Reset handshake on a new connection.
+ if (m_handshakeState == AllDoneState)
+ m_handshakeState = NothingDoneState;
- bool ok = false;
QString errorDescription;
- const QByteArray statusLine = pSocket->readLine();
- int httpMajorVersion, httpMinorVersion;
- int httpStatusCode;
- QString httpStatusMessage;
- if (Q_UNLIKELY(!parseStatusLine(statusLine, &httpMajorVersion, &httpMinorVersion,
- &httpStatusCode, &httpStatusMessage))) {
- errorDescription = QWebSocket::tr("Invalid statusline in response: %1.").arg(QString::fromLatin1(statusLine));
- } else {
- QString headerLine = readLine(pSocket);
- QMap<QString, QString> headers;
- while (!headerLine.isEmpty()) {
+ switch (m_handshakeState) {
+ case NothingDoneState:
+ m_headers.clear();
+ m_handshakeState = ReadingStatusState;
+ // no break
+ case ReadingStatusState:
+ if (!pSocket->canReadLine())
+ return;
+ m_statusLine = pSocket->readLine();
+ if (Q_UNLIKELY(!parseStatusLine(m_statusLine, &m_httpMajorVersion, &m_httpMinorVersion, &m_httpStatusCode, &m_httpStatusMessage))) {
+ errorDescription = QWebSocket::tr("Invalid statusline in response: %1.").arg(QString::fromLatin1(m_statusLine));
+ break;
+ }
+ m_handshakeState = ReadingHeaderState;
+ // no break
+ case ReadingHeaderState:
+ while (pSocket->canReadLine()) {
+ QString headerLine = readLine(pSocket);
const QStringList headerField = headerLine.split(QStringLiteral(": "),
QString::SkipEmptyParts);
if (headerField.size() == 2) {
- headers.insertMulti(headerField[0].toLower(), headerField[1]);
+ m_headers.insertMulti(headerField[0].toLower(), headerField[1]);
+ }
+ if (headerField.isEmpty()) {
+ m_handshakeState = ParsingHeaderState;
+ break;
}
- headerLine = readLine(pSocket);
}
- const QString acceptKey = headers.value(QStringLiteral("sec-websocket-accept"),
- QString());
- const QString upgrade = headers.value(QStringLiteral("upgrade"), QString());
- const QString connection = headers.value(QStringLiteral("connection"), QString());
+ if (m_handshakeState != ParsingHeaderState) {
+ if (pSocket->atEnd()) {
+ errorDescription = QWebSocket::tr("QWebSocketPrivate::processHandshake: Connection closed while reading header.");
+ break;
+ }
+ return;
+ }
+ // no break
+ case ParsingHeaderState: {
+ const QString acceptKey = m_headers.value(QStringLiteral("sec-websocket-accept"), QString());
+ const QString upgrade = m_headers.value(QStringLiteral("upgrade"), QString());
+ const QString connection = m_headers.value(QStringLiteral("connection"), QString());
// unused for the moment
-// const QString extensions = headers.value(QStringLiteral("sec-websocket-extensions"),
+// const QString extensions = m_headers.value(QStringLiteral("sec-websocket-extensions"),
// QString());
-// const QString protocol = headers.value(QStringLiteral("sec-websocket-protocol"),
+// const QString protocol = m_headers.value(QStringLiteral("sec-websocket-protocol"),
// QString());
- const QString version = headers.value(QStringLiteral("sec-websocket-version"),
- QString());
+ const QString version = m_headers.value(QStringLiteral("sec-websocket-version"), QString());
- if (Q_LIKELY(httpStatusCode == 101)) {
+ bool ok = false;
+ if (Q_LIKELY(m_httpStatusCode == 101)) {
//HTTP/x.y 101 Switching Protocols
//TODO: do not check the httpStatusText right now
ok = !(acceptKey.isEmpty() ||
- (httpMajorVersion < 1 || httpMinorVersion < 1) ||
+ (m_httpMajorVersion < 1 || m_httpMinorVersion < 1) ||
(upgrade.toLower() != QStringLiteral("websocket")) ||
(connection.toLower() != QStringLiteral("upgrade")));
if (ok) {
@@ -950,9 +971,9 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket)
} else {
errorDescription =
QWebSocket::tr("QWebSocketPrivate::processHandshake: Invalid statusline in response: %1.")
- .arg(QString::fromLatin1(statusLine));
+ .arg(QString::fromLatin1(m_statusLine));
}
- } else if (httpStatusCode == 400) {
+ } else if (m_httpStatusCode == 400) {
//HTTP/1.1 400 Bad Request
if (!version.isEmpty()) {
const QStringList versions = version.split(QStringLiteral(", "),
@@ -963,29 +984,38 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket)
errorDescription =
QWebSocket::tr("Handshake: Server requests a version that we don't support: %1.")
.arg(versions.join(QStringLiteral(", ")));
- ok = false;
} else {
//we tried v13, but something different went wrong
errorDescription =
QWebSocket::tr("QWebSocketPrivate::processHandshake: Unknown error condition encountered. Aborting connection.");
- ok = false;
}
+ } else {
+ errorDescription =
+ QWebSocket::tr("QWebSocketPrivate::processHandshake: Unknown error condition encountered. Aborting connection.");
}
} else {
errorDescription =
QWebSocket::tr("QWebSocketPrivate::processHandshake: Unhandled http status code: %1 (%2).")
- .arg(httpStatusCode).arg(httpStatusMessage);
- ok = false;
+ .arg(m_httpStatusCode).arg(m_httpStatusMessage);
}
+ if (ok)
+ m_handshakeState = AllDoneState;
+ break;
+ }
+ case AllDoneState:
+ Q_UNREACHABLE();
+ break;
+ }
- if (!ok) {
- setErrorString(errorDescription);
- Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
- } else {
- //handshake succeeded
- setSocketState(QAbstractSocket::ConnectedState);
- Q_EMIT q->connected();
- }
+ if (m_handshakeState == AllDoneState) {
+ // handshake succeeded
+ setSocketState(QAbstractSocket::ConnectedState);
+ Q_EMIT q->connected();
+ } else {
+ // handshake failed
+ m_handshakeState = AllDoneState;
+ setErrorString(errorDescription);
+ Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
}
}
diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h
index f13e08d..9d4ba1c 100644
--- a/src/websockets/qwebsocket_p.h
+++ b/src/websockets/qwebsocket_p.h
@@ -224,6 +224,19 @@ private:
QMaskGenerator *m_pMaskGenerator;
QDefaultMaskGenerator m_defaultMaskGenerator;
+ enum HandshakeState {
+ NothingDoneState,
+ ReadingStatusState,
+ ReadingHeaderState,
+ ParsingHeaderState,
+ AllDoneState
+ } m_handshakeState;
+ QByteArray m_statusLine;
+ int m_httpStatusCode;
+ int m_httpMajorVersion, m_httpMinorVersion;
+ QString m_httpStatusMessage;
+ QMap<QString, QString> m_headers;
+
friend class QWebSocketServerPrivate;
};
diff --git a/tests/auto/qwebsocket/tst_qwebsocket.cpp b/tests/auto/qwebsocket/tst_qwebsocket.cpp
index 29ba7a3..537aa31 100644
--- a/tests/auto/qwebsocket/tst_qwebsocket.cpp
+++ b/tests/auto/qwebsocket/tst_qwebsocket.cpp
@@ -413,8 +413,11 @@ void tst_QWebSocket::tst_sendTextMessage()
QSignalSpy binaryMessageReceived(&socket, SIGNAL(binaryMessageReceived(QByteArray)));
QSignalSpy binaryFrameReceived(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool)));
- socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
- QStringLiteral(":") + QString::number(echoServer.port())));
+ QUrl url = QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() +
+ QStringLiteral(":") + QString::number(echoServer.port()));
+ url.addQueryItem("queryitem", "with encoded characters");
+
+ socket.open(url);
if (socketConnectedSpy.count() == 0)
QVERIFY(socketConnectedSpy.wait(500));