From 004f3d1f49c54bc62743a838161ac157ffc37e41 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 13 Jun 2024 16:39:12 +0300 Subject: websocket internal code went to MWebSocket --- protocols/WhatsApp/src/message.cpp | 2 +- protocols/WhatsApp/src/proto.cpp | 8 +- protocols/WhatsApp/src/proto.h | 7 +- protocols/WhatsApp/src/server.cpp | 152 +++++-------------------------------- protocols/WhatsApp/src/utils.cpp | 14 ++-- 5 files changed, 35 insertions(+), 148 deletions(-) (limited to 'protocols/WhatsApp') diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index a664e49953..2acf0b3a4e 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -152,7 +152,7 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node) if (WAJid(szChatId).isUser()) pszReceiptTo = szAuthor; } - else if (!m_hServerConn) + else if (!m_ws) pszReceiptType = "inactive"; SendReceipt(szChatId, pszReceiptTo, msgId, pszReceiptType); diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index 9cf48f0d6b..38071deaf6 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -223,19 +223,19 @@ int WhatsAppProto::SetStatus(int iNewStatus) if (m_iDesiredStatus == ID_STATUS_OFFLINE) { SetServerStatus(m_iDesiredStatus); - if (m_hServerConn != nullptr) - Netlib_Shutdown(m_hServerConn); + if (m_ws != nullptr) + m_ws->terminate(); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); } - else if (m_hServerConn == nullptr && !IsStatusConnecting(m_iStatus)) { + else if (m_ws == nullptr && !IsStatusConnecting(m_iStatus)) { m_iStatus = ID_STATUS_CONNECTING; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); ForkThread(&WhatsAppProto::ServerThread); } - else if (m_hServerConn != nullptr) { + else if (m_ws != nullptr) { SetServerStatus(m_iDesiredStatus); m_iStatus = m_iDesiredStatus; diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index 3a7842bd1f..8170101d2f 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -164,6 +164,7 @@ struct WACollection class WANoise { friend class WhatsAppProto; + friend class WebSocket; WhatsAppProto *ppro; uint32_t readCounter = 0, writeCounter = 0; @@ -268,6 +269,7 @@ class WhatsAppProto : public PROTO friend class WANoise; friend class CWhatsAppQRDlg; friend class COptionsDlg; + friend class WebSocket; class CWhatsAppProtoImpl { @@ -347,7 +349,7 @@ class WhatsAppProto : public PROTO /// Network //////////////////////////////////////////////////////////////////////////// time_t m_lastRecvTime; - HNETLIBCONN m_hServerConn; + WebSocket *m_ws; mir_cs m_csPacketQueue; OBJLIST m_arPacketQueue; @@ -365,7 +367,6 @@ class WhatsAppProto : public PROTO void ProcessReceipt(MCONTACT hContact, const char *msgId, bool bRead); - bool WSReadPacket(const WSHeader &hdr, MBinBuffer &buf); int WSSend(const ProtobufCMessage &msg); int WSSendNode(WANode &node); int WSSendNode(WANode &node, WA_PKT_HANDLER); @@ -450,7 +451,7 @@ public: ~WhatsAppProto(); __forceinline bool isOnline() const - { return m_hServerConn != 0; + { return m_ws != 0; } __forceinline void writeStr(const char *pszSetting, const JSONNode &node) diff --git a/protocols/WhatsApp/src/server.cpp b/protocols/WhatsApp/src/server.cpp index e6305d3dd5..bf7bf142c6 100644 --- a/protocols/WhatsApp/src/server.cpp +++ b/protocols/WhatsApp/src/server.cpp @@ -27,7 +27,9 @@ void WhatsAppProto::ServerThreadWorker() MHttpHeaders hdrs; hdrs.AddHeader("Origin", "https://web.whatsapp.com"); - NLHR_PTR pReply(WebSocket_Connect(m_hNetlibUser, "web.whatsapp.com/ws/chat", &hdrs)); + WebSocket ws(this); + + NLHR_PTR pReply(ws.connect(m_hNetlibUser, "web.whatsapp.com/ws/chat", &hdrs)); if (pReply == nullptr) { debugLogA("Server connection failed, exiting"); return; @@ -41,7 +43,7 @@ void WhatsAppProto::ServerThreadWorker() m_noise->init(); debugLogA("Server connection succeeded"); - m_hServerConn = pReply->nlc; + m_ws = &ws; m_lastRecvTime = time(0); m_iPacketId = 1; @@ -55,134 +57,18 @@ void WhatsAppProto::ServerThreadWorker() msg.clienthello = &client; WSSend(msg); - MBinBuffer netbuf; - - for (m_bTerminated = false; !m_bTerminated;) { - unsigned char buf[2048]; - int bufSize = Netlib_Recv(m_hServerConn, (char *)buf, _countof(buf), MSG_NODUMP); - if (bufSize == 0) { - debugLogA("Gateway connection gracefully closed"); - break; - } - if (bufSize < 0) { - debugLogA("Gateway connection error, exiting"); - break; - } - - netbuf.append(buf, bufSize); - - WSHeader hdr; - if (!WebSocket_InitHeader(hdr, netbuf.data(), netbuf.length())) - continue; - - // we lack some data, let's read them - if (netbuf.length() < hdr.headerSize + hdr.payloadSize) - if (!WSReadPacket(hdr, netbuf)) - break; - - // debugLogA("Got packet: buffer = %d, opcode = %d, headerSize = %d, payloadSize = %d, final = %d, masked = %d", - // netbuf.length(), hdr.opCode, hdr.headerSize, hdr.payloadSize, hdr.bIsFinal, hdr.bIsMasked); - // Netlib_Dump(m_hServerConn, netbuf.data(), netbuf.length(), false, 0); - - m_lastRecvTime = time(0); - - // read all payloads from the current buffer, one by one - while (true) { - MBinBuffer currPacket; - currPacket.assign(netbuf.data() + hdr.headerSize, hdr.payloadSize); - - switch (hdr.opCode) { - case 1: // json packet - debugLogA("Text packet, skipping"); - /* - currPacket.append("", 1); // add 0 to use strchr safely - CMStringA szJson(pos, (int)dataSize); - - JSONNode root = JSONNode::parse(szJson); - if (root) { - debugLogA("JSON received:\n%s", start); - - CMStringA szPrefix(start, int(pos - start - 1)); - auto *pReq = m_arPacketQueue.find((WARequest *)&szPrefix); - if (pReq != nullptr) { - root << CHAR_PARAM("$id$", szPrefix); - } - } - } - */ - break; - - case 2: // binary packet - if (hdr.payloadSize > 32) - ProcessBinaryPacket(currPacket.data(), hdr.payloadSize); - break; - - case 8: // close - debugLogA("server required to exit"); - m_bRespawn = m_bTerminated = true; // simply reconnect, don't exit - break; - - default: - Netlib_Dump(m_hServerConn, currPacket.data(), hdr.payloadSize, false, 0); - } - - netbuf.remove(hdr.headerSize + hdr.payloadSize); - // debugLogA("%d bytes removed from network buffer, %d bytes remain", hdr.headerSize + hdr.payloadSize, netbuf.length()); - if (netbuf.length() == 0) - break; - - // if we have not enough data for header, continue reading - if (!WebSocket_InitHeader(hdr, netbuf.data(), netbuf.length())) { - debugLogA("not enough data for header, continue reading"); - break; - } - - // if we have not enough data for data, continue reading - if (hdr.headerSize + hdr.payloadSize > netbuf.length()) { - debugLogA("not enough place for data (%d+%d > %d), continue reading", hdr.headerSize, hdr.payloadSize, netbuf.length()); - break; - } - - debugLogA("Got inner packet: buffer = %d, opcode = %d, headerSize = %d, payloadSize = %d, final = %d, masked = %d", - netbuf.length(), hdr.opCode, hdr.headerSize, hdr.payloadSize, hdr.bIsFinal, hdr.bIsMasked); - } - } - - debugLogA("Server connection dropped"); - Netlib_CloseHandle(m_hServerConn); - m_hServerConn = nullptr; -} - -bool WhatsAppProto::WSReadPacket(const WSHeader &hdr, MBinBuffer &res) -{ - size_t currPacketSize = res.length() - hdr.headerSize; - - char buf[1024]; - while (currPacketSize < hdr.payloadSize) { - int result = Netlib_Recv(m_hServerConn, buf, _countof(buf), MSG_NODUMP); - if (result == 0) { - debugLogA("Gateway connection gracefully closed"); - return false; - } - if (result < 0) { - debugLogA("Gateway connection error, exiting"); - return false; - } - - currPacketSize += result; - res.append(buf, result); - } - return true; + ws.run(); + m_ws = nullptr; } ///////////////////////////////////////////////////////////////////////////////////////// // Binary data processing -void WhatsAppProto::ProcessBinaryPacket(const uint8_t *pData, size_t cbDataLen) +void WebSocket::process(const uint8_t *pData, size_t cbDataLen) { - while (size_t payloadLen = m_noise->decodeFrame(pData, cbDataLen)) { - if (m_noise->bInitFinished) { - MBinBuffer buf = m_noise->decrypt(pData, payloadLen); + while (size_t payloadLen = p->m_noise->decodeFrame(pData, cbDataLen)) { + if (p->m_noise->bInitFinished) { + MBinBuffer buf = p->m_noise->decrypt(pData, payloadLen); WAReader rdr(buf.data(), buf.length()); auto b = rdr.readInt8(); @@ -195,22 +81,22 @@ void WhatsAppProto::ProcessBinaryPacket(const uint8_t *pData, size_t cbDataLen) if (WANode *pNode = rdr.readNode()) { CMStringA szText; pNode->print(szText); - debugLogA("Got binary node:\n%s", szText.c_str()); + p->debugLogA("Got binary node:\n%s", szText.c_str()); - auto pHandler = FindPersistentHandler(*pNode); + auto pHandler = p->FindPersistentHandler(*pNode); if (pHandler) - (this->*pHandler)(*pNode); + (p->*pHandler)(*pNode); else - debugLogA("cannot handle incoming message"); + p->debugLogA("cannot handle incoming message"); delete pNode; } else { - debugLogA("wrong or broken payload"); - Netlib_Dump(m_hServerConn, pData, cbDataLen, false, 0); + p->debugLogA("wrong or broken payload"); + Netlib_Dump(m_hConn, pData, cbDataLen, false, 0); } } - else OnProcessHandshake(pData, (int)payloadLen); + else p->OnProcessHandshake(pData, (int)payloadLen); pData = (BYTE*)pData + payloadLen; cbDataLen -= payloadLen; @@ -408,8 +294,8 @@ void WhatsAppProto::ShutdownSession() debugLogA("WhatsAppProto::ShutdownSession"); // shutdown all resources - if (m_hServerConn) - Netlib_Shutdown(m_hServerConn); + if (m_ws) + m_ws->terminate(); OnLoggedOut(); } diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index ff1a5b5daf..133584014c 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -169,14 +169,14 @@ CMStringA WhatsAppProto::GenerateMessageId() int WhatsAppProto::WSSend(const ProtobufCMessage &msg) { - if (m_hServerConn == nullptr) + if (m_ws == nullptr) return -1; MBinBuffer buf(proto::Serialize(&msg)); - Netlib_Dump(m_hServerConn, buf.data(), buf.length(), true, 0); + // Netlib_Dump(m_hServerConn, buf.data(), buf.length(), true, 0); MBinBuffer payload = m_noise->encodeFrame(buf.data(), buf.length()); - WebSocket_SendBinary(m_hServerConn, payload.data(), payload.length()); + m_ws->sendBinary(payload.data(), payload.length()); return 0; } @@ -184,7 +184,7 @@ int WhatsAppProto::WSSend(const ProtobufCMessage &msg) int WhatsAppProto::WSSendNode(WANode &node) { - if (m_hServerConn == nullptr) + if (m_ws == nullptr) return 0; CMStringA szText; @@ -196,13 +196,13 @@ int WhatsAppProto::WSSendNode(WANode &node) MBinBuffer encData = m_noise->encrypt(writer.body.data(), writer.body.length()); MBinBuffer payload = m_noise->encodeFrame(encData.data(), encData.length()); - WebSocket_SendBinary(m_hServerConn, payload.data(), payload.length()); + m_ws->sendBinary(payload.data(), payload.length()); return 1; } int WhatsAppProto::WSSendNode(WANode &node, WA_PKT_HANDLER pHandler) { - if (m_hServerConn == nullptr) + if (m_ws == nullptr) return 0; CMStringA id(GenerateMessageId()); @@ -217,7 +217,7 @@ int WhatsAppProto::WSSendNode(WANode &node, WA_PKT_HANDLER pHandler) int WhatsAppProto::WSSendNode(WANode &node, WA_PKT_HANDLER_FULL pHandler, void *pUserInfo) { - if (m_hServerConn == nullptr) + if (m_ws == nullptr) return 0; CMStringA id(GenerateMessageId()); -- cgit v1.2.3