diff options
author | Franck Dude <enstone83@gmail.com> | 2019-12-07 16:46:52 +0100 |
---|---|---|
committer | Franck Dude <enstone83@gmail.com> | 2019-12-13 20:09:40 +0100 |
commit | cea5603ee1a56bb5d177f35ed3f884345875099e (patch) | |
tree | c7c942c55fc767d8a3f3beed93dcea0bfb8b4b63 /src | |
parent | 92cec7af3ee88673d58e70e5b9a84a0cf55aa734 (diff) | |
download | qtwebsockets-cea5603ee1a56bb5d177f35ed3f884345875099e.tar.gz |
Fix websocket handshake request header parsing
Header ends with \r\n\r\n but there might be more data inside the
tcpbuffer
Never read past the header
Task-number: QTBUG-70000
Change-Id: If3d4cb362646e43a91faf00f89e50510ff00fa56
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/websockets/qwebsocket_p.cpp | 6 | ||||
-rw-r--r-- | src/websockets/qwebsocket_p.h | 2 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver_p.cpp | 33 |
3 files changed, 33 insertions, 8 deletions
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index 36aefd9..c9dbb1f 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -569,7 +569,7 @@ void QWebSocketPrivate::enableMasking(bool enable) /*! * \internal */ -void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket) +void QWebSocketPrivate::makeConnections(QTcpSocket *pTcpSocket) { Q_ASSERT(pTcpSocket); Q_Q(QWebSocket); @@ -636,6 +636,10 @@ void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket) &QWebSocketPrivate::processPong); QObjectPrivate::connect(&m_dataProcessor, &QWebSocketDataProcessor::closeReceived, this, &QWebSocketPrivate::processClose); + + //fire readyread, in case we already have data inside the tcpSocket + if (pTcpSocket->bytesAvailable()) + Q_EMIT pTcpSocket->readyRead(); } /*! diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h index e72daa5..1db1077 100644 --- a/src/websockets/qwebsocket_p.h +++ b/src/websockets/qwebsocket_p.h @@ -182,7 +182,7 @@ private: Q_REQUIRED_RESULT qint64 doWriteFrames(const QByteArray &data, bool isBinary); - void makeConnections(const QTcpSocket *pTcpSocket); + void makeConnections(QTcpSocket *pTcpSocket); void releaseConnections(const QTcpSocket *pTcpSocket); QByteArray getFrameHeader(QWebSocketProtocol::OpCode opCode, quint64 payloadLength, diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp index 8225b59..574adf5 100644 --- a/src/websockets/qwebsocketserver_p.cpp +++ b/src/websockets/qwebsocketserver_p.cpp @@ -430,9 +430,16 @@ void QWebSocketServerPrivate::handshakeReceived() //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502) // According to RFC822 the body is separated from the headers by a null line (CRLF) - if (!pTcpSocket->peek(pTcpSocket->bytesAvailable()).endsWith(QByteArrayLiteral("\r\n\r\n"))) { + const QByteArray& endOfHeaderMarker = QByteArrayLiteral("\r\n\r\n"); + + QByteArray header = pTcpSocket->peek(pTcpSocket->bytesAvailable()); + const int endOfHeaderIndex = header.indexOf(endOfHeaderMarker); + if (endOfHeaderIndex < 0) { + //then we don't have our header complete yet return; } + const int headerSize = endOfHeaderIndex + endOfHeaderMarker.size(); + disconnect(pTcpSocket, &QTcpSocket::readyRead, this, &QWebSocketServerPrivate::handshakeReceived); bool success = false; @@ -446,8 +453,20 @@ void QWebSocketServerPrivate::handshakeReceived() return; } + //don't read past the header + header.resize(headerSize); + //remove our header from the tcpSocket + qint64 skippedSize = pTcpSocket->skip(headerSize); + + if (skippedSize != headerSize) { + pTcpSocket->close(); + setError(QWebSocketProtocol::CloseCodeProtocolError, + QWebSocketServer::tr("Read handshake request header failed.")); + return; + } + QWebSocketHandshakeRequest request(pTcpSocket->peerPort(), isSecure); - QTextStream textStream(pTcpSocket); + QTextStream textStream(header, QIODevice::ReadOnly); request.readHandshake(textStream, MAX_HEADERLINE_LENGTH, MAX_HEADERLINES); if (request.isValid()) { @@ -501,11 +520,13 @@ void QWebSocketServerPrivate::handleConnection(QTcpSocket *pTcpSocket) const QObjectPrivate::connect(pTcpSocket, &QTcpSocket::readyRead, this, &QWebSocketServerPrivate::handshakeReceived, Qt::QueuedConnection); - if (pTcpSocket->canReadLine()) { - // We received some data! We must emit now to be sure that handshakeReceived is called - // since the data could have been received before the signal and slot was connected. - emit pTcpSocket->readyRead(); + + // We received some data! We must emit now to be sure that handshakeReceived is called + // since the data could have been received before the signal and slot was connected. + if (pTcpSocket->bytesAvailable()) { + Q_EMIT pTcpSocket->readyRead(); } + QObjectPrivate::connect(pTcpSocket, &QTcpSocket::disconnected, this, &QWebSocketServerPrivate::onSocketDisconnected); } |