Moved processing of control frame from QWebSocketPrivate to DataProcessor.
authorKurt Pattyn <pattyn.kurt@gmail.com>
Sat, 31 Aug 2013 17:07:32 +0000 (19:07 +0200)
committerKurt Pattyn <pattyn.kurt@gmail.com>
Sat, 31 Aug 2013 17:07:32 +0000 (19:07 +0200)
Added closeReceived(), pingReceived() and pongReceived() signals.
Added processClose(), processPing() and processPong() slot to QWebSocketPrivate

src/dataprocessor_p.cpp
src/dataprocessor_p.h
src/qwebsocket_p.cpp
src/qwebsocket_p.h

index ddd311a..674d701 100644 (file)
@@ -637,8 +637,7 @@ void DataProcessor::process(QIODevice *pIoDevice)
         {
             if (frame.isControlFrame())
             {
-                Q_EMIT controlFrameReceived(frame.getOpCode(), frame.getPayload());
-                isDone = true;  //exit the loop after a control frame, so we can get a chance to close the socket if necessary
+                isDone = processControlFrame(frame);
             }
             else    //we have a dataframe; opcode can be OC_CONTINUE, OC_TEXT or OC_BINARY
             {
@@ -741,4 +740,80 @@ void DataProcessor::clear()
     }
 }
 
+bool DataProcessor::processControlFrame(const Frame &frame)
+{
+    bool mustStopProcessing = false;
+    switch (frame.getOpCode())
+    {
+    case QWebSocketProtocol::OC_PING:
+    {
+        Q_EMIT pingReceived(frame.getPayload());
+        break;
+    }
+    case QWebSocketProtocol::OC_PONG:
+    {
+        Q_EMIT pongReceived(frame.getPayload());
+        break;
+    }
+    case QWebSocketProtocol::OC_CLOSE:
+    {
+        quint16 closeCode = QWebSocketProtocol::CC_NORMAL;
+        QString closeReason;
+        QByteArray payload = frame.getPayload();
+        if (payload.size() > 0)   //close frame can have a close code and reason
+        {
+            closeCode = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(payload.constData()));
+            if (!QWebSocketProtocol::isCloseCodeValid(closeCode))
+            {
+                closeCode = QWebSocketProtocol::CC_PROTOCOL_ERROR;
+                closeReason = tr("Invalid close code %1 detected.").arg(closeCode);
+            }
+            else
+            {
+                if (payload.size() > 2)
+                {
+                    QTextCodec *tc = QTextCodec::codecForName("UTF-8");
+                    QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
+                    closeReason = tc->toUnicode(payload.constData() + 2, payload.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.");
+                    }
+                }
+            }
+        }
+        mustStopProcessing = true;
+        Q_EMIT closeReceived(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_C:
+    case QWebSocketProtocol::OC_RESERVED_B:
+    case QWebSocketProtocol::OC_RESERVED_D:
+    case QWebSocketProtocol::OC_RESERVED_E:
+    case QWebSocketProtocol::OC_RESERVED_F:
+    {
+        //do nothing
+        //case added to make C++ compiler happy
+        break;
+    }
+    default:
+    {
+        qDebug() << "DataProcessor::processControlFrame: Invalid opcode detected:" << static_cast<int>(frame.getOpCode());
+        //Do nothing
+        break;
+    }
+    }
+    return mustStopProcessing;
+}
+
 QT_END_NAMESPACE
index 7cb7c04..c5850af 100644 (file)
@@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 QT_BEGIN_NAMESPACE
 
 class QIODevice;
+class Frame;
 
 /*!
     \internal
@@ -53,7 +54,9 @@ public:
     virtual ~DataProcessor();
 
 Q_SIGNALS:
-    void controlFrameReceived(QWebSocketProtocol::OpCode opCode, QByteArray frame);
+    void pingReceived(QByteArray data);
+    void pongReceived(QByteArray data);
+    void closeReceived(QWebSocketProtocol::CloseCode closeCode, QString closeReason);
     void textFrameReceived(QString frame, bool lastFrame);
     void binaryFrameReceived(QByteArray frame, bool lastFrame);
     void textMessageReceived(QString message);
@@ -87,6 +90,8 @@ private:
     quint64 m_payloadLength;
     QTextCodec::ConverterState *m_pConverterState;
     QTextCodec *m_pTextCodec;
+
+    bool processControlFrame(const Frame &frame);
 };
 
 QT_END_NAMESPACE
index 8acb9e3..39737dc 100644 (file)
@@ -351,12 +351,14 @@ void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket)
     connect(pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(processStateChanged(QAbstractSocket::SocketState)));
     connect(pTcpSocket, SIGNAL(readyRead()), this, SLOT(processData()));
 
-    connect(&m_dataProcessor, SIGNAL(controlFrameReceived(QWebSocketProtocol::OpCode, QByteArray)), this, SLOT(processControlFrame(QWebSocketProtocol::OpCode, QByteArray)));
     connect(&m_dataProcessor, SIGNAL(textFrameReceived(QString,bool)), q, SIGNAL(textFrameReceived(QString,bool)));
     connect(&m_dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)), q, SIGNAL(binaryFrameReceived(QByteArray,bool)));
     connect(&m_dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)), q, SIGNAL(binaryMessageReceived(QByteArray)));
     connect(&m_dataProcessor, SIGNAL(textMessageReceived(QString)), q, SIGNAL(textMessageReceived(QString)));
     connect(&m_dataProcessor, SIGNAL(errorEncountered(QWebSocketProtocol::CloseCode,QString)), this, SLOT(close(QWebSocketProtocol::CloseCode,QString)));
+    connect(&m_dataProcessor, SIGNAL(pingReceived(QByteArray)), this, SLOT(processPing(QByteArray)));
+    connect(&m_dataProcessor, SIGNAL(pongReceived(QByteArray)), this, SLOT(processPong(QByteArray)));
+    connect(&m_dataProcessor, SIGNAL(closeReceived(QWebSocketProtocol::CloseCode,QString)), this, SLOT(processClose(QWebSocketProtocol::CloseCode,QString)));
 }
 
 /*!
@@ -378,7 +380,9 @@ void QWebSocketPrivate::releaseConnections(const QTcpSocket *pTcpSocket)
         disconnect(pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(processStateChanged(QAbstractSocket::SocketState)));
         disconnect(pTcpSocket, SIGNAL(readyRead()), this, SLOT(processData()));
     }
-    disconnect(&m_dataProcessor, SIGNAL(controlFrameReceived(QWebSocketProtocol::OpCode,QByteArray)), this, SLOT(processControlFrame(QWebSocketProtocol::OpCode,QByteArray)));
+    disconnect(&m_dataProcessor, SIGNAL(pingReceived(QByteArray)), this, SLOT(processPing(QByteArray)));
+    disconnect(&m_dataProcessor, SIGNAL(pongReceived(QByteArray)), this, SLOT(processPong(QByteArray)));
+    disconnect(&m_dataProcessor, SIGNAL(closeReceived(QWebSocketProtocol::CloseCode,QString)), this, SLOT(processClose(QWebSocketProtocol::CloseCode,QString)));
     disconnect(&m_dataProcessor, SIGNAL(textFrameReceived(QString,bool)), q, SIGNAL(textFrameReceived(QString,bool)));
     disconnect(&m_dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)), q, SIGNAL(binaryFrameReceived(QByteArray,bool)));
     disconnect(&m_dataProcessor, SIGNAL(binaryMessageReceived(QByteArray)), q, SIGNAL(binaryMessageReceived(QByteArray)));
@@ -856,96 +860,37 @@ void QWebSocketPrivate::processData()
     }
 }
 
-/*!
-    \internal
- */
-void QWebSocketPrivate::processControlFrame(QWebSocketProtocol::OpCode opCode, QByteArray frame)
+void QWebSocketPrivate::processPing(QByteArray data)
 {
-    Q_Q(QWebSocket);
-    switch (opCode)
-    {
-    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)
-        {
-            if (m_mustMask)
-            {
-                QWebSocketProtocol::mask(&frame, maskingKey);
-            }
-            m_pSocket->write(frame);
-        }
-        break;
-    }
-    case QWebSocketProtocol::OC_PONG:
+    quint32 maskingKey = 0;
+    if (m_mustMask)
     {
-        Q_EMIT q->pong(static_cast<quint64>(m_pingTimer.elapsed()));
-        break;
+        maskingKey = generateMaskingKey();
     }
-    case QWebSocketProtocol::OC_CLOSE:
+    m_pSocket->write(getFrameHeader(QWebSocketProtocol::OC_PONG, data.size(), maskingKey, true));
+    if (data.size() > 0)
     {
-        quint16 closeCode = QWebSocketProtocol::CC_NORMAL;
-        QString closeReason;
-        if (frame.size() > 0)   //close frame can have a close code and reason
+        if (m_mustMask)
         {
-            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
-            {
-                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)
-                    {
-                        closeCode = QWebSocketProtocol::CC_WRONG_DATATYPE;
-                        closeReason = tr("Invalid UTF-8 code encountered.");
-                    }
-                }
-            }
+            QWebSocketProtocol::mask(&data, maskingKey);
         }
-        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_C:
-    case QWebSocketProtocol::OC_RESERVED_B:
-    case QWebSocketProtocol::OC_RESERVED_D:
-    case QWebSocketProtocol::OC_RESERVED_E:
-    case QWebSocketProtocol::OC_RESERVED_F:
-    {
-        //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_pSocket->write(data);
     }
 }
 
+void QWebSocketPrivate::processPong(QByteArray data)
+{
+    Q_UNUSED(data);
+    Q_Q(QWebSocket);
+    Q_EMIT q->pong(static_cast<quint64>(m_pingTimer.elapsed()));
+}
+
+void QWebSocketPrivate::processClose(QWebSocketProtocol::CloseCode closeCode, QString closeReason)
+{
+    m_isClosingHandshakeReceived = true;
+    close(closeCode, closeReason);
+}
+
 /*!
     \internal
  */
index 5a226bf..5a1ffec 100644 (file)
@@ -104,7 +104,9 @@ public Q_SLOTS:
 
 private Q_SLOTS:
     void processData();
-    void processControlFrame(QWebSocketProtocol::OpCode opCode, QByteArray frame);
+    void processPing(QByteArray data);
+    void processPong(QByteArray data);
+    void processClose(QWebSocketProtocol::CloseCode closeCode, QString closeReason);
     void processHandshake(QTcpSocket *pSocket);
     void processStateChanged(QAbstractSocket::SocketState socketState);