diff options
20 files changed, 530 insertions, 366 deletions
diff --git a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp index c8d2cd6..6664e59 100644 --- a/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp +++ b/src/imports/qmlwebsockets/qmlwebsockets_plugin.cpp @@ -43,6 +43,8 @@ #include <QtQml> +QT_BEGIN_NAMESPACE + void QmlWebsocket_plugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("Qt.WebSockets")); @@ -50,3 +52,5 @@ void QmlWebsocket_plugin::registerTypes(const char *uri) // @uri Qt.WebSockets qmlRegisterType<QQmlWebSocket>(uri, 1 /*major*/, 0 /*minor*/, "WebSocket"); } + +QT_END_NAMESPACE diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.cpp b/src/imports/qmlwebsockets/qqmlwebsocket.cpp index 9d2ce7f..3483d75 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.cpp +++ b/src/imports/qmlwebsockets/qqmlwebsocket.cpp @@ -59,6 +59,8 @@ #include "qqmlwebsocket.h" #include <QtWebSockets/QWebSocket> +QT_BEGIN_NAMESPACE + QQmlWebSocket::QQmlWebSocket(QObject *parent) : QObject(parent), m_webSocket(), @@ -74,14 +76,14 @@ QQmlWebSocket::~QQmlWebSocket() { } -void QQmlWebSocket::sendTextMessage(const QString &message) +qint64 QQmlWebSocket::sendTextMessage(const QString &message) { if (m_status != Open) { setErrorString(tr("Messages can only be send when the socket has Open status.")); setStatus(Error); - return; + return 0; } - m_webSocket->write(message); + return m_webSocket->write(message); } QUrl QQmlWebSocket::url() const @@ -123,14 +125,16 @@ void QQmlWebSocket::classBegin() void QQmlWebSocket::componentComplete() { - m_webSocket.reset(new QWebSocket()); - connect(m_webSocket.data(), SIGNAL(textMessageReceived(QString)), this, SIGNAL(textMessageReceived(QString))); - connect(m_webSocket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); - connect(m_webSocket.data(), SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState))); + m_webSocket.reset(new (std::nothrow) QWebSocket()); + if (Q_LIKELY(m_webSocket)) { + connect(m_webSocket.data(), SIGNAL(textMessageReceived(QString)), this, SIGNAL(textMessageReceived(QString))); + connect(m_webSocket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); + connect(m_webSocket.data(), SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState))); - m_componentCompleted = true; + m_componentCompleted = true; - open(); + open(); + } } void QQmlWebSocket::onError(QAbstractSocket::SocketError error) @@ -210,14 +214,14 @@ bool QQmlWebSocket::isActive() const void QQmlWebSocket::open() { - if (m_componentCompleted && m_isActive && m_url.isValid() && m_webSocket) { + if (m_componentCompleted && m_isActive && m_url.isValid() && Q_LIKELY(m_webSocket)) { m_webSocket->open(m_url); } } void QQmlWebSocket::close() { - if (m_componentCompleted && m_webSocket) { + if (m_componentCompleted && Q_LIKELY(m_webSocket)) { m_webSocket->close(); } } @@ -230,3 +234,5 @@ void QQmlWebSocket::setErrorString(QString errorString) m_errorString = errorString; Q_EMIT errorStringChanged(m_errorString); } + +QT_END_NAMESPACE diff --git a/src/imports/qmlwebsockets/qqmlwebsocket.h b/src/imports/qmlwebsockets/qqmlwebsocket.h index 47cf6fa..b9d7769 100644 --- a/src/imports/qmlwebsockets/qqmlwebsocket.h +++ b/src/imports/qmlwebsockets/qqmlwebsocket.h @@ -48,6 +48,8 @@ #include <QScopedPointer> #include <QWebSocket> +QT_BEGIN_NAMESPACE + class QQmlWebSocket : public QObject, public QQmlParserStatus { Q_OBJECT @@ -81,8 +83,7 @@ public: void setActive(bool active); bool isActive() const; -public Q_SLOTS: - void sendTextMessage(const QString &message); + Q_INVOKABLE qint64 sendTextMessage(const QString &message); Q_SIGNALS: @@ -114,4 +115,6 @@ private: void setErrorString(QString errorString = QString()); }; +QT_END_NAMESPACE + #endif // QQMLWEBSOCKET_H diff --git a/src/websockets/qsslserver_p.cpp b/src/websockets/qsslserver_p.cpp index 550c511..009922c 100644 --- a/src/websockets/qsslserver_p.cpp +++ b/src/websockets/qsslserver_p.cpp @@ -70,18 +70,20 @@ void QSslServer::incomingConnection(qintptr socket) { QSslSocket *pSslSocket = new QSslSocket(); - pSslSocket->setSslConfiguration(m_sslConfiguration); + if (Q_LIKELY(pSslSocket)) { + pSslSocket->setSslConfiguration(m_sslConfiguration); - if (pSslSocket->setSocketDescriptor(socket)) { - connect(pSslSocket, SIGNAL(peerVerifyError(QSslError)), this, SIGNAL(peerVerifyError(QSslError))); - connect(pSslSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SIGNAL(sslErrors(QList<QSslError>))); - connect(pSslSocket, SIGNAL(encrypted()), this, SIGNAL(newEncryptedConnection())); + if (Q_LIKELY(pSslSocket->setSocketDescriptor(socket))) { + connect(pSslSocket, SIGNAL(peerVerifyError(QSslError)), this, SIGNAL(peerVerifyError(QSslError))); + connect(pSslSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SIGNAL(sslErrors(QList<QSslError>))); + connect(pSslSocket, SIGNAL(encrypted()), this, SIGNAL(newEncryptedConnection())); - addPendingConnection(pSslSocket); + addPendingConnection(pSslSocket); - pSslSocket->startServerEncryption(); - } else { - delete pSslSocket; + pSslSocket->startServerEncryption(); + } else { + delete pSslSocket; + } } } diff --git a/src/websockets/qwebsocket.h b/src/websockets/qwebsocket.h index 8a6369a..40e1e9a 100644 --- a/src/websockets/qwebsocket.h +++ b/src/websockets/qwebsocket.h @@ -65,7 +65,9 @@ class Q_WEBSOCKETS_EXPORT QWebSocket : public QObject Q_DECLARE_PRIVATE(QWebSocket) public: - explicit QWebSocket(const QString &origin = QString(), QWebSocketProtocol::Version version = QWebSocketProtocol::V_LATEST, QObject *parent = Q_NULLPTR); + explicit QWebSocket(const QString &origin = QString(), + QWebSocketProtocol::Version version = QWebSocketProtocol::V_LATEST, + QObject *parent = Q_NULLPTR); virtual ~QWebSocket(); void abort(); diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index d605617..39a2481 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -170,7 +170,7 @@ void QWebSocketPrivate::abort() QAbstractSocket::SocketError QWebSocketPrivate::error() const { QAbstractSocket::SocketError err = QAbstractSocket::OperationError; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { err = m_pSocket->error(); } return err; @@ -196,7 +196,7 @@ QString QWebSocketPrivate::errorString() const bool QWebSocketPrivate::flush() { bool result = true; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { result = m_pSocket->flush(); } return result; @@ -207,9 +207,7 @@ bool QWebSocketPrivate::flush() */ qint64 QWebSocketPrivate::write(const char *message) { - //TODO: create a QByteArray from message, and directly call doWriteFrames - //now the data is converted to a string, and then converted back to a bytearray - return write(QString::fromUtf8(message)); + return doWriteFrames(QByteArray::fromRawData(message, qstrlen(message)), false); } /*! @@ -217,9 +215,7 @@ qint64 QWebSocketPrivate::write(const char *message) */ qint64 QWebSocketPrivate::write(const char *message, qint64 maxSize) { - //TODO: create a QByteArray from message, and directly call doWriteFrames - //now the data is converted to a string, and then converted back to a bytearray - return write(QString::fromUtf8(message, static_cast<int>(maxSize))); + return write(QByteArray::fromRawData(message, maxSize), false); } /*! @@ -269,9 +265,9 @@ void QWebSocketPrivate::ignoreSslErrors(const QList<QSslError> &errors) void QWebSocketPrivate::ignoreSslErrors() { m_configuration.m_ignoreSslErrors = true; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { QSslSocket *pSslSocket = qobject_cast<QSslSocket *>(m_pSocket.data()); - if (pSslSocket) { + if (Q_LIKELY(pSslSocket)) { pSslSocket->ignoreSslErrors(); } } @@ -289,13 +285,15 @@ QWebSocket *QWebSocketPrivate::upgradeFrom(QTcpSocket *pTcpSocket, QObject *parent) { QWebSocket *pWebSocket = new QWebSocket(pTcpSocket, response.acceptedVersion(), parent); - pWebSocket->d_func()->setExtension(response.acceptedExtension()); - pWebSocket->d_func()->setOrigin(request.origin()); - pWebSocket->d_func()->setRequestUrl(request.requestUrl()); - pWebSocket->d_func()->setProtocol(response.acceptedProtocol()); - pWebSocket->d_func()->setResourceName(request.requestUrl().toString(QUrl::RemoveUserInfo)); - //a server should not send masked frames - pWebSocket->d_func()->enableMasking(false); + if (Q_LIKELY(pWebSocket)) { + pWebSocket->d_func()->setExtension(response.acceptedExtension()); + pWebSocket->d_func()->setOrigin(request.origin()); + pWebSocket->d_func()->setRequestUrl(request.requestUrl()); + pWebSocket->d_func()->setProtocol(response.acceptedProtocol()); + pWebSocket->d_func()->setResourceName(request.requestUrl().toString(QUrl::RemoveUserInfo)); + //a server should not send masked frames + pWebSocket->d_func()->enableMasking(false); + } return pWebSocket; } @@ -305,7 +303,7 @@ QWebSocket *QWebSocketPrivate::upgradeFrom(QTcpSocket *pTcpSocket, */ void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString reason) { - if (!m_pSocket) { + if (Q_UNLIKELY(!m_pSocket)) { return; } if (!m_isClosingHandshakeSent) { @@ -347,7 +345,7 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask) pTcpSocket->deleteLater(); } //if (m_url != url) - if (!m_pSocket) { + if (Q_LIKELY(!m_pSocket)) { Q_Q(QWebSocket); m_dataProcessor.clear(); @@ -377,34 +375,50 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask) } else { QSslSocket *sslSocket = new QSslSocket(this); m_pSocket.reset(sslSocket); - - makeConnections(m_pSocket.data()); - connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); - setSocketState(QAbstractSocket::ConnectingState); - - sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration); - if (m_configuration.m_ignoreSslErrors) { - sslSocket->ignoreSslErrors(); + if (Q_LIKELY(m_pSocket)) { + m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); + m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); + + makeConnections(m_pSocket.data()); + connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); + setSocketState(QAbstractSocket::ConnectingState); + + sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration); + if (Q_UNLIKELY(m_configuration.m_ignoreSslErrors)) { + sslSocket->ignoreSslErrors(); + } else { + sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors); + } + #ifndef QT_NO_NETWORKPROXY + sslSocket->setProxy(m_configuration.m_proxy); + #endif + sslSocket->connectToHostEncrypted(url.host(), url.port(443)); } else { - sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors); + const QString message = tr("Out of memory."); + setErrorString(message); + emit q->error(QAbstractSocket::SocketResourceError); } -#ifndef QT_NO_NETWORKPROXY - sslSocket->setProxy(m_configuration.m_proxy); -#endif - sslSocket->connectToHostEncrypted(url.host(), url.port(443)); } } else #endif if (url.scheme() == QStringLiteral("ws")) { m_pSocket.reset(new QTcpSocket(this)); + if (Q_LIKELY(m_pSocket)) { + m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); + m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); - makeConnections(m_pSocket.data()); - connect(m_pSocket.data(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); - setSocketState(QAbstractSocket::ConnectingState); -#ifndef QT_NO_NETWORKPROXY - m_pSocket->setProxy(m_configuration.m_proxy); -#endif - m_pSocket->connectToHost(url.host(), url.port(80)); + makeConnections(m_pSocket.data()); + connect(m_pSocket.data(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); + setSocketState(QAbstractSocket::ConnectingState); + #ifndef QT_NO_NETWORKPROXY + m_pSocket->setProxy(m_configuration.m_proxy); + #endif + m_pSocket->connectToHost(url.host(), url.port(80)); + } else { + const QString message = tr("Out of memory."); + setErrorString(message); + emit q->error(QAbstractSocket::SocketResourceError); + } } else { const QString message = tr("Unsupported websockets scheme: %1").arg(url.scheme()); setErrorString(message); @@ -424,7 +438,7 @@ void QWebSocketPrivate::ping(QByteArray payload) m_pingTimer.restart(); QByteArray pingFrame = getFrameHeader(QWebSocketProtocol::OC_PING, payload.size(), 0 /*do not mask*/, true); pingFrame.append(payload); - writeFrame(pingFrame); + (void)writeFrame(pingFrame); } /*! @@ -507,7 +521,7 @@ void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket) Q_ASSERT(pTcpSocket); Q_Q(QWebSocket); - if (pTcpSocket) { + if (Q_LIKELY(pTcpSocket)) { //pass through signals connect(pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), q, SIGNAL(error(QAbstractSocket::SocketError))); connect(pTcpSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), q, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *))); @@ -535,7 +549,7 @@ void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket) */ void QWebSocketPrivate::releaseConnections(const QTcpSocket *pTcpSocket) { - if (pTcpSocket) { + if (Q_LIKELY(pTcpSocket)) { disconnect(pTcpSocket); } disconnect(&m_dataProcessor); @@ -614,7 +628,7 @@ QByteArray QWebSocketPrivate::getFrameHeader(QWebSocketProtocol::OpCode opCode, quint8 byte = 0x00; bool ok = payloadLength <= 0x7FFFFFFFFFFFFFFFULL; - if (ok) { + if (Q_LIKELY(ok)) { //FIN, RSV1-3, opcode byte = static_cast<quint8>((opCode & 0x0F) | (lastFrame ? 0x80 : 0x00)); //FIN, opcode //RSV-1, RSV-2 and RSV-3 are zero @@ -657,7 +671,7 @@ QByteArray QWebSocketPrivate::getFrameHeader(QWebSocketProtocol::OpCode opCode, qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary) { qint64 payloadWritten = 0; - if (!m_pSocket) { + if (Q_UNLIKELY(!m_pSocket)) { return payloadWritten; } Q_Q(QWebSocket); @@ -666,16 +680,15 @@ qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary) int numFrames = data.size() / FRAME_SIZE_IN_BYTES; QByteArray tmpData(data); - //TODO: really necessary? tmpData.detach(); char *payload = tmpData.data(); quint64 sizeLeft = quint64(data.size()) % FRAME_SIZE_IN_BYTES; - if (sizeLeft) { + if (Q_LIKELY(sizeLeft)) { ++numFrames; } //catch the case where the payload is zero bytes; //in this case, we still need to send a frame - if (numFrames == 0) { + if (Q_UNLIKELY(numFrames == 0)) { numFrames = 1; } quint64 currentPosition = 0; @@ -698,13 +711,13 @@ qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary) bytesWritten += m_pSocket->write(getFrameHeader(opcode, size, maskingKey, isLastFrame)); //write payload - if (size > 0) { + if (Q_LIKELY(size > 0)) { char *currentData = payload + currentPosition; if (m_mustMask) { QWebSocketProtocol::mask(currentData, size, maskingKey); } qint64 written = m_pSocket->write(currentData, static_cast<qint64>(size)); - if (written > 0) { + if (Q_LIKELY(written > 0)) { bytesWritten += written; payloadWritten += written; } else { @@ -717,7 +730,7 @@ qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary) currentPosition += size; bytesLeft -= size; } - if (payloadWritten != data.size()) { + if (Q_UNLIKELY(payloadWritten != data.size())) { setErrorString(tr("Bytes written %1 != %2.").arg(payloadWritten).arg(data.size())); Q_EMIT q->error(QAbstractSocket::NetworkError); } @@ -759,11 +772,11 @@ QByteArray QWebSocketPrivate::generateKey() const /*! \internal */ -QString QWebSocketPrivate::calculateAcceptKey(const QString &key) const +QString QWebSocketPrivate::calculateAcceptKey(const QByteArray &key) const { - const QString tmpKey = key % QStringLiteral("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - const QByteArray hash = QCryptographicHash::hash(tmpKey.toLatin1(), QCryptographicHash::Sha1); - return QString::fromLatin1(hash.toBase64()); + const QByteArray tmpKey = key + QByteArrayLiteral("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + const QByteArray hash = QCryptographicHash::hash(tmpKey, QCryptographicHash::Sha1).toBase64(); + return QString::fromLatin1(hash); } /*! @@ -772,7 +785,7 @@ QString QWebSocketPrivate::calculateAcceptKey(const QString &key) const qint64 QWebSocketPrivate::writeFrames(const QList<QByteArray> &frames) { qint64 written = 0; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { QList<QByteArray>::const_iterator it; for (it = frames.cbegin(); it < frames.cend(); ++it) { written += writeFrame(*it); @@ -787,7 +800,7 @@ qint64 QWebSocketPrivate::writeFrames(const QList<QByteArray> &frames) qint64 QWebSocketPrivate::writeFrame(const QByteArray &frame) { qint64 written = 0; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { written = m_pSocket->write(frame); } return written; @@ -800,15 +813,13 @@ QString readLine(QTcpSocket *pSocket) { Q_ASSERT(pSocket); QString line; - if (pSocket) { - char c; - while (pSocket->getChar(&c)) { - if (c == char('\r')) { - pSocket->getChar(&c); - break; - } else { - line.append(QChar::fromLatin1(c)); - } + char c; + while (pSocket->getChar(&c)) { + if (c == char('\r')) { + pSocket->getChar(&c); + break; + } else { + line.append(QChar::fromLatin1(c)); } } return line; @@ -835,7 +846,7 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket) int httpStatusCode; QString httpStatusMessage; const QRegularExpressionMatch match = regExp.match(statusLine); - if (match.hasMatch()) { + if (Q_LIKELY(match.hasMatch())) { QStringList tokens = match.capturedTexts(); tokens.removeFirst(); //remove the search string if (tokens.length() == 3) { @@ -845,7 +856,7 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket) ok = true; } } - if (!ok) { + if (Q_UNLIKELY(!ok)) { errorDescription = tr("Invalid statusline in response: %1.").arg(statusLine); } else { QString headerLine = readLine(pSocket); @@ -864,7 +875,7 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket) //const QString protocol = headers.value(QStringLiteral("Sec-WebSocket-Protocol"), QStringLiteral("")); const QString version = headers.value(QStringLiteral("Sec-WebSocket-Version"), QStringLiteral("")); - if (httpStatusCode == 101) { + if (Q_LIKELY(httpStatusCode == 101)) { //HTTP/x.y 101 Switching Protocols bool conversionOk = false; const float version = httpProtocol.midRef(5).toFloat(&conversionOk); @@ -874,7 +885,7 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket) (upgrade.toLower() != QStringLiteral("websocket")) || (connection.toLower() != QStringLiteral("upgrade"))); if (ok) { - const QString accept = calculateAcceptKey(QString::fromLatin1(m_key)); + const QString accept = calculateAcceptKey(m_key); ok = (accept == acceptKey); if (!ok) { errorDescription = tr("Accept-Key received from server %1 does not match the client key %2.").arg(acceptKey).arg(accept); @@ -1070,7 +1081,7 @@ QAbstractSocket::SocketState QWebSocketPrivate::state() const bool QWebSocketPrivate::waitForConnected(int msecs) { bool result = false; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { result = m_pSocket->waitForConnected(msecs); } return result; @@ -1082,7 +1093,7 @@ bool QWebSocketPrivate::waitForConnected(int msecs) bool QWebSocketPrivate::waitForDisconnected(int msecs) { bool result = false; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { result = m_pSocket->waitForDisconnected(msecs); } return result; @@ -1116,7 +1127,7 @@ void QWebSocketPrivate::setErrorString(const QString &errorString) QHostAddress QWebSocketPrivate::localAddress() const { QHostAddress address; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { address = m_pSocket->localAddress(); } return address; @@ -1128,7 +1139,7 @@ QHostAddress QWebSocketPrivate::localAddress() const quint16 QWebSocketPrivate::localPort() const { quint16 port = 0; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { port = m_pSocket->localPort(); } return port; @@ -1140,7 +1151,7 @@ quint16 QWebSocketPrivate::localPort() const QAbstractSocket::PauseModes QWebSocketPrivate::pauseMode() const { QAbstractSocket::PauseModes mode = QAbstractSocket::PauseNever; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { mode = m_pSocket->pauseMode(); } return mode; @@ -1152,7 +1163,7 @@ QAbstractSocket::PauseModes QWebSocketPrivate::pauseMode() const QHostAddress QWebSocketPrivate::peerAddress() const { QHostAddress address; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { address = m_pSocket->peerAddress(); } return address; @@ -1164,7 +1175,7 @@ QHostAddress QWebSocketPrivate::peerAddress() const QString QWebSocketPrivate::peerName() const { QString name; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { name = m_pSocket->peerName(); } return name; @@ -1176,7 +1187,7 @@ QString QWebSocketPrivate::peerName() const quint16 QWebSocketPrivate::peerPort() const { quint16 port = 0; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { port = m_pSocket->peerPort(); } return port; @@ -1208,7 +1219,7 @@ void QWebSocketPrivate::setProxy(const QNetworkProxy &networkProxy) qint64 QWebSocketPrivate::readBufferSize() const { qint64 size = 0; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { size = m_pSocket->readBufferSize(); } return size; @@ -1219,7 +1230,7 @@ qint64 QWebSocketPrivate::readBufferSize() const */ void QWebSocketPrivate::resume() { - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { m_pSocket->resume(); } } @@ -1229,7 +1240,7 @@ void QWebSocketPrivate::resume() */ void QWebSocketPrivate::setPauseMode(QAbstractSocket::PauseModes pauseMode) { - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { m_pSocket->setPauseMode(pauseMode); } } @@ -1239,7 +1250,7 @@ void QWebSocketPrivate::setPauseMode(QAbstractSocket::PauseModes pauseMode) */ void QWebSocketPrivate::setReadBufferSize(qint64 size) { - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { m_pSocket->setReadBufferSize(size); } } @@ -1249,7 +1260,7 @@ void QWebSocketPrivate::setReadBufferSize(qint64 size) */ void QWebSocketPrivate::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value) { - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { m_pSocket->setSocketOption(option, value); } } @@ -1260,7 +1271,7 @@ void QWebSocketPrivate::setSocketOption(QAbstractSocket::SocketOption option, co QVariant QWebSocketPrivate::socketOption(QAbstractSocket::SocketOption option) { QVariant val; - if (m_pSocket) { + if (Q_LIKELY(m_pSocket)) { val = m_pSocket->socketOption(option); } return val; diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h index e21c274..d9fc612 100644 --- a/src/websockets/qwebsocket_p.h +++ b/src/websockets/qwebsocket_p.h @@ -142,10 +142,10 @@ public: QWebSocketProtocol::CloseCode closeCode() const; QString closeReason() const; - qint64 write(const char *message); //send data as text - qint64 write(const char *message, qint64 maxSize); //send data as text - qint64 write(const QString &message); //send data as text - qint64 write(const QByteArray &data); //send data as binary + qint64 write(const char *message) Q_REQUIRED_RESULT; + qint64 write(const char *message, qint64 maxSize) Q_REQUIRED_RESULT; + qint64 write(const QString &message) Q_REQUIRED_RESULT; + qint64 write(const QByteArray &data) Q_REQUIRED_RESULT; //send data as binary #ifndef QT_NO_SSL void ignoreSslErrors(const QList<QSslError> &errors); @@ -184,13 +184,13 @@ private: void setSocketState(QAbstractSocket::SocketState state); void setErrorString(const QString &errorString); - qint64 doWriteFrames(const QByteArray &data, bool isBinary); + qint64 doWriteFrames(const QByteArray &data, bool isBinary) Q_REQUIRED_RESULT; void makeConnections(const QTcpSocket *pTcpSocket); void releaseConnections(const QTcpSocket *pTcpSocket); QByteArray getFrameHeader(QWebSocketProtocol::OpCode opCode, quint64 payloadLength, quint32 maskingKey, bool lastFrame); - QString calculateAcceptKey(const QString &key) const; + QString calculateAcceptKey(const QByteArray &key) const; QString createHandShakeRequest(QString resourceName, QString host, QString origin, @@ -201,13 +201,13 @@ private: static QWebSocket *upgradeFrom(QTcpSocket *tcpSocket, const QWebSocketHandshakeRequest &request, const QWebSocketHandshakeResponse &response, - QObject *parent = Q_NULLPTR); + QObject *parent = Q_NULLPTR) Q_REQUIRED_RESULT; quint32 generateMaskingKey() const; QByteArray generateKey() const; quint32 generateRandomNumber() const; - qint64 writeFrames(const QList<QByteArray> &frames); - qint64 writeFrame(const QByteArray &frame); + qint64 writeFrames(const QList<QByteArray> &frames) Q_REQUIRED_RESULT; + qint64 writeFrame(const QByteArray &frame) Q_REQUIRED_RESULT; QScopedPointer<QTcpSocket> m_pSocket; QString m_errorString; diff --git a/src/websockets/qwebsocketcorsauthenticator.cpp b/src/websockets/qwebsocketcorsauthenticator.cpp index af9f5a1..dd0c0ec 100644 --- a/src/websockets/qwebsocketcorsauthenticator.cpp +++ b/src/websockets/qwebsocketcorsauthenticator.cpp @@ -109,8 +109,7 @@ QWebSocketCorsAuthenticator::QWebSocketCorsAuthenticator(const QWebSocketCorsAut QWebSocketCorsAuthenticator &QWebSocketCorsAuthenticator::operator =(const QWebSocketCorsAuthenticator &other) { Q_D(QWebSocketCorsAuthenticator); - if (this != &other) - { + if (this != &other) { d->m_origin = other.d_ptr->m_origin; d->m_isAllowed = other.d_ptr->m_isAllowed; } diff --git a/src/websockets/qwebsocketdataprocessor_p.cpp b/src/websockets/qwebsocketdataprocessor_p.cpp index 340e84b..1b3c8c3 100644 --- a/src/websockets/qwebsocketdataprocessor_p.cpp +++ b/src/websockets/qwebsocketdataprocessor_p.cpp @@ -124,17 +124,17 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice) while (!isDone) { QWebSocketFrame frame = QWebSocketFrame::readFrame(pIoDevice); - if (frame.isValid()) { + if (Q_LIKELY(frame.isValid())) { if (frame.isControlFrame()) { isDone = processControlFrame(frame); } else { //we have a dataframe; opcode can be OC_CONTINUE, OC_TEXT or OC_BINARY - if (!m_isFragmented && frame.isContinuationFrame()) { + if (Q_UNLIKELY(!m_isFragmented && frame.isContinuationFrame())) { clear(); Q_EMIT errorEncountered(QWebSocketProtocol::CC_PROTOCOL_ERROR, tr("Received Continuation frame, while there is nothing to continue.")); return; } - if (m_isFragmented && frame.isDataFrame() && !frame.isContinuationFrame()) { + if (Q_UNLIKELY(m_isFragmented && frame.isDataFrame() && !frame.isContinuationFrame())) { clear(); Q_EMIT errorEncountered(QWebSocketProtocol::CC_PROTOCOL_ERROR, tr("All data frames after the initial data frame must have opcode 0 (continuation).")); return; @@ -144,7 +144,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice) m_isFragmented = !frame.isFinalFrame(); } quint64 messageLength = (quint64)(m_opCode == QWebSocketProtocol::OC_TEXT) ? m_textMessage.length() : m_binaryMessage.length(); - if ((messageLength + quint64(frame.payload().length())) > MAX_MESSAGE_SIZE_IN_BYTES) { + if (Q_UNLIKELY((messageLength + quint64(frame.payload().length())) > MAX_MESSAGE_SIZE_IN_BYTES)) { clear(); Q_EMIT errorEncountered(QWebSocketProtocol::CC_TOO_MUCH_DATA, tr("Received message is too big.")); return; @@ -153,7 +153,7 @@ void QWebSocketDataProcessor::process(QIODevice *pIoDevice) if (m_opCode == QWebSocketProtocol::OC_TEXT) { QString frameTxt = m_pTextCodec->toUnicode(frame.payload().constData(), frame.payload().size(), m_pConverterState); bool failed = (m_pConverterState->invalidChars != 0) || (frame.isFinalFrame() && (m_pConverterState->remainingChars != 0)); - if (failed) { + if (Q_UNLIKELY(failed)) { clear(); Q_EMIT errorEncountered(QWebSocketProtocol::CC_WRONG_DATATYPE, tr("Invalid UTF-8 code encountered.")); return; @@ -233,14 +233,14 @@ bool QWebSocketDataProcessor::processControlFrame(const QWebSocketFrame &frame) quint16 closeCode = QWebSocketProtocol::CC_NORMAL; QString closeReason; QByteArray payload = frame.payload(); - if (payload.size() == 1) { + if (Q_UNLIKELY(payload.size() == 1)) { //size is either 0 (no close code and no reason) or >= 2 (at least a close code of 2 bytes) closeCode = QWebSocketProtocol::CC_PROTOCOL_ERROR; closeReason = tr("Payload of close frame is too small."); - } else if (payload.size() > 1) { + } else if (Q_LIKELY(payload.size() > 1)) { //close frame can have a close code and reason closeCode = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(payload.constData())); - if (!QWebSocketProtocol::isCloseCodeValid(closeCode)) { + if (Q_UNLIKELY(!QWebSocketProtocol::isCloseCodeValid(closeCode))) { closeCode = QWebSocketProtocol::CC_PROTOCOL_ERROR; closeReason = tr("Invalid close code %1 detected.").arg(closeCode); } else { @@ -249,7 +249,7 @@ bool QWebSocketDataProcessor::processControlFrame(const QWebSocketFrame &frame) QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull); closeReason = tc->toUnicode(payload.constData() + 2, payload.size() - 2, &state); const bool failed = (state.invalidChars != 0) || (state.remainingChars != 0); - if (failed) { + if (Q_UNLIKELY(failed)) { closeCode = QWebSocketProtocol::CC_WRONG_DATATYPE; closeReason = tr("Invalid UTF-8 code encountered."); } diff --git a/src/websockets/qwebsocketframe_p.cpp b/src/websockets/qwebsocketframe_p.cpp index 4c9947f..c075e9e 100644 --- a/src/websockets/qwebsocketframe_p.cpp +++ b/src/websockets/qwebsocketframe_p.cpp @@ -345,7 +345,7 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) } case PS_READ_HEADER: { - if (pIoDevice->bytesAvailable() >= 2) { + if (Q_LIKELY(pIoDevice->bytesAvailable() >= 2)) { //FIN, RSV1-3, Opcode char header[2] = {0}; bytesRead = pIoDevice->read(header, 2); @@ -389,15 +389,15 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) case PS_READ_PAYLOAD_LENGTH: { - if (pIoDevice->bytesAvailable() >= 2) { + if (Q_LIKELY(pIoDevice->bytesAvailable() >= 2)) { uchar length[2] = {0}; bytesRead = pIoDevice->read(reinterpret_cast<char *>(length), 2); - if (bytesRead == -1) { + if (Q_UNLIKELY(bytesRead == -1)) { frame.setError(QWebSocketProtocol::CC_GOING_AWAY, QObject::tr("Error occurred while reading from the network: %1").arg(pIoDevice->errorString())); processingState = PS_DISPATCH_RESULT; } else { payloadLength = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(length)); - if (payloadLength < 126) { + if (Q_UNLIKELY(payloadLength < 126)) { //see http://tools.ietf.org/html/rfc6455#page-28 paragraph 5.2 //"in all cases, the minimal number of bytes MUST be used to encode //the length, for example, the length of a 124-byte-long string @@ -416,17 +416,19 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) case PS_READ_BIG_PAYLOAD_LENGTH: { - if (pIoDevice->bytesAvailable() >= 8) { + if (Q_LIKELY(pIoDevice->bytesAvailable() >= 8)) { uchar length[8] = {0}; bytesRead = pIoDevice->read(reinterpret_cast<char *>(length), 8); - if (bytesRead < 8) { + if (Q_UNLIKELY(bytesRead < 8)) { frame.setError(QWebSocketProtocol::CC_ABNORMAL_DISCONNECTION, QObject::tr("Something went wrong during reading from the network.")); processingState = PS_DISPATCH_RESULT; } else { //Most significant bit must be set to 0 as per http://tools.ietf.org/html/rfc6455#section-5.2 - //We don't check for that. We just strip off the highest bit - payloadLength = qFromBigEndian<quint64>(length) & ~(1ULL << 63); - if (payloadLength <= 0xFFFFu) { + payloadLength = qFromBigEndian<quint64>(length); + if (Q_UNLIKELY(payloadLength & (quint64(1) << 63))) { + frame.setError(QWebSocketProtocol::CC_PROTOCOL_ERROR, QObject::tr("Highest bit of payload length is not 0.")); + processingState = PS_DISPATCH_RESULT; + } else if (Q_UNLIKELY(payloadLength <= 0xFFFFu)) { //see http://tools.ietf.org/html/rfc6455#page-28 paragraph 5.2 //"in all cases, the minimal number of bytes MUST be used to encode //the length, for example, the length of a 124-byte-long string @@ -446,7 +448,7 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) case PS_READ_MASK: { - if (pIoDevice->bytesAvailable() >= 4) { + if (Q_LIKELY(pIoDevice->bytesAvailable() >= 4)) { bytesRead = pIoDevice->read(reinterpret_cast<char *>(&frame.m_mask), sizeof(frame.m_mask)); if (bytesRead == -1) { frame.setError(QWebSocketProtocol::CC_GOING_AWAY, QObject::tr("Error while reading from the network: %1.").arg(pIoDevice->errorString())); @@ -465,7 +467,7 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) { if (!payloadLength) { processingState = PS_DISPATCH_RESULT; - } else if (payloadLength > MAX_FRAME_SIZE_IN_BYTES) { + } else if (Q_UNLIKELY(payloadLength > MAX_FRAME_SIZE_IN_BYTES)) { frame.setError(QWebSocketProtocol::CC_TOO_MUCH_DATA, QObject::tr("Maximum framesize exceeded.")); processingState = PS_DISPATCH_RESULT; } else { @@ -473,7 +475,7 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice) if (bytesAvailable >= payloadLength) { frame.m_payload = pIoDevice->read(payloadLength); //payloadLength can be safely cast to an integer, as the MAX_FRAME_SIZE_IN_BYTES = MAX_INT - if (frame.m_payload.length() != int(payloadLength)) { + if (Q_UNLIKELY(frame.m_payload.length() != int(payloadLength))) { //some error occurred; refer to the Qt documentation of QIODevice::read() frame.setError(QWebSocketProtocol::CC_ABNORMAL_DISCONNECTION, QObject::tr("Some serious error occurred while reading from the network.")); processingState = PS_DISPATCH_RESULT; @@ -530,14 +532,14 @@ bool QWebSocketFrame::checkValidity() if (isValid()) { return true; } - if (m_rsv1 || m_rsv2 || m_rsv3) { + if (Q_UNLIKELY(m_rsv1 || m_rsv2 || m_rsv3)) { setError(QWebSocketProtocol::CC_PROTOCOL_ERROR, QObject::tr("Rsv field is non-zero")); - } else if (QWebSocketProtocol::isOpCodeReserved(m_opCode)) { + } else if (Q_UNLIKELY(QWebSocketProtocol::isOpCodeReserved(m_opCode))) { setError(QWebSocketProtocol::CC_PROTOCOL_ERROR, QObject::tr("Used reserved opcode")); } else if (isControlFrame()) { - if (m_length > 125) { + if (Q_UNLIKELY(m_length > 125)) { setError(QWebSocketProtocol::CC_PROTOCOL_ERROR, QObject::tr("Controle frame is larger than 125 bytes")); - } else if (!m_isFinalFrame) { + } else if (Q_UNLIKELY(!m_isFinalFrame)) { setError(QWebSocketProtocol::CC_PROTOCOL_ERROR, QObject::tr("Controle frames cannot be fragmented")); } else { m_isValid = true; diff --git a/src/websockets/qwebsockethandshakerequest_p.cpp b/src/websockets/qwebsockethandshakerequest_p.cpp index 79ab9a8..2b557df 100644 --- a/src/websockets/qwebsockethandshakerequest_p.cpp +++ b/src/websockets/qwebsockethandshakerequest_p.cpp @@ -196,12 +196,12 @@ QTextStream &QWebSocketHandshakeRequest::readFromStream(QTextStream &textStream) { m_isValid = false; clear(); - if (textStream.status() != QTextStream::Ok) { + if (Q_UNLIKELY(textStream.status() != QTextStream::Ok)) { return textStream; } const QString requestLine = textStream.readLine(); const QStringList tokens = requestLine.split(' ', QString::SkipEmptyParts); - if (tokens.length() < 3) { + if (Q_UNLIKELY(tokens.length() < 3)) { m_isValid = false; clear(); return textStream; @@ -212,7 +212,7 @@ QTextStream &QWebSocketHandshakeRequest::readFromStream(QTextStream &textStream) bool conversionOk = false; const float httpVersion = httpProtocol.midRef(5).toFloat(&conversionOk); - if (!conversionOk) { + if (Q_UNLIKELY(!conversionOk)) { clear(); m_isValid = false; return textStream; @@ -221,7 +221,7 @@ QTextStream &QWebSocketHandshakeRequest::readFromStream(QTextStream &textStream) m_headers.clear(); while (!headerLine.isEmpty()) { const QStringList headerField = headerLine.split(QStringLiteral(": "), QString::SkipEmptyParts); - if (headerField.length() < 2) { + if (Q_UNLIKELY(headerField.length() < 2)) { clear(); return textStream; } @@ -293,7 +293,7 @@ QTextStream &QWebSocketHandshakeRequest::readFromStream(QTextStream &textStream) (!conversionOk || (httpVersion < 1.1f)) || (upgrade.toLower() != QStringLiteral("websocket")) || (!connectionValues.contains(QStringLiteral("upgrade"), Qt::CaseInsensitive))); - if (!m_isValid) { + if (Q_UNLIKELY(!m_isValid)) { clear(); } return textStream; diff --git a/src/websockets/qwebsockethandshakeresponse_p.cpp b/src/websockets/qwebsockethandshakeresponse_p.cpp index a554640..4831a78 100644 --- a/src/websockets/qwebsockethandshakeresponse_p.cpp +++ b/src/websockets/qwebsockethandshakeresponse_p.cpp @@ -150,7 +150,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(const QWebSocketHandsh QList<QWebSocketProtocol::Version> matchingVersions = request.versions().toSet().intersect(supportedVersions.toSet()).toList(); std::sort(matchingVersions.begin(), matchingVersions.end(), std::greater<QWebSocketProtocol::Version>()); //sort in descending order - if (matchingVersions.isEmpty()) { + if (Q_UNLIKELY(matchingVersions.isEmpty())) { m_error = QWebSocketProtocol::CC_PROTOCOL_ERROR; m_errorString = tr("Unsupported version requested."); m_canUpgrade = false; @@ -186,7 +186,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(const QWebSocketHandsh m_errorString = tr("Bad handshake request received."); m_canUpgrade = false; } - if (!m_canUpgrade) { + if (Q_UNLIKELY(!m_canUpgrade)) { response << QStringLiteral("HTTP/1.1 400 Bad Request"); QStringList versions; Q_FOREACH (QWebSocketProtocol::Version version, supportedVersions) { @@ -204,7 +204,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(const QWebSocketHandsh */ QTextStream &QWebSocketHandshakeResponse::writeToStream(QTextStream &textStream) const { - if (!m_response.isEmpty()) { + if (Q_LIKELY(!m_response.isEmpty())) { textStream << m_response.toLatin1().constData(); } else { textStream.setStatus(QTextStream::WriteFailed); diff --git a/src/websockets/qwebsocketprotocol_p.cpp b/src/websockets/qwebsocketprotocol_p.cpp index 98d7b6f..ab51dd8 100644 --- a/src/websockets/qwebsocketprotocol_p.cpp +++ b/src/websockets/qwebsocketprotocol_p.cpp @@ -140,7 +140,7 @@ Version versionFromString(const QString &versionString) const int ver = versionString.toInt(&ok); QSet<Version> supportedVersions; supportedVersions << V_0 << V_4 << V_5 << V_6 << V_7 << V_8 << V_13; - if (ok) { + if (Q_LIKELY(ok)) { if (supportedVersions.contains(static_cast<Version>(ver))) { version = static_cast<Version>(ver); } diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp index b20e2f6..d60d6b1 100644 --- a/src/websockets/qwebsocketserver.cpp +++ b/src/websockets/qwebsocketserver.cpp @@ -425,8 +425,8 @@ QHostAddress QWebSocketServer::serverAddress() const */ QWebSocketServer::SecureMode QWebSocketServer::secureMode() const { - Q_D(const QWebSocketServer); #ifndef QT_NO_SSL + Q_D(const QWebSocketServer); return (d->secureMode() == QWebSocketServerPrivate::SECURE_MODE) ? QWebSocketServer::SECURE_MODE : QWebSocketServer::NON_SECURE_MODE; #else diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp index d59966d..d8533fc 100644 --- a/src/websockets/qwebsocketserver_p.cpp +++ b/src/websockets/qwebsocketserver_p.cpp @@ -74,15 +74,20 @@ QWebSocketServerPrivate::QWebSocketServerPrivate(const QString &serverName, QWeb Q_ASSERT(pWebSocketServer); if (m_secureMode == NON_SECURE_MODE) { m_pTcpServer = new QTcpServer(this); - connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection())); - } else - { + if (Q_LIKELY(m_pTcpServer)) { + connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection())); + } else { + qFatal("Could not allocate memory for tcp server."); + } + } else { #ifndef QT_NO_SSL QSslServer *pSslServer = new QSslServer(this); m_pTcpServer = pSslServer; - connect(pSslServer, SIGNAL(newEncryptedConnection()), this, SLOT(onNewConnection())); - connect(pSslServer, SIGNAL(peerVerifyError(QSslError)), q_ptr, SIGNAL(peerVerifyError(QSslError))); - connect(pSslServer, SIGNAL(sslErrors(QList<QSslError>)), q_ptr, SIGNAL(sslErrors(QList<QSslError>))); + if (Q_LIKELY(m_pTcpServer)) { + connect(pSslServer, SIGNAL(newEncryptedConnection()), this, SLOT(onNewConnection())); + connect(pSslServer, SIGNAL(peerVerifyError(QSslError)), q_ptr, SIGNAL(peerVerifyError(QSslError))); + connect(pSslServer, SIGNAL(sslErrors(QList<QSslError>)), q_ptr, SIGNAL(sslErrors(QList<QSslError>))); + } #else qFatal("SSL not supported on this platform."); #endif @@ -176,7 +181,7 @@ void QWebSocketServerPrivate::addPendingConnection(QWebSocket *pWebSocket) QWebSocket *QWebSocketServerPrivate::nextPendingConnection() { QWebSocket *pWebSocket = Q_NULLPTR; - if (!m_pendingConnections.isEmpty()) { + if (Q_LIKELY(!m_pendingConnections.isEmpty())) { pWebSocket = m_pendingConnections.dequeue(); } return pWebSocket; @@ -286,7 +291,7 @@ QList<QWebSocketProtocol::Version> QWebSocketServerPrivate::supportedVersions() */ QStringList QWebSocketServerPrivate::supportedProtocols() const { - QList<QString> supportedProtocols; + QStringList supportedProtocols; return supportedProtocols; //no protocols are currently supported } @@ -295,7 +300,7 @@ QStringList QWebSocketServerPrivate::supportedProtocols() const */ QStringList QWebSocketServerPrivate::supportedExtensions() const { - QList<QString> supportedExtensions; + QStringList supportedExtensions; return supportedExtensions; //no extensions are currently supported } @@ -370,7 +375,7 @@ void QWebSocketServerPrivate::onNewConnection() void QWebSocketServerPrivate::onCloseConnection() { QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(sender()); - if (pTcpSocket) { + if (Q_LIKELY(pTcpSocket)) { pTcpSocket->close(); } } @@ -382,7 +387,7 @@ void QWebSocketServerPrivate::handshakeReceived() { Q_Q(QWebSocketServer); QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(sender()); - if (pTcpSocket) { + if (Q_LIKELY(pTcpSocket)) { bool success = false; bool isSecure = false; diff --git a/tests/auto/dataprocessor/tst_dataprocessor.cpp b/tests/auto/dataprocessor/tst_dataprocessor.cpp index f8c3f77..f99a569 100644 --- a/tests/auto/dataprocessor/tst_dataprocessor.cpp +++ b/tests/auto/dataprocessor/tst_dataprocessor.cpp @@ -47,6 +47,7 @@ #include "private/qwebsocketdataprocessor_p.h" #include "private/qwebsocketprotocol_p.h" +#include "QtWebSockets/qwebsocketprotocol.h" const quint8 FIN = 0x80; const quint8 RSV1 = 0x40; @@ -98,7 +99,11 @@ private Q_SLOTS: void goodCloseFrame(); void goodCloseFrame_data(); - //void goodHeaders(); //test all valid opcodes + /*! + * \brief Test all valid opcodes + */ + void goodOpcodes(); + void goodOpcodes_data(); /*! Tests the QWebSocketDataProcessor for the correct handling of non-charactercodes @@ -226,11 +231,14 @@ void tst_DataProcessor::goodBinaryFrame_data() QTest::addColumn<QByteArray>("payload"); for (int i = 0; i < (65536 + 256); i += 128) //be sure to get small (< 126 bytes), large (> 125 bytes & < 64K) and big (>64K) frames { - QTest::newRow(QString("Binary frame with %1 bytes").arg(i).toStdString().data()) << QByteArray(i, char(1)); + QTest::newRow(QStringLiteral("Binary frame with %1 bytes").arg(i).toLatin1().constData()) + << QByteArray(i, char(1)); } for (int i = 0; i < 256; ++i) //test all possible bytes in the payload { - QTest::newRow(QString("Binary frame containing byte: '0x%1'").arg(QByteArray(1, char(i)).toHex().constData()).toStdString().data()) << QByteArray(i, char(1)); + QTest::newRow(QStringLiteral("Binary frame containing byte: '0x%1'") + .arg(QByteArray(1, char(i)).toHex().constData()).toLatin1().constData()) + << QByteArray(i, char(1)); } } @@ -296,19 +304,23 @@ void tst_DataProcessor::goodTextFrame_data() //test frames with small (< 126), large ( < 65536) and big ( > 65535) payloads for (int i = 0; i < (65536 + 256); i += 128) { - QTest::newRow(QString("Text frame with %1 ASCII characters").arg(i).toStdString().data()) << QByteArray(i, 'a') << i; + QTest::newRow(QStringLiteral("Text frame with %1 ASCII characters").arg(i).toLatin1().constData()) + << QByteArray(i, 'a') << i; } //test all valid ASCII characters for (int i = 0; i < 128; ++i) { - QTest::newRow(QString("Text frame with containing ASCII character '0x%1'").arg(QByteArray(1, char(i)).toHex().constData()).toStdString().data()) << QByteArray(1, char(i)) << 1; + QTest::newRow(QStringLiteral("Text frame with containing ASCII character '0x%1'") + .arg(QByteArray(1, char(i)).toHex().constData()).toLatin1().constData()) + << QByteArray(1, char(i)) << 1; } - //UC 6.2 //the text string reads: Text frame containing Hello-µ@ßöäüàá-UTF-8!! //Visual Studio doesn't like UTF-8 in source code, so we use escape codes for the string //The number 22 refers to the length of the string; the length was incorrectly calculated on Visual Studio - QTest::newRow(QStringLiteral("Text frame containing Hello-\xC2\xB5\x40\xC3\x9F\xC3\xB6\xC3\xA4\xC3\xBC\xC3\xA0\xC3\xA1-UTF-8!!").toStdString().data()) << QByteArray::fromHex("48656c6c6f2dc2b540c39fc3b6c3a4c3bcc3a0c3a12d5554462d382121") << 22; + QTest::newRow(QStringLiteral("Text frame containing Hello-\xC2\xB5\x40\xC3\x9F\xC3\xB6\xC3\xA4\xC3\xBC\xC3\xA0\xC3\xA1-UTF-8!!").toLatin1().constData()) + << QByteArray::fromHex("48656c6c6f2dc2b540c39fc3b6c3a4c3bcc3a0c3a12d5554462d382121") + << 22; } void tst_DataProcessor::goodTextFrame() @@ -424,11 +436,14 @@ void tst_DataProcessor::goodCloseFrame_data() //control frame data cannot exceed 125 bytes; smaller than 124, because we also need a 2 byte close code for (int i = 0; i < 124; ++i) { - QTest::newRow(QString("Close frame with %1 ASCII characters").arg(i).toStdString().data()) << QString(i, 'a') << QWebSocketProtocol::CC_NORMAL; + QTest::newRow(QStringLiteral("Close frame with %1 ASCII characters").arg(i).toLatin1().constData()) + << QString(i, 'a') << QWebSocketProtocol::CC_NORMAL; } for (int i = 0; i < 126; ++i) { - QTest::newRow(QString("Text frame with containing ASCII character '0x%1'").arg(QByteArray(1, char(i)).toHex().constData()).toStdString().data()) << QString(1, char(i)) << QWebSocketProtocol::CC_NORMAL; + QTest::newRow(QStringLiteral("Text frame with containing ASCII character '0x%1'") + .arg(QByteArray(1, char(i)).toHex().constData()).toLatin1().constData()) + << QString(1, char(i)) << QWebSocketProtocol::CC_NORMAL; } QTest::newRow("Close frame with close code NORMAL") << QString(1, 'a') << QWebSocketProtocol::CC_NORMAL; QTest::newRow("Close frame with close code BAD OPERATION") << QString(1, 'a') << QWebSocketProtocol::CC_BAD_OPERATION; @@ -462,6 +477,53 @@ void tst_DataProcessor::goodCloseFrame_data() QTest::newRow("Close frame with no close code and no reason") << QString() << QWebSocketProtocol::CloseCode(0); } +void tst_DataProcessor::goodOpcodes_data() +{ + QTest::addColumn<QWebSocketProtocol::OpCode>("opCode"); + + QTest::newRow("Frame with PING opcode") << QWebSocketProtocol::OC_PING; + QTest::newRow("Frame with PONG opcode") << QWebSocketProtocol::OC_PONG; + QTest::newRow("Frame with TEXT opcode") << QWebSocketProtocol::OC_TEXT; + QTest::newRow("Frame with BINARY opcode") << QWebSocketProtocol::OC_BINARY; + QTest::newRow("Frame with CLOSE opcode") << QWebSocketProtocol::OC_CLOSE; +} + +void tst_DataProcessor::goodOpcodes() +{ + QByteArray data; + QBuffer buffer; + QWebSocketDataProcessor dataProcessor; + QFETCH(QWebSocketProtocol::OpCode, opCode); + + data.append((char)(FIN | opCode)); + data.append(char(0)); //zero length + + buffer.setData(data); + buffer.open(QIODevice::ReadOnly); + + QSignalSpy errorReceivedSpy(&dataProcessor, SIGNAL(errorEncountered(QWebSocketProtocol::CloseCode,QString))); + QSignalSpy closeReceivedSpy(&dataProcessor, SIGNAL(closeReceived(QWebSocketProtocol::CloseCode,QString))); + QSignalSpy pingReceivedSpy(&dataProcessor, SIGNAL(pingReceived(QByteArray))); + QSignalSpy pongReceivedSpy(&dataProcessor, SIGNAL(pongReceived(QByteArray))); + QSignalSpy textFrameReceivedSpy(&dataProcessor, SIGNAL(textFrameReceived(QString,bool))); + QSignalSpy textMessageReceivedSpy(&dataProcessor, SIGNAL(textMessageReceived(QString))); + QSignalSpy binaryFrameReceivedSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool))); + QSignalSpy binaryMessageReceivedSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray))); + + dataProcessor.process(&buffer); + + QCOMPARE(errorReceivedSpy.count(), 0); + QCOMPARE(pingReceivedSpy.count(), opCode == QWebSocketProtocol::OC_PING ? 1 : 0); + QCOMPARE(pongReceivedSpy.count(), opCode == QWebSocketProtocol::OC_PONG ? 1 : 0); + QCOMPARE(closeReceivedSpy.count(), opCode == QWebSocketProtocol::OC_CLOSE ? 1 : 0); + QCOMPARE(textFrameReceivedSpy.count(), opCode == QWebSocketProtocol::OC_TEXT ? 1 : 0); + QCOMPARE(textMessageReceivedSpy.count(), opCode == QWebSocketProtocol::OC_TEXT ? 1 : 0); + QCOMPARE(binaryFrameReceivedSpy.count(), opCode == QWebSocketProtocol::OC_BINARY ? 1 : 0); + QCOMPARE(binaryMessageReceivedSpy.count(), opCode == QWebSocketProtocol::OC_BINARY ? 1 : 0); + + buffer.close(); +} + void tst_DataProcessor::goodCloseFrame() { QByteArray data; @@ -857,18 +919,41 @@ void tst_DataProcessor::invalidControlFrame_data() QTest::newRow("Close control frame with payload size 126") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << quint8(126) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(126) + << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Ping control frame with payload size 126") - << quint8(FIN | QWebSocketProtocol::OC_PING) << quint8(126) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_PING) + << quint8(126) + << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Close control frame with payload size 126") - << quint8(FIN | QWebSocketProtocol::OC_PONG) << quint8(126) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_PONG) + << quint8(126) + << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Non-final close control frame (fragmented)") - << quint8(QWebSocketProtocol::OC_CLOSE) << quint8(32) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(QWebSocketProtocol::OC_CLOSE) + << quint8(32) + << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Non-final ping control frame (fragmented)") - << quint8(QWebSocketProtocol::OC_PING) << quint8(32) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(QWebSocketProtocol::OC_PING) + << quint8(32) << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Non-final pong control frame (fragmented)") - << quint8(QWebSocketProtocol::OC_PONG) << quint8(32) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(QWebSocketProtocol::OC_PONG) + << quint8(32) + << QByteArray() + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; } void tst_DataProcessor::invalidControlFrame() @@ -885,123 +970,127 @@ void tst_DataProcessor::invalidCloseFrame_data() QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode"); QTest::newRow("Close control frame with payload size 1") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << quint8(1) << QByteArray(1, 'a') << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(1) + << QByteArray(1, 'a') + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; quint16 swapped = qToBigEndian<quint16>(QWebSocketProtocol::CC_ABNORMAL_DISCONNECTION); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); //Not allowed per RFC 6455 (see para 7.4.1) QTest::newRow("Close control frame close code ABNORMAL DISCONNECTION") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(QWebSocketProtocol::CC_MISSING_STATUS_CODE); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); //Not allowed per RFC 6455 (see para 7.4.1) QTest::newRow("Close control frame close code MISSING STATUS CODE") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(1004); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 1004") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(QWebSocketProtocol::CC_TLS_HANDSHAKE_FAILED); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); //Not allowed per RFC 6455 (see para 7.4.1) QTest::newRow("Close control frame close code TLS HANDSHAKE FAILED") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(0); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 0") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(999); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 999") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(1012); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 1012") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(1013); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 1013") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(1014); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 1014") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(1100); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 1100") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(2000); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 2000") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(2999); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 2999") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(5000); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 5000") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; swapped = qToBigEndian<quint16>(65535u); wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped)); QTest::newRow("Close control frame close code 65535") - << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << - quint8(2) << - QByteArray(wireRepresentation, 2) << - false << - QWebSocketProtocol::CC_PROTOCOL_ERROR; + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(2) + << QByteArray(wireRepresentation, 2) + << false + << QWebSocketProtocol::CC_PROTOCOL_ERROR; } void tst_DataProcessor::invalidCloseFrame() @@ -1243,15 +1332,11 @@ void tst_DataProcessor::incompleteSizeField_data() QTest::addColumn<bool>("isContinuationFrame"); QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode"); - ////////////////////////////////////////////////////////////////////////////////////////////////// //for a frame length value of 126, there should be 2 bytes following to form a 16-bit frame length - ////////////////////////////////////////////////////////////////////////////////////////////////// insertIncompleteSizeFieldTest(126, 0); insertIncompleteSizeFieldTest(126, 1); - ////////////////////////////////////////////////////////////////////////////////////////////////// //for a frame length value of 127, there should be 8 bytes following to form a 64-bit frame length - ////////////////////////////////////////////////////////////////////////////////////////////////// insertIncompleteSizeFieldTest(127, 0); insertIncompleteSizeFieldTest(127, 1); insertIncompleteSizeFieldTest(127, 2); @@ -1351,82 +1436,82 @@ QString tst_DataProcessor::opCodeToString(quint8 opCode) { case QWebSocketProtocol::OC_BINARY: { - frameType = "Binary"; + frameType = QStringLiteral("Binary"); break; } case QWebSocketProtocol::OC_TEXT: { - frameType = "Text"; + frameType = QStringLiteral("Text"); break; } case QWebSocketProtocol::OC_PING: { - frameType = "Ping"; + frameType = QStringLiteral("Ping"); break; } case QWebSocketProtocol::OC_PONG: { - frameType = "Pong"; + frameType = QStringLiteral("Pong"); break; } case QWebSocketProtocol::OC_CLOSE: { - frameType = "Close"; + frameType = QStringLiteral("Close"); break; } case QWebSocketProtocol::OC_CONTINUE: { - frameType = "Continuation"; + frameType = QStringLiteral("Continuation"); break; } case QWebSocketProtocol::OC_RESERVED_3: { - frameType = "Reserved3"; + frameType = QStringLiteral("Reserved3"); break; } case QWebSocketProtocol::OC_RESERVED_4: { - frameType = "Reserved5"; + frameType = QStringLiteral("Reserved5"); break; } case QWebSocketProtocol::OC_RESERVED_5: { - frameType = "Reserved5"; + frameType = QStringLiteral("Reserved5"); break; } case QWebSocketProtocol::OC_RESERVED_6: { - frameType = "Reserved6"; + frameType = QStringLiteral("Reserved6"); break; } case QWebSocketProtocol::OC_RESERVED_7: { - frameType = "Reserved7"; + frameType = QStringLiteral("Reserved7"); break; } case QWebSocketProtocol::OC_RESERVED_B: { - frameType = "ReservedB"; + frameType = QStringLiteral("ReservedB"); break; } case QWebSocketProtocol::OC_RESERVED_C: { - frameType = "ReservedC"; + frameType = QStringLiteral("ReservedC"); break; } case QWebSocketProtocol::OC_RESERVED_D: { - frameType = "ReservedD"; + frameType = QStringLiteral("ReservedD"); break; } case QWebSocketProtocol::OC_RESERVED_E: { - frameType = "ReservedE"; + frameType = QStringLiteral("ReservedE"); break; } case QWebSocketProtocol::OC_RESERVED_F: { - frameType = "ReservedF"; + frameType = QStringLiteral("ReservedF"); break; } default: @@ -1442,19 +1527,22 @@ void tst_DataProcessor::minimumSize16Bit(quint16 sizeInBytes) { quint16 swapped16 = qToBigEndian<quint16>(sizeInBytes); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped16)); - QTest::newRow(QString("Text frame with payload size %1, represented in 2 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Text frame with payload size %1, represented in 2 bytes") + .arg(sizeInBytes).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(126) << QByteArray(wireRepresentation, 2) << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; - QTest::newRow(QString("Binary frame with payload size %1, represented in 2 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Binary frame with payload size %1, represented in 2 bytes") + .arg(sizeInBytes).toLatin1().constBegin()) << quint8(FIN | QWebSocketProtocol::OC_BINARY) << quint8(126) << QByteArray(wireRepresentation, 2) << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; - QTest::newRow(QString("Continuation frame with payload size %1, represented in 2 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Continuation frame with payload size %1, represented in 2 bytes") + .arg(sizeInBytes).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CONTINUE) << quint8(126) << QByteArray(wireRepresentation, 2) @@ -1467,21 +1555,24 @@ void tst_DataProcessor::minimumSize64Bit(quint64 sizeInBytes) quint64 swapped64 = qToBigEndian<quint64>(sizeInBytes); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped64)); - QTest::newRow(QString("Text frame with payload size %1, represented in 8 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Text frame with payload size %1, represented in 8 bytes") + .arg(sizeInBytes).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(127) << QByteArray(wireRepresentation, 8) << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; - QTest::newRow(QString("Binary frame with payload size %1, represented in 8 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Binary frame with payload size %1, represented in 8 bytes") + .arg(sizeInBytes).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_BINARY) << quint8(127) << QByteArray(wireRepresentation, 8) << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; - QTest::newRow(QString("Continuation frame with payload size %1, represented in 8 bytes").arg(sizeInBytes).toStdString().data()) + QTest::newRow(QStringLiteral("Continuation frame with payload size %1, represented in 8 bytes") + .arg(sizeInBytes).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CONTINUE) << quint8(127) << QByteArray(wireRepresentation, 8) @@ -1497,7 +1588,8 @@ void tst_DataProcessor::invalidUTF8(const char *dataTag, const char *utf8Sequenc { quint16 closeCode = qToBigEndian<quint16>(QWebSocketProtocol::CC_NORMAL); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&closeCode)); - QTest::newRow(QString("Close frame with invalid UTF8-sequence: %1").arg(dataTag).toStdString().data()) + QTest::newRow(QStringLiteral("Close frame with invalid UTF8-sequence: %1") + .arg(dataTag).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << quint8(payload.length() + 2) << QByteArray(wireRepresentation, 2).append(payload) @@ -1506,14 +1598,16 @@ void tst_DataProcessor::invalidUTF8(const char *dataTag, const char *utf8Sequenc } else { - QTest::newRow(QString("Text frame with invalid UTF8-sequence: %1").arg(dataTag).toStdString().data()) + QTest::newRow(QStringLiteral("Text frame with invalid UTF8-sequence: %1") + .arg(dataTag).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(payload.length()) << payload << false << QWebSocketProtocol::CC_WRONG_DATATYPE; - QTest::newRow(QString("Continuation text frame with invalid UTF8-sequence: %1").arg(dataTag).toStdString().data()) + QTest::newRow(QStringLiteral("Continuation text frame with invalid UTF8-sequence: %1") + .arg(dataTag).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CONTINUE) << quint8(payload.length()) << payload @@ -1529,7 +1623,7 @@ void tst_DataProcessor::invalidField(const char *dataTag, quint8 invalidFieldVal << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; - QTest::newRow(QString(dataTag).append(" with continuation frame").toStdString().data()) + QTest::newRow(QString::fromLatin1(dataTag).append(" with continuation frame").toLatin1().constData()) << quint8(FIN | invalidFieldValue) << quint8(0x00) << QByteArray() @@ -1547,7 +1641,8 @@ void tst_DataProcessor::incompleteFrame(quint8 controlCode, quint64 indicatedSiz if (indicatedSize < 126) { - QTest::newRow(frameType.append(QString(" frame with payload size %1, but only %2 bytes of data").arg(indicatedSize).arg(actualPayloadSize)).toStdString().data()) + QTest::newRow(frameType.append(QStringLiteral(" frame with payload size %1, but only %2 bytes of data") + .arg(indicatedSize).arg(actualPayloadSize)).toLatin1().constData()) << quint8(FIN | controlCode) << quint8(indicatedSize) << firstFrame.append(QByteArray(actualPayloadSize, 'a')) @@ -1558,7 +1653,8 @@ void tst_DataProcessor::incompleteFrame(quint8 controlCode, quint64 indicatedSiz { quint16 swapped16 = qToBigEndian<quint16>(static_cast<quint16>(indicatedSize)); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped16)); - QTest::newRow(frameType.append(QString(" frame with payload size %1, but only %2 bytes of data").arg(indicatedSize).arg(actualPayloadSize)).toStdString().data()) + QTest::newRow(frameType.append(QStringLiteral(" frame with payload size %1, but only %2 bytes of data") + .arg(indicatedSize).arg(actualPayloadSize)).toLatin1().constData()) << quint8(FIN | controlCode) << quint8(126) << firstFrame.append(QByteArray(wireRepresentation, 2).append(QByteArray(actualPayloadSize, 'a'))) @@ -1569,7 +1665,8 @@ void tst_DataProcessor::incompleteFrame(quint8 controlCode, quint64 indicatedSiz { quint64 swapped64 = qToBigEndian<quint64>(indicatedSize); const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&swapped64)); - QTest::newRow(frameType.append(QString(" frame with payload size %1, but only %2 bytes of data").arg(indicatedSize).arg(actualPayloadSize)).toStdString().data()) + QTest::newRow(frameType.append(QStringLiteral(" frame with payload size %1, but only %2 bytes of data") + .arg(indicatedSize).arg(actualPayloadSize)).toLatin1().constData()) << quint8(FIN | controlCode) << quint8(127) << firstFrame.append(QByteArray(wireRepresentation, 8).append(QByteArray(actualPayloadSize, 'a'))) @@ -1582,13 +1679,15 @@ void tst_DataProcessor::nonCharacterSequence(const char *sequence) { QByteArray utf8Sequence = QByteArray::fromHex(sequence); - QTest::newRow(QString("Text frame with payload containing the non-control character sequence 0x%1").arg(QString(sequence)).toLatin1().constData()) + QTest::newRow(QStringLiteral("Text frame with payload containing the non-control character sequence 0x%1") + .arg(QString::fromLocal8Bit(sequence)).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(utf8Sequence.size()) << utf8Sequence << false; - QTest::newRow(QString("Continuation frame with payload containing the non-control character sequence 0x%1").arg(QString(sequence)).toLatin1().constData()) + QTest::newRow(QStringLiteral("Continuation frame with payload containing the non-control character sequence 0x%1") + .arg(QString::fromLocal8Bit(sequence)).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CONTINUE) << quint8(utf8Sequence.size()) << utf8Sequence @@ -1597,19 +1696,22 @@ void tst_DataProcessor::nonCharacterSequence(const char *sequence) void tst_DataProcessor::insertIncompleteSizeFieldTest(quint8 payloadCode, quint8 numBytesFollowing) { - QTest::newRow(QString("Text frame with payload size %1, with %2 bytes following.").arg(payloadCode).arg(numBytesFollowing).toStdString().data()) + QTest::newRow(QStringLiteral("Text frame with payload size %1, with %2 bytes following.") + .arg(payloadCode).arg(numBytesFollowing).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(payloadCode) << QByteArray(numBytesFollowing, quint8(1)) << false << QWebSocketProtocol::CC_GOING_AWAY; - QTest::newRow(QString("Binary frame with payload size %1, with %2 bytes following.").arg(payloadCode).arg(numBytesFollowing).toStdString().data()) + QTest::newRow(QStringLiteral("Binary frame with payload size %1, with %2 bytes following.") + .arg(payloadCode).arg(numBytesFollowing).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_BINARY) << quint8(payloadCode) << QByteArray(numBytesFollowing, quint8(1)) << false << QWebSocketProtocol::CC_GOING_AWAY; - QTest::newRow(QString("Continuation frame with payload size %1, with %2 bytes following.").arg(payloadCode).arg(numBytesFollowing).toStdString().data()) + QTest::newRow(QStringLiteral("Continuation frame with payload size %1, with %2 bytes following.") + .arg(payloadCode).arg(numBytesFollowing).toLatin1().constData()) << quint8(FIN | QWebSocketProtocol::OC_CONTINUE) << quint8(payloadCode) << QByteArray(numBytesFollowing, quint8(1)) diff --git a/tests/auto/handshakerequest/tst_handshakerequest.cpp b/tests/auto/handshakerequest/tst_handshakerequest.cpp index 3ee5587..8b9133c 100644 --- a/tests/auto/handshakerequest/tst_handshakerequest.cpp +++ b/tests/auto/handshakerequest/tst_handshakerequest.cpp @@ -148,42 +148,51 @@ void tst_HandshakeRequest::tst_invalidStream_data() { QTest::addColumn<QString>("dataStream"); - QTest::newRow("garbage on 2 lines") << "foofoofoo\r\nfoofoo\r\n\r\n"; - QTest::newRow("garbage on 1 line") << "foofoofoofoofoo"; - QTest::newRow("Correctly formatted but invalid fields") << "VERB RESOURCE PROTOCOL"; + QTest::newRow("garbage on 2 lines") << QStringLiteral("foofoofoo\r\nfoofoo\r\n\r\n"); + QTest::newRow("garbage on 1 line") << QStringLiteral("foofoofoofoofoo"); + QTest::newRow("Correctly formatted but invalid fields") << QStringLiteral("VERB RESOURCE PROTOCOL"); //internally the fields are parsed and indexes are used to convert to a http version for instance //this test checks if there doesn't occur an out-of-bounds exception - QTest::newRow("Correctly formatted but invalid short fields") << "V R P"; - QTest::newRow("Invalid \\0 character in header") << "V R\0 P"; - QTest::newRow("Invalid http version in header") << "V R HTTP/invalid"; - QTest::newRow("Empty header field") << "GET . HTTP/1.1\r\nHEADER: "; - QTest::newRow("All zeros") << QString(QByteArray(10, char(0))); + QTest::newRow("Correctly formatted but invalid short fields") << QStringLiteral("V R P"); + QTest::newRow("Invalid \\0 character in header") << QStringLiteral("V R\0 P"); + QTest::newRow("Invalid http version in header") << QStringLiteral("V R HTTP/invalid"); + QTest::newRow("Empty header field") << QStringLiteral("GET . HTTP/1.1\r\nHEADER: "); + QTest::newRow("All zeros") << QString::fromUtf8(QByteArray(10, char(0))); QTest::newRow("Invalid hostname") << "GET . HTTP/1.1\r\nHost: \xFF\xFF"; - QTest::newRow("Complete heaer - Invalid websocket version") << "GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: \xFF\xFF\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: Upgrade\r\n\r\n"; - QTest::newRow("Complete header - Invalid verb") << "XXX . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: Upgrade\r\n\r\n"; - QTest::newRow("Complete header - Invalid http version") << "GET . HTTP/a.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: Upgrade\r\n\r\n"; - QTest::newRow("Complete header - Invalid connection") << "GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: xxxxxxx\r\n\r\n"; - QTest::newRow("Complete header - Invalid upgrade") << "GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: wabsocket\r\n" \ - "Connection: Upgrade\r\n\r\n"; - QTest::newRow("Complete header - Upgrade contains too many values") << "GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket,ftp\r\n" \ - "Connection: Upgrade\r\n\r\n"; + //doing extensive QStringLiteral concatenations here, because + //MSVC 2010 complains when using concatenation literal strings about + //concatenation of wide and narrow strings (error C2308) + QTest::newRow("Complete header - Invalid websocket version") + << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: \xFF\xFF\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: Upgrade\r\n\r\n"); + QTest::newRow("Complete header - Invalid verb") + << QStringLiteral("XXX . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: Upgrade\r\n\r\n"); + QTest::newRow("Complete header - Invalid http version") + << QStringLiteral("GET . HTTP/a.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: Upgrade\r\n\r\n"); + QTest::newRow("Complete header - Invalid connection") + << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: xxxxxxx\r\n\r\n"); + QTest::newRow("Complete header - Invalid upgrade") + << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: wabsocket\r\n") + + QStringLiteral("Connection: Upgrade\r\n\r\n"); + QTest::newRow("Complete header - Upgrade contains too many values") + << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket,ftp\r\n") + + QStringLiteral("Connection: Upgrade\r\n\r\n"); } void tst_HandshakeRequest::tst_invalidStream() @@ -218,10 +227,10 @@ void tst_HandshakeRequest::tst_invalidStream() */ void tst_HandshakeRequest::tst_multipleValuesInConnectionHeader() { - QString header = "GET /test HTTP/1.1\r\nHost: foo.com\r\nSec-WebSocket-Version: 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: Upgrade,keepalive\r\n\r\n"; + QString header = QStringLiteral("GET /test HTTP/1.1\r\nHost: foo.com\r\nSec-WebSocket-Version: 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: Upgrade,keepalive\r\n\r\n"); QByteArray data; QTextStream textStream(&data); QWebSocketHandshakeRequest request(80, false); @@ -247,11 +256,11 @@ void tst_HandshakeRequest::tst_multipleValuesInConnectionHeader() void tst_HandshakeRequest::tst_multipleVersions() { - QString header = "GET /test HTTP/1.1\r\nHost: foo.com\r\n" \ - "Sec-WebSocket-Version: 4, 5, 6, 7, 8, 13\r\n" \ - "Sec-WebSocket-Key: AVDFBDDFF\r\n" \ - "Upgrade: websocket\r\n" \ - "Connection: Upgrade,keepalive\r\n\r\n"; + QString header = QStringLiteral("GET /test HTTP/1.1\r\nHost: foo.com\r\n") + + QStringLiteral("Sec-WebSocket-Version: 4, 5, 6, 7, 8, 13\r\n") + + QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") + + QStringLiteral("Upgrade: websocket\r\n") + + QStringLiteral("Connection: Upgrade,keepalive\r\n\r\n"); QByteArray data; QTextStream textStream(&data); QWebSocketHandshakeRequest request(80, false); diff --git a/tests/auto/websocketframe/tst_websocketframe.cpp b/tests/auto/websocketframe/tst_websocketframe.cpp index 1cdd201..e3f3e12 100644 --- a/tests/auto/websocketframe/tst_websocketframe.cpp +++ b/tests/auto/websocketframe/tst_websocketframe.cpp @@ -118,7 +118,7 @@ QByteArray FrameHelper::wireRepresentation() quint16 swapped = qToBigEndian<quint16>(static_cast<quint16>(payloadLength)); wireRep.append(static_cast<const char *>(static_cast<const void *>(&swapped)), 2); } - else if (payloadLength <= 0x7FFFFFFFFFFFFFFFULL) + else { byte |= 127; wireRep.append(static_cast<char>(byte)); @@ -264,54 +264,54 @@ void tst_WebSocketFrame::tst_goodFrames_data() QTest::newRow("Non masked final text frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << false << true << false; QTest::newRow("Non masked final binary frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_BINARY - << true << QByteArray("\x00\x01\x02\x03\x04") + << true << QByteArrayLiteral("\x00\x01\x02\x03\x04") << false << true << false; QTest::newRow("Non masked final text frame with no payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_TEXT - << true << QByteArray() + << true << QByteArrayLiteral("") << false << true << false; QTest::newRow("Non masked final binary frame with no payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_BINARY - << true << QByteArray() + << true << QByteArrayLiteral("") << false << true << false; QTest::newRow("Non masked final close frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_CLOSE - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << true << false << false; QTest::newRow("Non masked final close frame with no payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_CLOSE - << true << QByteArray() + << true << QByteArrayLiteral("") << true << false << false; QTest::newRow("Non masked final ping frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_PING - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << true << false << false; QTest::newRow("Non masked final pong frame with no payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_PONG - << true << QByteArray() + << true << QByteArrayLiteral("") << true << false << false; QTest::newRow("Non masked final continuation frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_CONTINUE - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << false << true << true; QTest::newRow("Non masked non-final continuation frame with small payload") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_CONTINUE - << false << QString("Hello world!").toUtf8() + << false << QStringLiteral("Hello world!").toUtf8() << false << true << true; } @@ -371,83 +371,83 @@ void tst_WebSocketFrame::tst_invalidFrames_data() QTest::newRow("RSV1 != 0") << 1 << 0 << 0 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("RSV2 != 0") << 0 << 1 << 0 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("RSV3 != 0") << 0 << 0 << 1 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("RSV1 != 0 and RSV2 != 0") << 1 << 1 << 0 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("RSV1 != 0 and RSV3 != 0") << 1 << 0 << 1 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("RSV2 != 0 and RSV3 != 0") << 0 << 1 << 1 << 0U << QWebSocketProtocol::OC_TEXT - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode 3") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_3 - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode 4") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_4 - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode 5") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_5 - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode 6") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_6 - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode 7") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_7 - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode B") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_B - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode C") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_C - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode D") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_D - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode E") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_E - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Reserved OpCode F") << 0 << 0 << 0 << 0U << QWebSocketProtocol::OC_RESERVED_F - << true << QString("Hello world!").toUtf8() + << true << QStringLiteral("Hello world!").toUtf8() << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Close Frame with payload > 125 bytes") @@ -546,7 +546,9 @@ void tst_WebSocketFrame::tst_malformedFrames_data() //header + payload should be 12 bytes for non-masked payloads < 126 bytes for (int i = 1; i < 12; ++i) { - QTest::newRow(QString("Header too small - %1 byte(s)").arg(i).toLatin1().constData()) << wireRep.left(i) << QWebSocketProtocol::CC_GOING_AWAY; + QTest::newRow(QStringLiteral("Header too small - %1 byte(s)").arg(i).toLatin1().constData()) + << wireRep.left(i) + << QWebSocketProtocol::CC_GOING_AWAY; } //too much data { @@ -558,6 +560,22 @@ void tst_WebSocketFrame::tst_malformedFrames_data() << wireRep.left(1).append(bigpayloadIndicator).append(reinterpret_cast<char *>(swapped), 8) << QWebSocketProtocol::CC_TOO_MUCH_DATA; } + //invalid size field + { + const char bigpayloadIndicator = char(127); + quint64 payloadSize = quint64(1) << 63; + uchar swapped[8] = {0}; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Highest bit of payload length is set") + << wireRep.left(1).append(bigpayloadIndicator).append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CC_PROTOCOL_ERROR; + + payloadSize = 256; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Overlong 64-bit size field; should be 16-bit") + << wireRep.left(1).append(bigpayloadIndicator).append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CC_PROTOCOL_ERROR; + } //overlong size field { const char largepayloadIndicator = char(126); diff --git a/tests/auto/websocketprotocol/tst_websocketprotocol.cpp b/tests/auto/websocketprotocol/tst_websocketprotocol.cpp index 8e73921..433d53a 100644 --- a/tests/auto/websocketprotocol/tst_websocketprotocol.cpp +++ b/tests/auto/websocketprotocol/tst_websocketprotocol.cpp @@ -101,10 +101,11 @@ void tst_WebSocketProtocol::tst_validMasks_data() QTest::addColumn<QString>("inputdata"); QTest::addColumn<QByteArray>("result"); - QTest::newRow("Empty payload") << 0x12345678u << QString("") << QByteArray(""); - QTest::newRow("ASCII payload of 8 characters") << 0x12345678u << QString("abcdefgh") << QByteArray("\x73\x56\x35\x1C\x77\x52\x31\x10"); - QTest::newRow("ASCII payload of 9 characters") << 0x12345678u << QString("abcdefghi") << QByteArray("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B"); - QTest::newRow("UTF-8 payload") << 0x12345678u << QString("∫∂ƒ©øØ") << QByteArray("\x2D\x0B\x69\xD1\xEA\xEC"); + QTest::newRow("Empty payload") << 0x12345678u << QStringLiteral("") << QByteArrayLiteral(""); + QTest::newRow("ASCII payload of 8 characters") << 0x12345678u << QStringLiteral("abcdefgh") << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10"); + QTest::newRow("ASCII payload of 9 characters") << 0x12345678u << QStringLiteral("abcdefghi") << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B"); + //MSVC doesn't like UTF-8 in source code; the following text is represented in the string below: ∫∂ƒ©øØ + QTest::newRow("UTF-8 payload") << 0x12345678u << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98") << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC"); } void tst_WebSocketProtocol::tst_validMasks() @@ -162,12 +163,12 @@ void tst_WebSocketProtocol::tst_closeCodes_data() for (int i = 0; i < 1000; ++i) { - QTest::newRow(QString("Close code %1").arg(i).toLatin1().constData()) << i << false; + QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false; } for (int i = 1000; i < 1004; ++i) { - QTest::newRow(QString("Close code %1").arg(i).toLatin1().constData()) << i << true; + QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true; } QTest::newRow("Close code 1004") << 1004 << false; @@ -176,17 +177,17 @@ void tst_WebSocketProtocol::tst_closeCodes_data() for (int i = 1007; i < 1012; ++i) { - QTest::newRow(QString("Close code %1").arg(i).toLatin1().constData()) << i << true; + QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true; } for (int i = 1013; i < 3000; ++i) { - QTest::newRow(QString("Close code %1").arg(i).toLatin1().constData()) << i << false; + QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false; } for (int i = 3000; i < 5000; ++i) { - QTest::newRow(QString("Close code %1").arg(i).toLatin1().constData()) << i << true; + QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true; } QTest::newRow("Close code 5000") << 1004 << false; diff --git a/tests/manual/compliance/tst_compliance.cpp b/tests/manual/compliance/tst_compliance.cpp index bd4f120..a5216b2 100644 --- a/tests/manual/compliance/tst_compliance.cpp +++ b/tests/manual/compliance/tst_compliance.cpp @@ -152,7 +152,7 @@ void tst_ComplianceTest::autobahnTest() url.setPath("/updateReports?"); QUrlQuery query; - query.addQueryItem("agent", "QWebSockets"); + query.addQueryItem("agent", "QtWebSockets"); url.setQuery(query); pWebSocket->open(url); spy.wait(60000); |