Replaced QTcpSocket * with a QIODevice * to make network independent unit tests possible.
authorKurt Pattyn <pattyn.kurt@gmail.com>
Mon, 26 Aug 2013 17:04:27 +0000 (19:04 +0200)
committerKurt Pattyn <pattyn.kurt@gmail.com>
Mon, 26 Aug 2013 17:04:27 +0000 (19:04 +0200)
src/dataprocessor_p.cpp
src/dataprocessor_p.h
src/qwebsocket_p.cpp

index fb7f5aa..214e581 100644 (file)
@@ -19,11 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "dataprocessor_p.h"
 #include "qwebsocketprotocol.h"
-#include <QTcpSocket>
+#include <QIODevice>
 #include <QtEndian>
 #include <limits.h>
 #include <QTextCodec>
 #include <QTextDecoder>
+#include <QDebug>
 
 QT_BEGIN_NAMESPACE
 
@@ -59,7 +60,7 @@ public:
 
     bool isValid() const;
 
-    static Frame readFrame(QTcpSocket *pSocket);
+    static Frame readFrame(QIODevice *pIoDevice);
 
 private:
     QWebSocketProtocol::CloseCode m_closeCode;
@@ -282,7 +283,7 @@ bool Frame::isValid() const
 /*!
     \internal
  */
-Frame Frame::readFrame(QTcpSocket *pSocket)
+Frame Frame::readFrame(QIODevice *pIoDevice)
 {
     bool isDone = false;
     qint64 bytesRead = 0;
@@ -299,7 +300,7 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
         {
             case PS_WAIT_FOR_MORE_DATA:
             {
-                bool ok = pSocket->waitForReadyRead(5000);
+                bool ok = pIoDevice->waitForReadyRead(5000);
                 if (!ok)
                 {
                     frame.setError(QWebSocketProtocol::CC_GOING_AWAY, QObject::tr("Timeout when reading data from socket."));
@@ -313,11 +314,11 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
             }
             case PS_READ_HEADER:
             {
-                if (pSocket->bytesAvailable() >= 2)
+                if (pIoDevice->bytesAvailable() >= 2)
                 {
                     //FIN, RSV1-3, Opcode
                     char header[2] = {0};
-                    bytesRead = pSocket->read(header, 2);
+                    bytesRead = pIoDevice->read(header, 2);
                     frame.m_isFinalFrame = (header[0] & 0x80) != 0;
                     frame.m_rsv1 = (header[0] & 0x40);
                     frame.m_rsv2 = (header[0] & 0x20);
@@ -361,11 +362,11 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
 
             case PS_READ_PAYLOAD_LENGTH:
             {
-                if (pSocket->bytesAvailable() >= 2)
+                if (pIoDevice->bytesAvailable() >= 2)
                 {
                     uchar length[2] = {0};
                     //TODO: Handle return value
-                    bytesRead = pSocket->read(reinterpret_cast<char *>(length), 2);
+                    bytesRead = pIoDevice->read(reinterpret_cast<char *>(length), 2);
                     payloadLength = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(length));
                     processingState = hasMask ? PS_READ_MASK : PS_READ_PAYLOAD;
                 }
@@ -378,11 +379,11 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
 
             case PS_READ_BIG_PAYLOAD_LENGTH:
             {
-                if (pSocket->bytesAvailable() >= 8)
+                if (pIoDevice->bytesAvailable() >= 8)
                 {
                     uchar length[8] = {0};
                     //TODO: Handle return value
-                    bytesRead = pSocket->read(reinterpret_cast<char *>(length), 8);
+                    bytesRead = pIoDevice->read(reinterpret_cast<char *>(length), 8);
                     //Most significant bit must be set to 0 as per http://tools.ietf.org/html/rfc6455#section-5.2
                     //TODO: Do we check for that?
                     payloadLength = qFromBigEndian<quint64>(length) & ~(1ULL << 63);
@@ -398,10 +399,10 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
 
             case PS_READ_MASK:
             {
-                if (pSocket->bytesAvailable() >= 4)
+                if (pIoDevice->bytesAvailable() >= 4)
                 {
                     //TODO: Handle return value
-                    bytesRead = pSocket->read(reinterpret_cast<char *>(&frame.m_mask), sizeof(frame.m_mask));
+                    bytesRead = pIoDevice->read(reinterpret_cast<char *>(&frame.m_mask), sizeof(frame.m_mask));
                     processingState = PS_READ_PAYLOAD;
                 }
                 else
@@ -424,10 +425,10 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
                 }
                 else
                 {
-                    quint64 bytesAvailable = static_cast<quint64>(pSocket->bytesAvailable());
+                    quint64 bytesAvailable = static_cast<quint64>(pIoDevice->bytesAvailable());
                     if (bytesAvailable >= payloadLength)
                     {
-                        frame.m_payload = pSocket->read(payloadLength);
+                        frame.m_payload = pIoDevice->read(payloadLength);
                         if (hasMask)
                         {
                             QWebSocketProtocol::mask(&frame.m_payload, frame.m_mask);
@@ -452,7 +453,7 @@ Frame Frame::readFrame(QTcpSocket *pSocket)
             default:
             {
                 //should not come here
-                qDebug() << "DataProcessor::process: Found invalid state. This should not happen!";
+                qWarning() << "DataProcessor::process: Found invalid state. This should not happen!";
                 frame.clear();
                 isDone = true;
                 break;
@@ -549,13 +550,13 @@ DataProcessor::~DataProcessor()
 /*!
     \internal
  */
-void DataProcessor::process(QTcpSocket *pSocket)
+void DataProcessor::process(QIODevice *pIoDevice)
 {
     bool isDone = false;
 
     while (!isDone)
     {
-        Frame frame = Frame::readFrame(pSocket);
+        Frame frame = Frame::readFrame(pIoDevice);
         if (frame.isValid())
         {
             if (frame.isControlFrame())
index 0c102d1..7cb7c04 100644 (file)
@@ -39,11 +39,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 QT_BEGIN_NAMESPACE
 
-class QTcpSocket;
+class QIODevice;
 
-/**
* @internal
- * @brief The DataProcessor class
+/*!
   \internal
+    The DataProcessor class reads and interprets incoming websocket messages, and emits appropriate signals.
  */
 class DataProcessor: public QObject
 {
@@ -61,7 +61,7 @@ Q_SIGNALS:
     void errorEncountered(QWebSocketProtocol::CloseCode code, QString description);
 
 public Q_SLOTS:
-    void process(QTcpSocket *pSocket);
+    void process(QIODevice *pIoDevice);
     void clear();
 
 private:
index f0fbf51..a433fc2 100644 (file)
@@ -786,46 +786,46 @@ void QWebSocketPrivate::processStateChanged(QAbstractSocket::SocketState socketS
     QAbstractSocket::SocketState webSocketState = this->state();
     switch (socketState)
     {
-        case QAbstractSocket::ConnectedState:
-        {
-            if (webSocketState == QAbstractSocket::ConnectingState)
-            {
-                m_key = generateKey();
-                QString handshake = createHandShakeRequest(m_resourceName, m_requestUrl.host() % ":" % QString::number(m_requestUrl.port(80)), origin(), "", "", m_key);
-                m_pSocket->write(handshake.toLatin1());
-            }
-            break;
-        }
-        case QAbstractSocket::ClosingState:
+    case QAbstractSocket::ConnectedState:
+    {
+        if (webSocketState == QAbstractSocket::ConnectingState)
         {
-            if (webSocketState == QAbstractSocket::ConnectedState)
-            {
-                setSocketState(QAbstractSocket::ClosingState);
-            }
-            break;
+            m_key = generateKey();
+            QString handshake = createHandShakeRequest(m_resourceName, m_requestUrl.host() % ":" % QString::number(m_requestUrl.port(80)), origin(), "", "", m_key);
+            m_pSocket->write(handshake.toLatin1());
         }
-        case QAbstractSocket::UnconnectedState:
+        break;
+    }
+    case QAbstractSocket::ClosingState:
+    {
+        if (webSocketState == QAbstractSocket::ConnectedState)
         {
-            if (webSocketState != QAbstractSocket::UnconnectedState)
-            {
-                setSocketState(QAbstractSocket::UnconnectedState);
-                Q_EMIT q->disconnected();
-            }
-            break;
+            setSocketState(QAbstractSocket::ClosingState);
         }
-        case QAbstractSocket::HostLookupState:
-        case QAbstractSocket::ConnectingState:
-        case QAbstractSocket::BoundState:
-        case QAbstractSocket::ListeningState:
-        {
-            //do nothing
-            //to make C++ compiler happy;
-            break;
-        }
-        default:
+        break;
+    }
+    case QAbstractSocket::UnconnectedState:
+    {
+        if (webSocketState != QAbstractSocket::UnconnectedState)
         {
-            break;
+            setSocketState(QAbstractSocket::UnconnectedState);
+            Q_EMIT q->disconnected();
         }
+        break;
+    }
+    case QAbstractSocket::HostLookupState:
+    case QAbstractSocket::ConnectingState:
+    case QAbstractSocket::BoundState:
+    case QAbstractSocket::ListeningState:
+    {
+        //do nothing
+        //to make C++ compiler happy;
+        break;
+    }
+    default:
+    {
+        break;
+    }
     }
 }
 
@@ -864,85 +864,85 @@ void QWebSocketPrivate::processControlFrame(QWebSocketProtocol::OpCode opCode, Q
     Q_Q(QWebSocket);
     switch (opCode)
     {
-        case QWebSocketProtocol::OC_PING:
+    case QWebSocketProtocol::OC_PING:
+    {
+        quint32 maskingKey = 0;
+        if (m_mustMask)
+        {
+            maskingKey = generateMaskingKey();
+        }
+        m_pSocket->write(getFrameHeader(QWebSocketProtocol::OC_PONG, frame.size(), maskingKey, true));
+        if (frame.size() > 0)
         {
-            quint32 maskingKey = 0;
             if (m_mustMask)
             {
-                maskingKey = generateMaskingKey();
+                QWebSocketProtocol::mask(&frame, maskingKey);
             }
-            m_pSocket->write(getFrameHeader(QWebSocketProtocol::OC_PONG, frame.size(), maskingKey, true));
-            if (frame.size() > 0)
-            {
-                if (m_mustMask)
-                {
-                    QWebSocketProtocol::mask(&frame, maskingKey);
-                }
-                m_pSocket->write(frame);
-            }
-            break;
-        }
-        case QWebSocketProtocol::OC_PONG:
-        {
-            Q_EMIT q->pong(static_cast<quint64>(m_pingTimer.elapsed()));
-            break;
+            m_pSocket->write(frame);
         }
-        case QWebSocketProtocol::OC_CLOSE:
+        break;
+    }
+    case QWebSocketProtocol::OC_PONG:
+    {
+        Q_EMIT q->pong(static_cast<quint64>(m_pingTimer.elapsed()));
+        break;
+    }
+    case QWebSocketProtocol::OC_CLOSE:
+    {
+        quint16 closeCode = QWebSocketProtocol::CC_NORMAL;
+        QString closeReason;
+        if (frame.size() > 0)   //close frame can have a close code and reason
         {
-            quint16 closeCode = QWebSocketProtocol::CC_NORMAL;
-            QString closeReason;
-            if (frame.size() > 0)   //close frame can have a close code and reason
+            closeCode = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(frame.constData()));
+            if (!QWebSocketProtocol::isCloseCodeValid(closeCode))
             {
-                closeCode = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(frame.constData()));
-                if (!QWebSocketProtocol::isCloseCodeValid(closeCode))
-                {
-                    closeCode = QWebSocketProtocol::CC_PROTOCOL_ERROR;
-                    closeReason = tr("Invalid close code %1 detected.").arg(closeCode);
-                }
-                else
+                closeCode = QWebSocketProtocol::CC_PROTOCOL_ERROR;
+                closeReason = tr("Invalid close code %1 detected.").arg(closeCode);
+            }
+            else
+            {
+                if (frame.size() > 2)
                 {
-                    if (frame.size() > 2)
+                    QTextCodec *tc = QTextCodec::codecForName("UTF-8");
+                    QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
+                    closeReason = tc->toUnicode(frame.constData() + 2, frame.size() - 2, &state);
+                    bool failed = (state.invalidChars != 0) || (state.remainingChars != 0);
+                    if (failed)
                     {
-                        QTextCodec *tc = QTextCodec::codecForName("UTF-8");
-                        QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
-                        closeReason = tc->toUnicode(frame.constData() + 2, frame.size() - 2, &state);
-                        bool failed = (state.invalidChars != 0) || (state.remainingChars != 0);
-                        if (failed)
-                        {
-                            closeCode = QWebSocketProtocol::CC_WRONG_DATATYPE;
-                            closeReason = tr("Invalid UTF-8 code encountered.");
-                        }
+                        closeCode = QWebSocketProtocol::CC_WRONG_DATATYPE;
+                        closeReason = tr("Invalid UTF-8 code encountered.");
                     }
                 }
             }
-            m_isClosingHandshakeReceived = true;
-            close(static_cast<QWebSocketProtocol::CloseCode>(closeCode), closeReason);
-            break;
-        }
-        case QWebSocketProtocol::OC_CONTINUE:
-        case QWebSocketProtocol::OC_BINARY:
-        case QWebSocketProtocol::OC_TEXT:
-        case QWebSocketProtocol::OC_RESERVED_3:
-        case QWebSocketProtocol::OC_RESERVED_4:
-        case QWebSocketProtocol::OC_RESERVED_5:
-        case QWebSocketProtocol::OC_RESERVED_6:
-        case QWebSocketProtocol::OC_RESERVED_7:
-        case QWebSocketProtocol::OC_RESERVED_B:
-        case QWebSocketProtocol::OC_RESERVED_D:
-        case QWebSocketProtocol::OC_RESERVED_E:
-        case QWebSocketProtocol::OC_RESERVED_F:
-        case QWebSocketProtocol::OC_RESERVED_V:
-        {
-            //do nothing
-            //case added to make C++ compiler happy
-            break;
-        }
-        default:
-        {
-            qDebug() << "WebSocket::processData: Invalid opcode detected:" << static_cast<int>(opCode);
-            //Do nothing
-            break;
         }
+        m_isClosingHandshakeReceived = true;
+        close(static_cast<QWebSocketProtocol::CloseCode>(closeCode), closeReason);
+        break;
+    }
+    case QWebSocketProtocol::OC_CONTINUE:
+    case QWebSocketProtocol::OC_BINARY:
+    case QWebSocketProtocol::OC_TEXT:
+    case QWebSocketProtocol::OC_RESERVED_3:
+    case QWebSocketProtocol::OC_RESERVED_4:
+    case QWebSocketProtocol::OC_RESERVED_5:
+    case QWebSocketProtocol::OC_RESERVED_6:
+    case QWebSocketProtocol::OC_RESERVED_7:
+    case QWebSocketProtocol::OC_RESERVED_B:
+    case QWebSocketProtocol::OC_RESERVED_D:
+    case QWebSocketProtocol::OC_RESERVED_E:
+    case QWebSocketProtocol::OC_RESERVED_F:
+    case QWebSocketProtocol::OC_RESERVED_V:
+    {
+        //do nothing
+        //case added to make C++ compiler happy
+        break;
+    }
+    default:
+    {
+        qDebug() << "WebSocket::processData: Invalid opcode detected:" << static_cast<int>(opCode);
+        //Do nothing
+        break;
+    }
     }
 }