aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-05 09:02:14 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-09-05 09:02:19 +0200
commit9f88317e29621451c18719abc5e22198b618471f (patch)
tree4259cf62f6b5343aeb1588ed19abeb7225dc8aee
parent034c5b8296119f6eb0046ae1276b7261872caa57 (diff)
parent36e4776fb5ac5506ab30cc96950aeb053c263ed2 (diff)
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
-rw-r--r--src/websockets/qwebsocket_p.cpp8
-rw-r--r--src/websockets/qwebsocket_p.h4
-rw-r--r--src/websockets/qwebsocketdataprocessor.cpp16
-rw-r--r--src/websockets/qwebsocketdataprocessor_p.h2
-rw-r--r--src/websockets/qwebsockethandshakeresponse.cpp9
-rw-r--r--src/websockets/qwebsocketserver.cpp2
-rw-r--r--tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp4
-rw-r--r--tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp28
8 files changed, 56 insertions, 17 deletions
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index 9b94d04..36aefd9 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -113,6 +113,7 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::
m_defaultMaskGenerator(),
m_handshakeState(NothingDoneState)
{
+ m_pingTimer.start();
}
/*!
@@ -144,6 +145,7 @@ QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol:
m_defaultMaskGenerator(),
m_handshakeState(NothingDoneState)
{
+ m_pingTimer.start();
}
/*!
@@ -1173,13 +1175,13 @@ void QWebSocketPrivate::processData()
{
if (!m_pSocket) // disconnected with data still in-bound
return;
- if (m_pSocket->bytesAvailable()) {
+ while (m_pSocket->bytesAvailable()) {
if (state() == QAbstractSocket::ConnectingState) {
if (!m_pSocket->canReadLine())
return;
processHandshake(m_pSocket);
- } else {
- m_dataProcessor.process(m_pSocket);
+ } else if (!m_dataProcessor.process(m_pSocket)) {
+ return;
}
}
}
diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h
index 4b39dfc..e72daa5 100644
--- a/src/websockets/qwebsocket_p.h
+++ b/src/websockets/qwebsocket_p.h
@@ -61,7 +61,7 @@
#include <QtNetwork/QSslError>
#include <QtNetwork/QSslSocket>
#endif
-#include <QtCore/QTime>
+#include <QtCore/QElapsedTimer>
#include <private/qobject_p.h>
#include "qwebsocket.h"
@@ -229,7 +229,7 @@ private:
QWebSocketProtocol::CloseCode m_closeCode;
QString m_closeReason;
- QTime m_pingTimer;
+ QElapsedTimer m_pingTimer;
QWebSocketDataProcessor m_dataProcessor;
QWebSocketConfiguration m_configuration;
diff --git a/src/websockets/qwebsocketdataprocessor.cpp b/src/websockets/qwebsocketdataprocessor.cpp
index 39287d4..191b992 100644
--- a/src/websockets/qwebsocketdataprocessor.cpp
+++ b/src/websockets/qwebsocketdataprocessor.cpp
@@ -123,8 +123,11 @@ quint64 QWebSocketDataProcessor::maxFrameSize()
/*!
\internal
+
+ Returns \c true if a complete websocket frame has been processed;
+ otherwise returns \c false.
*/
-void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
+bool QWebSocketDataProcessor::process(QIODevice *pIoDevice)
{
bool isDone = false;
@@ -135,7 +138,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
QObject::connect(pIoDevice, &QIODevice::readyRead,
&waitTimer, &QTimer::stop, Qt::UniqueConnection);
waitTimer.start();
- return;
+ return false;
} else if (Q_LIKELY(frame.isValid())) {
if (frame.isControlFrame()) {
isDone = processControlFrame(frame);
@@ -146,7 +149,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
Q_EMIT errorEncountered(QWebSocketProtocol::CloseCodeProtocolError,
tr("Received Continuation frame, while there is " \
"nothing to continue."));
- return;
+ return true;
}
if (Q_UNLIKELY(m_isFragmented && frame.isDataFrame() &&
!frame.isContinuationFrame())) {
@@ -154,7 +157,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
Q_EMIT errorEncountered(QWebSocketProtocol::CloseCodeProtocolError,
tr("All data frames after the initial data frame " \
"must have opcode 0 (continuation)."));
- return;
+ return true;
}
if (!frame.isContinuationFrame()) {
m_opCode = frame.opCode();
@@ -168,7 +171,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
clear();
Q_EMIT errorEncountered(QWebSocketProtocol::CloseCodeTooMuchData,
tr("Received message is too big."));
- return;
+ return true;
}
if (m_opCode == QWebSocketProtocol::OpCodeText) {
@@ -181,7 +184,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
clear();
Q_EMIT errorEncountered(QWebSocketProtocol::CloseCodeWrongDatatype,
tr("Invalid UTF-8 code encountered."));
- return;
+ return true;
} else {
m_textMessage.append(frameTxt);
Q_EMIT textFrameReceived(frameTxt, frame.isFinalFrame());
@@ -211,6 +214,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice)
}
frame.clear();
}
+ return true;
}
/*!
diff --git a/src/websockets/qwebsocketdataprocessor_p.h b/src/websockets/qwebsocketdataprocessor_p.h
index 41226d6..03635b1 100644
--- a/src/websockets/qwebsocketdataprocessor_p.h
+++ b/src/websockets/qwebsocketdataprocessor_p.h
@@ -88,7 +88,7 @@ Q_SIGNALS:
void errorEncountered(QWebSocketProtocol::CloseCode code, const QString &description);
public Q_SLOTS:
- void process(QIODevice *pIoDevice);
+ bool process(QIODevice *pIoDevice);
void clear();
private:
diff --git a/src/websockets/qwebsockethandshakeresponse.cpp b/src/websockets/qwebsockethandshakeresponse.cpp
index 383f1bf..d3ef609 100644
--- a/src/websockets/qwebsockethandshakeresponse.cpp
+++ b/src/websockets/qwebsockethandshakeresponse.cpp
@@ -162,13 +162,16 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(
if (request.isValid()) {
const QString acceptKey = calculateAcceptKey(request.key());
const QList<QString> matchingProtocols =
- listIntersection(supportedProtocols, request.protocols(), std::less<>());
+ listIntersection(supportedProtocols, request.protocols(),
+ std::less<QString>());
//TODO: extensions must be kept in the order in which they arrive
//cannot use set.intersect() to get the supported extensions
const QList<QString> matchingExtensions =
- listIntersection(supportedExtensions, request.extensions(), std::less<>());
+ listIntersection(supportedExtensions, request.extensions(),
+ std::less<QString>());
const QList<QWebSocketProtocol::Version> matchingVersions =
- listIntersection(supportedVersions, request.versions(), std::greater<>()); //sort in descending order
+ listIntersection(supportedVersions, request.versions(),
+ std::greater<QWebSocketProtocol::Version>()); //sort in descending order
if (Q_UNLIKELY(matchingVersions.isEmpty())) {
m_error = QWebSocketProtocol::CloseCodeProtocolError;
diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp
index 9717401..ecd9da8 100644
--- a/src/websockets/qwebsocketserver.cpp
+++ b/src/websockets/qwebsocketserver.cpp
@@ -359,6 +359,7 @@ int QWebSocketServer::maxPendingConnections() const
handshake their connection is closed.
\sa setHandshakeTimeout()
+ \since 5.14
*/
int QWebSocketServer::handshakeTimeout() const
{
@@ -599,6 +600,7 @@ void QWebSocketServer::setMaxPendingConnections(int numConnections)
negative value (e.g. -1) to disable the timeout.
\sa handshakeTimeout()
+ \since 5.14
*/
void QWebSocketServer::setHandshakeTimeout(int msec)
{
diff --git a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
index 19af815..71e1262 100644
--- a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
+++ b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
@@ -472,8 +472,8 @@ void tst_QWebSocket::tst_sendTextMessage()
QCOMPARE(urlConnected, url);
QCOMPARE(socket.bytesToWrite(), 0);
- // transmit a long text message with 64 kb
- QString longString(65536, 'a');
+ // transmit a long text message with 1 MB
+ QString longString(0x100000, 'a');
socket.sendTextMessage(longString);
QVERIFY(socket.bytesToWrite() > longString.length());
QVERIFY(textMessageReceived.wait());
diff --git a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
index 442196b..20d7060 100644
--- a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
+++ b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
@@ -116,6 +116,7 @@ private Q_SLOTS:
void tst_scheme(); // qtbug-55927
void tst_handleConnection();
void tst_handshakeTimeout(); // qtbug-63312, qtbug-57026
+ void multipleFrames();
private:
bool m_shouldSkipUnsupportedIpv6Test;
@@ -823,6 +824,33 @@ void tst_QWebSocketServer::tst_handshakeTimeout()
}
}
+void tst_QWebSocketServer::multipleFrames()
+{
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+ QSignalSpy serverConnectionSpy(&server, &QWebSocketServer::newConnection);
+ QVERIFY(server.listen());
+
+ QWebSocket socket;
+ QSignalSpy socketConnectedSpy(&socket, &QWebSocket::connected);
+ QSignalSpy messageReceivedSpy(&socket, &QWebSocket::binaryMessageReceived);
+ socket.open(server.serverUrl().toString());
+
+ QVERIFY(serverConnectionSpy.wait());
+ QVERIFY(socketConnectedSpy.wait());
+
+ auto serverSocket = std::unique_ptr<QWebSocket>(server.nextPendingConnection());
+ QVERIFY(serverSocket);
+ for (int i = 0; i < 10; i++)
+ serverSocket->sendBinaryMessage(QByteArray("abc"));
+ if (serverSocket->bytesToWrite())
+ QVERIFY(serverSocket->flush());
+
+ QVERIFY(messageReceivedSpy.wait());
+ // Since there's no guarantee the operating system will fit all 10 websocket frames into 1 tcp
+ // frame, let's just assume it will do at least 2. EXCEPT_FAIL any which doesn't merge any.
+ QVERIFY2(messageReceivedSpy.count() > 1, "Received only 1 message in the TCP frame!");
+}
+
QTEST_MAIN(tst_QWebSocketServer)
#include "tst_qwebsocketserver.moc"