Merge remote-tracking branch 'origin/stable' into dev
authorSergio Ahumada <sahumada@blackberry.com>
Thu, 13 Mar 2014 13:50:03 +0000 (14:50 +0100)
committerSergio Ahumada <sahumada@blackberry.com>
Thu, 13 Mar 2014 13:50:05 +0000 (14:50 +0100)
Change-Id: I0ee590f834200c488498315e66acf7cd046d43ad

26 files changed:
.gitattributes [new file with mode: 0644]
.tag [new file with mode: 0644]
examples/doc/echoclient.qdoc
examples/doc/echoserver.qdoc
examples/doc/qmlwebsocketclient.qdoc
examples/doc/simplechat.qdoc
examples/doc/sslechoclient.qdoc
examples/doc/sslechoserver.qdoc
examples/examples.qdoc
examples/sslechoclient/sslechoclient.cpp
examples/sslechoclient/sslechoclient.h
src/websockets/doc/qtwebsockets.qdocconf
src/websockets/doc/src/index.qdoc
src/websockets/doc/src/qtwebsockets-module.qdoc
src/websockets/qdefaultmaskgenerator_p.cpp
src/websockets/qmaskgenerator.cpp
src/websockets/qsslserver.cpp
src/websockets/qsslserver_p.h
src/websockets/qwebsocket.cpp
src/websockets/qwebsocket_p.cpp
src/websockets/qwebsockethandshakeresponse.cpp
src/websockets/qwebsocketserver.cpp
src/websockets/qwebsocketserver_p.cpp
tests/auto/dataprocessor/tst_dataprocessor.cpp
tests/auto/qwebsocket/tst_qwebsocket.cpp
tests/manual/websockets/tst_websockets.cpp

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..1a045fa
--- /dev/null
@@ -0,0 +1,4 @@
+.tag                    export-subst
+.gitignore              export-ignore
+.gitattributes          export-ignore
+.commit-template        export-ignore
diff --git a/.tag b/.tag
new file mode 100644 (file)
index 0000000..6828f88
--- /dev/null
+++ b/.tag
@@ -0,0 +1 @@
+$Format:%H$
index a1f1646..a6cb1a9 100644 (file)
     \example echoclient
     \title Echo Client Example
     \ingroup qtwebsockets-examples
-    \brief Explains how to use the websocket API to create a simple echo client.
+    \brief Describes how to use the websocket API for creating a simple echo client.
+
+    The Echo Client Example shows how to use the websocket API to create a simple
+    echo client.
 
     \sa {Echo Server Example}
 */
index b7b8299..fcb0442 100644 (file)
     \example echoserver
     \title Echo Server Example
     \ingroup qtwebsockets-examples
+    \brief Shows how to create a simple server application that
+    sends back the messages it receives.
 
-    The Echo Server example shows how to create a simple server application that
-    sends back the messages that it receives, using the websockets API.
+    The Echo Server Example shows how to create a simple server application that
+    sends back the messages it receives, using the websockets API.
 
     \sa {Echo Client Example}
 */
index 0bf39bd..776e486 100644 (file)
@@ -43,4 +43,5 @@
     \example qmlwebsocketclient
     \title QML WebSocket Client Example
     \ingroup qtwebsockets-examples
+    \brief Explains how to program a QML WebSocket client example.
 */
index 215c46a..506d45a 100644 (file)
     \example simplechat
     \title Simple Chat Example
     \ingroup qtwebsockets-examples
+    \brief Shows how to use the QWebSocket and QWebSocketServer classes
+    for creating a minimalistic chat application over websockets.
 
-    The Simple Chat example shows how to use the QWebSocket and QWebSocketServer
+    The Simple Chat Example shows how to use the QWebSocket and QWebSocketServer
     classes to create a minimalistic chat application over websockets.
+
 */
index ca515ec..d7d1897 100644 (file)
@@ -43,6 +43,8 @@
     \example sslechoclient
     \title SSL Echo Client Example
     \ingroup qtwebsockets-examples
+    \brief Shows how to use the QWebSocket class to implement an echo
+    client over a secure connection (wss).
 
     The SSL Echo Client example shows how to use the QWebSocket class to implement
     an echo client over a secure connection (wss).
index 608b27a..d158a68 100644 (file)
@@ -43,6 +43,8 @@
     \example sslechoserver
     \title SSL Echo Server Example
     \ingroup qtwebsockets-examples
+    \brief Shows how to use the QWebSocketServer class for implementing a simple
+    echo server over secure sockets (wss).
 
     The SSL Echo Server example shows how to use the QWebSocketServer class
     to implement a simple echo server over secure sockets (wss).
index b770704..bc1ad32 100644 (file)
@@ -45,8 +45,7 @@
     \page examples.html
     \brief List of Qt WebSocket examples
 
-    The module provides the following examples for reference to
-    help understand the API usage:
+    The examples below can be used as a guide to using the API.
 
     \list
     \li \l echoclient
index fdf00df..037990d 100644 (file)
@@ -40,6 +40,8 @@
 ****************************************************************************/
 #include "sslechoclient.h"
 #include <QtCore/QDebug>
+#include <QtWebSockets/QWebSocket>
+#include <QCoreApplication>
 
 QT_USE_NAMESPACE
 
@@ -49,6 +51,9 @@ SslEchoClient::SslEchoClient(const QUrl &url, QObject *parent) :
     m_webSocket()
 {
     connect(&m_webSocket, &QWebSocket::connected, this, &SslEchoClient::onConnected);
+    typedef void (QWebSocket:: *sslErrorsSignal)(const QList<QSslError> &);
+    connect(&m_webSocket, static_cast<sslErrorsSignal>(&QWebSocket::sslErrors),
+            this, &SslEchoClient::onSslErrors);
     m_webSocket.open(QUrl(url));
 }
 //! [constructor]
@@ -67,5 +72,17 @@ void SslEchoClient::onConnected()
 void SslEchoClient::onTextMessageReceived(QString message)
 {
     qDebug() << "Message received:" << message;
+    qApp->quit();
+}
+
+void SslEchoClient::onSslErrors(const QList<QSslError> &errors)
+{
+    Q_UNUSED(errors);
+
+    // WARNING: Never ignore SSL errors in production code.
+    // The proper way to handle self-signed certificates is to add a custom root
+    // to the CA store.
+
+    m_webSocket.ignoreSslErrors();
 }
 //! [onTextMessageReceived]
index cec9e9d..7ec373b 100644 (file)
 
 #include <QtCore/QObject>
 #include <QtWebSockets/QWebSocket>
+#include <QtNetwork/QSslError>
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
 
 QT_FORWARD_DECLARE_CLASS(QWebSocket)
 
@@ -52,13 +56,10 @@ class SslEchoClient : public QObject
 public:
     explicit SslEchoClient(const QUrl &url, QObject *parent = Q_NULLPTR);
 
-Q_SIGNALS:
-
-public Q_SLOTS:
-
 private Q_SLOTS:
     void onConnected();
     void onTextMessageReceived(QString message);
+    void onSslErrors(const QList<QSslError> &errors);
 
 private:
     QWebSocket m_webSocket;
index 434c9f2..7822edc 100644 (file)
@@ -40,11 +40,11 @@ tagfile                                             = ../../../doc/qtwebsockets/
 
 depends                                             += qtcore qtnetwork qtdoc
 
-headerdirs                                          += ..
+headerdirs                                          += .. \
                                                        ../../imports
 
 sourcedirs                                          += .. \
-                                                       src
+                                                       src \
                                                        ../../imports
 
 
index f85380b..2961ef3 100644 (file)
     QT += websockets
     \endcode
 
-    \section1 Related information
+    \section1 Reference documentation
     \list
     \li \l{Qt WebSockets C++ Classes}{C++ Classes}
-    \li \l{Qt WebSockets Examples}{Examples}
     \li \l{Qt WebSockets QML Types}{QML Types}
     \endlist
+
+    \section1 Examples
+
+    The module provides the following examples as a guide to using
+    the API.
+    \l{Qt WebSockets Examples}{Examples}
 */
index c4dea41..02d31d1 100644 (file)
@@ -29,6 +29,7 @@
     \title Qt WebSockets C++ Classes
     \ingroup modules
     \qtvariable websockets
+    \since 5.3
     \brief List of C++ classes that provide WebSockets communication.
 
     To use these classes in your application, use the following include
@@ -52,4 +53,9 @@
     \brief List of QML types that provide WebSockets communication.
 
     \annotatedlist websockets-qml
+
+    The QML types are accessed by using:
+    \code
+    import QtWebSockets 1.0
+    \endcode
 */
index 814e04d..da166ac 100644 (file)
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
+/*!
+    \class QDefaultMaskGenerator
+
+    \inmodule QtWebSockets
+
+    \brief The QDefaultMaskGenerator class provides the default mask generator for QtWebSockets.
+
+    The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455}
+    requires that all communication from client to server must be masked. This is to prevent
+    malicious scripts to attack bad behaving proxies.
+    For more information about the importance of good masking,
+    see \l {http://w2spconf.com/2011/papers/websocket.pdf}.
+    The default mask generator uses the cryptographically insecure qrand() function.
+    The best measure against attacks mentioned in the document above,
+    is to use QWebSocket over a secure connection (\e wss://).
+    In general, always be careful to not have 3rd party script access to
+    a QWebSocket in your application.
+
+    \internal
+*/
 
 #include "qdefaultmaskgenerator_p.h"
 #include <QDateTime>
 
 QT_BEGIN_NAMESPACE
 
+/*!
+    Constructs a new QDefaultMaskGenerator with the given \a parent.
+
+    \internal
+*/
 QDefaultMaskGenerator::QDefaultMaskGenerator(QObject *parent) :
     QMaskGenerator(parent)
 {
 }
 
+/*!
+    Destroys the QDefaultMaskGenerator object.
+
+    \internal
+*/
 QDefaultMaskGenerator::~QDefaultMaskGenerator()
 {
 }
 
+/*!
+    Seeds the QDefaultMaskGenerator using qsrand().
+    When seed() is not called, no seed is used at all.
+
+    \internal
+*/
 bool QDefaultMaskGenerator::seed()
 {
     qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
     return true;
 }
 
+/*!
+    Generates a new random mask using the insecure qrand() method.
+
+    \internal
+*/
 quint32 QDefaultMaskGenerator::nextMask()
 {
     return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
index aa78f77..04f5e1e 100644 (file)
 
 /*!
     \class QMaskGenerator
-    The QMaskGenerator class provides an abstract base for custom 32-bit mask generators.
+
+    \inmodule QtWebSockets
+
+    \brief The QMaskGenerator class provides an abstract base for custom 32-bit mask generators.
 
     The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455}
     requires that all communication from client to server must be masked. This is to prevent
@@ -61,6 +64,7 @@
     Initializes the QMaskGenerator by seeding the randomizer.
     When seed() is not called, it depends on the specific implementation of a subclass if
     a default seed is used or no seed is used at all.
+    Returns \e true if seeding succeeds, otherwise false.
 */
 
 /*!
@@ -75,7 +79,7 @@
 QT_BEGIN_NAMESPACE
 
 /*!
-    Creates a new QMaskGenerator object.
+    Creates a new QMaskGenerator object with the given optional QObject \a parent.
  */
 QMaskGenerator::QMaskGenerator(QObject *parent) :
     QObject(parent)
index d1add19..e5faded 100644 (file)
 **
 ****************************************************************************/
 
+/*!
+    \class QSslServer
+
+    \inmodule QtWebSockets
+
+    \brief Implements a secure TCP server over SSL.
+
+    \internal
+*/
+
 #include "qsslserver_p.h"
 
 #include <QtNetwork/QSslSocket>
 
 QT_BEGIN_NAMESPACE
 
+/*!
+    Constructs a new QSslServer with the given \a parent.
+
+    \internal
+*/
 QSslServer::QSslServer(QObject *parent) :
     QTcpServer(parent),
     m_sslConfiguration(QSslConfiguration::defaultConfiguration())
 {
 }
 
+/*!
+    Destroys the QSslServer.
+
+    All open connections are closed.
+
+    \internal
+*/
 QSslServer::~QSslServer()
 {
 }
 
+/*!
+    Sets the \a sslConfiguration to use.
+
+    \sa QSslSocket::setSslConfiguration()
+
+    \internal
+*/
 void QSslServer::setSslConfiguration(const QSslConfiguration &sslConfiguration)
 {
     m_sslConfiguration = sslConfiguration;
 }
 
+/*!
+    Returns the current ssl configuration.
+
+    \internal
+*/
 QSslConfiguration QSslServer::sslConfiguration() const
 {
     return m_sslConfiguration;
 }
 
+/*!
+    Called when a new connection is established.
+
+    Converts \a socket to a QSslSocket.
+
+    \internal
+*/
 void QSslServer::incomingConnection(qintptr socket)
 {
     QSslSocket *pSslSocket = new QSslSocket();
index 12da3c5..12b9369 100644 (file)
@@ -55,7 +55,7 @@ class QSslServer : public QTcpServer
     Q_DISABLE_COPY(QSslServer)
 
 public:
-    QSslServer(QObject *parent = Q_NULLPTR);
+    explicit QSslServer(QObject *parent = Q_NULLPTR);
     virtual ~QSslServer();
 
     void setSslConfiguration(const QSslConfiguration &sslConfiguration);
index 707d459..85b45c0 100644 (file)
     QWebSocket only supports version 13 of the WebSocket protocol, as outlined in
     \l {http://tools.ietf.org/html/rfc6455}{RFC 6455}.
 
+    \note Some proxies do not understand certain HTTP headers used during a web socket handshake.
+    In that case, non-secure web socket connections fail. The best way to mitigate against
+    this problem is to use web sockets over a secure connection.
+
     \warning To generate masks, this implementation of WebSockets uses the cryptographically
     insecure qrand() function.
     For more information about the importance of good masking,
index be589db..c51ba38 100644 (file)
@@ -92,7 +92,7 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::
     QObjectPrivate(),
     q_ptr(pWebSocket),
     m_pSocket(),
-    m_errorString(QWebSocket::tr("Unknown error")),
+    m_errorString(),
     m_version(version),
     m_resourceName(),
     m_requestUrl(),
index d244000..aa9a881 100644 (file)
@@ -207,7 +207,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(
         if (Q_UNLIKELY(!m_canUpgrade)) {
             response << QStringLiteral("HTTP/1.1 400 Bad Request");
             QStringList versions;
-            Q_FOREACH (QWebSocketProtocol::Version version, supportedVersions)
+            Q_FOREACH (const QWebSocketProtocol::Version &version, supportedVersions)
                 versions << QString::number(static_cast<int>(version));
             response << QStringLiteral("Sec-WebSocket-Version: ")
                                 % versions.join(QStringLiteral(", "));
index 0645947..884f422 100644 (file)
     \l {http://tools.ietf.org/html/rfc6455#page-39} {extensions} and
     \l {http://tools.ietf.org/html/rfc6455#page-12} {subprotocols}.
 
+    \note When working with self-signed certificates, FireFox currently has a
+    \l {https://bugzilla.mozilla.org/show_bug.cgi?id=594502} {bug} that prevents it to
+    connect to a secure websocket server. To work around this problem, first browse to the
+    secure websocket server using https. FireFox will indicate that the certificate is invalid.
+    From here on, the certificate can be added to the exceptions. After this, the secure websockets
+    connection should work.
+
     QWebSocketServer only supports version 13 of the WebSocket protocol, as outlined in RFC 6455.
 
     \sa echoserver.html
index a43e75a..f349dc2 100644 (file)
@@ -94,7 +94,8 @@ void QWebSocketServerPrivate::init()
         m_pTcpServer = pSslServer;
         if (Q_LIKELY(m_pTcpServer)) {
             QObjectPrivate::connect(pSslServer, &QSslServer::newEncryptedConnection,
-                                    this, &QWebSocketServerPrivate::onNewConnection);
+                                    this, &QWebSocketServerPrivate::onNewConnection,
+                                    Qt::QueuedConnection);
             QObject::connect(pSslServer, &QSslServer::peerVerifyError,
                              q_ptr, &QWebSocketServer::peerVerifyError);
             QObject::connect(pSslServer, &QSslServer::sslErrors,
@@ -414,13 +415,22 @@ void QWebSocketServerPrivate::handshakeReceived()
         qWarning() << QWebSocketServer::tr("Sender is not a QTcpSocket. This is a Qt bug!!!");
         return;
     }
+    //When using Google Chrome the handshake in received in two parts.
+    //Therefore, the readyRead signal is emitted twice.
+    //This is a guard against the BEAST attack.
+    //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html
+    //For Safari, the handshake is delivered at once
+    //FIXME: For FireFox, the readyRead signal is never emitted
+    //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502)
+    if (!pTcpSocket->canReadLine()) {
+        return;
+    }
+    disconnect(pTcpSocket, &QTcpSocket::readyRead,
+               this, &QWebSocketServerPrivate::handshakeReceived);
     Q_Q(QWebSocketServer);
     bool success = false;
     bool isSecure = false;
 
-    disconnect(pTcpSocket, &QTcpSocket::readyRead,
-               this, &QWebSocketServerPrivate::handshakeReceived);
-
     if (m_pendingConnections.length() >= maxPendingConnections()) {
         pTcpSocket->close();
         pTcpSocket->deleteLater();
index c60ed0e..a63193a 100644 (file)
@@ -751,7 +751,7 @@ void tst_DataProcessor::frameTooSmall()
     QSignalSpy pongMessageSpy(&dataProcessor, SIGNAL(pongReceived(QByteArray)));
     QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString)));
     QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)));
-    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool)));
+    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString,bool)));
     QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)));
 
     dataProcessor.process(&buffer);
@@ -1363,7 +1363,7 @@ void tst_DataProcessor::invalidPayloadInCloseFrame()
     QSignalSpy pongMessageSpy(&dataProcessor, SIGNAL(pongReceived(QByteArray)));
     QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString)));
     QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)));
-    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool)));
+    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString,bool)));
     QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)));
 
     data.append(firstByte).append(secondByte);
@@ -1463,7 +1463,7 @@ void tst_DataProcessor::doTest()
                         SIGNAL(errorEncountered(QWebSocketProtocol::CloseCode,QString)));
     QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString)));
     QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)));
-    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool)));
+    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString,bool)));
     QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)));
 
     if (isContinuationFrame)
@@ -1508,7 +1508,7 @@ void tst_DataProcessor::doCloseFrameTest()
                         SIGNAL(errorEncountered(QWebSocketProtocol::CloseCode,QString)));
     QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString)));
     QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)));
-    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool)));
+    QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString,bool)));
     QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)));
 
     data.append(firstByte).append(secondByte);
index f7f57b7..9e5997e 100644 (file)
@@ -146,6 +146,7 @@ private Q_SLOTS:
     void tst_invalidOrigin();
     void tst_sendTextMessage();
     void tst_sendBinaryMessage();
+    void tst_errorString();
 };
 
 tst_QWebSocket::tst_QWebSocket()
@@ -202,8 +203,7 @@ void tst_QWebSocket::tst_initialisation()
     QCOMPARE(socket->origin(), expectedOrigin);
     QCOMPARE(socket->version(), expectedVersion);
     QCOMPARE(socket->error(), QAbstractSocket::UnknownSocketError);
-    //error string defaults to "Unknown error" (localised)
-    QVERIFY(!socket->errorString().isEmpty());
+    QVERIFY(socket->errorString().isEmpty());
     QVERIFY(!socket->isValid());
     QVERIFY(socket->localAddress().isNull());
     QCOMPARE(socket->localPort(), quint16(0));
@@ -407,11 +407,15 @@ void tst_QWebSocket::tst_invalidOrigin()
 
 void tst_QWebSocket::tst_sendTextMessage()
 {
-    //will resolve in another commit
+    //TODO: will resolve in another commit
 #ifndef Q_OS_WIN
     EchoServer echoServer;
 
     QWebSocket socket;
+
+    //should return 0 because socket is not open yet
+    QCOMPARE(socket.sendTextMessage(QStringLiteral("1234")), 0);
+
     QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
     QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString)));
     QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool)));
@@ -477,11 +481,15 @@ void tst_QWebSocket::tst_sendTextMessage()
 
 void tst_QWebSocket::tst_sendBinaryMessage()
 {
-    //will resolve in another commit
+    //TODO: will resolve in another commit
 #ifndef Q_OS_WIN
     EchoServer echoServer;
 
     QWebSocket socket;
+
+    //should return 0 because socket is not open yet
+    QCOMPARE(socket.sendBinaryMessage(QByteArrayLiteral("1234")), 0);
+
     QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
     QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString)));
     QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool)));
@@ -514,7 +522,7 @@ void tst_QWebSocket::tst_sendBinaryMessage()
 
     socket.close();
 
-    //QTBUG-36762: QWebSocket emits multiplied signals when socket was reopened
+    //QTBUG-36762: QWebSocket emits multiple signals when socket is reopened
     socketConnectedSpy.clear();
     binaryMessageReceived.clear();
     binaryFrameReceived.clear();
@@ -545,6 +553,28 @@ void tst_QWebSocket::tst_sendBinaryMessage()
 #endif
 }
 
+void tst_QWebSocket::tst_errorString()
+{
+    //Check for QTBUG-37228: QWebSocket returns "Unknown Error" for known errors
+    QWebSocket socket;
+
+    //check that the default error string is empty
+    QVERIFY(socket.errorString().isEmpty());
+
+    QSignalSpy errorSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
+
+    socket.open(QUrl(QStringLiteral("ws://someserver.on.mars:9999")));
+
+    if (errorSpy.count() == 0)
+        errorSpy.wait();
+    QCOMPARE(errorSpy.count(), 1);
+    QList<QVariant> arguments = errorSpy.takeFirst();
+    QAbstractSocket::SocketError socketError =
+            qvariant_cast<QAbstractSocket::SocketError>(arguments.at(0));
+    QCOMPARE(socketError, QAbstractSocket::HostNotFoundError);
+    QCOMPARE(socket.errorString(), QStringLiteral("Host not found"));
+}
+
 QTEST_MAIN(tst_QWebSocket)
 
 #include "tst_qwebsocket.moc"
index c2fbc6b..b9a7f5e 100644 (file)
@@ -169,7 +169,7 @@ void tst_WebSocketsTest::testPeerAddress()
     QVERIFY(addresses.length() > 0);
     QHostAddress peer = m_pWebSocket->peerAddress();
     bool found = false;
-    Q_FOREACH(QHostAddress a, addresses)
+    Q_FOREACH (const QHostAddress &a, addresses)
     {
         if (a == peer)
         {