ssize_t WsConnection::onFramePayloadLen(const char* data, size_t count) { uint8_t payloadLen = (uint8_t)data[0]; m_mask = payloadLen & 0x80; payloadLen &= 0x7f; if(isControlFrame() && payloadLen >= 126) { //control frames must have payload < 126 return -1; } if(payloadLen < 126) { handleFramePayloadLen(payloadLen); } else if(payloadLen == 126) { m_status = FramePayloadLen16; } else if(payloadLen == 127) { m_status = FramePayloadLen64; } else { //payload error return -1; } return 1; }
/*! \internal */ bool QWebSocketFrame::checkValidity() { if (Q_UNLIKELY(m_rsv1 || m_rsv2 || m_rsv3)) { setError(QWebSocketProtocol::CloseCodeProtocolError, QObject::tr("Rsv field is non-zero")); } else if (Q_UNLIKELY(QWebSocketProtocol::isOpCodeReserved(m_opCode))) { setError(QWebSocketProtocol::CloseCodeProtocolError, QObject::tr("Used reserved opcode")); } else if (isControlFrame()) { if (Q_UNLIKELY(m_length > 125)) { setError(QWebSocketProtocol::CloseCodeProtocolError, QObject::tr("Controle frame is larger than 125 bytes")); } else if (Q_UNLIKELY(!m_isFinalFrame)) { setError(QWebSocketProtocol::CloseCodeProtocolError, QObject::tr("Controle frames cannot be fragmented")); } else { m_isValid = true; } } else { m_isValid = true; } return m_isValid; }
/*! \internal */ bool QWebSocketFrame::isDataFrame() const { return !isControlFrame(); }
ssize_t WsConnection::handleFrameData(const ConnectionPtr_t& conn) { uint8_t opcode = m_opcode; string data = m_cache; if(isControlFrame()) { if(!isFinalFrame()) { //control frames must not be fragmented return -1; } } else if(m_opcode == 0) { //continuation frame if(m_appData.empty()) { //nothing to continue return -1; } m_appData += m_cache; if(isFinalFrame()) { opcode = m_lastOpcode; data = m_appData; string().swap(m_appData); } } else { //start of new data message if(!m_appData.empty()) { //can't start new message until the old one is finished return -1; } if(isFinalFrame()) { opcode = m_opcode; data = m_cache; } else { m_lastOpcode = m_opcode; m_appData = m_cache; } } string().swap(m_cache); if(isFinalFrame()) { if(handleMessage(conn, opcode, data) < 0) { return -1; } } m_status = FrameStart; return 0; }