diff options
-rw-r--r-- | include/m_netlib.h | 2 | ||||
-rw-r--r-- | protocols/Discord/src/gateway.cpp | 16 | ||||
-rw-r--r-- | protocols/Discord/src/http.cpp | 3 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 8 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 3 | ||||
-rw-r--r-- | protocols/WhatsAppWeb/src/server.cpp | 6 | ||||
-rw-r--r-- | src/mir_app/src/netlib_websocket.cpp | 73 |
7 files changed, 50 insertions, 61 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h index 8119863412..3164125e2a 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -789,7 +789,7 @@ struct WSHeader };
// connects to a WebSocket server
-EXTERN_C MIR_APP_DLL(HNETLIBCONN) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
// validates that the provided buffer contains full WebSocket datagram
EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize);
diff --git a/protocols/Discord/src/gateway.cpp b/protocols/Discord/src/gateway.cpp index 414979ad20..fae8eef7cc 100644 --- a/protocols/Discord/src/gateway.cpp +++ b/protocols/Discord/src/gateway.cpp @@ -47,13 +47,25 @@ bool CDiscordProto::GatewayThreadWorker() { 0, 0 } }; - m_hGatewayConnection = WebSocket_Connect(m_hGatewayNetlibUser, m_szGateway + "/?encoding=json&v=6", hdrs); - if (m_hGatewayConnection == nullptr) { + auto *pReply = WebSocket_Connect(m_hGatewayNetlibUser, m_szGateway + "/?encoding=json&v=6", hdrs); + if (pReply == nullptr) { debugLogA("Gateway connection failed, exiting"); return false; } debugLogA("Gateway connection succeeded"); + m_hGatewayConnection = pReply->nlc; + + for (int i=0; i < pReply->headersCount; i++) + if (!mir_strcmp(pReply->headers[i].szName, "Set-Cookie")) { + m_szCookie = pReply->headers[i].szValue; + + int idx = m_szCookie.Find(';'); + if (idx != -1) + m_szCookie.Truncate(idx); + break; + } + Netlib_FreeHttpRequest(pReply); bool bExit = false; int offset = 0; diff --git a/protocols/Discord/src/http.cpp b/protocols/Discord/src/http.cpp index 54b90ec668..215df90e92 100644 --- a/protocols/Discord/src/http.cpp +++ b/protocols/Discord/src/http.cpp @@ -55,6 +55,9 @@ AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR pData = mir_utf8encodeW(text); dataLength = (int)mir_strlen(pData); } + + if (!ppro->m_szCookie.IsEmpty()) + AddHeader("Cookie", ppro->m_szCookie); AddHeader("Content-Type", "application/json"); m_pFunc = pFunc; diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index bc15c1b22e..1051b57005 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -451,9 +451,11 @@ int CDiscordProto::SetAwayMsg(int iStatus, const wchar_t *msg) replaceStrW(pwszMessage, msg); - JSONNode status; status.set_name("custom_status"); status << WCHAR_PARAM("text", (msg) ? msg : L""); - JSONNode root; root << status; - Push(new AsyncHttpRequest(this, REQUEST_PATCH, "/users/@me/settings", nullptr, &root)); + if (m_bOnline) { + JSONNode status; status.set_name("custom_status"); status << WCHAR_PARAM("text", (msg) ? msg : L""); + JSONNode root; root << status; + Push(new AsyncHttpRequest(this, REQUEST_PATCH, "/users/@me/settings", nullptr, &root)); + } return 0; } diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index f68383b1d7..a25da70c5d 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -182,7 +182,8 @@ class CDiscordProto : public PROTO<CDiscordProto> CMStringA m_szGateway, // gateway url - m_szGatewaySessionId; // current session id + m_szGatewaySessionId, // current session id + m_szCookie; // a cookie to be passed into all http queries HNETLIBUSER m_hGatewayNetlibUser; // the separate netlib user handle for gateways HNETLIBCONN m_hGatewayConnection; // gateway connection diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp index df03c6badf..5fed264e36 100644 --- a/protocols/WhatsAppWeb/src/server.cpp +++ b/protocols/WhatsAppWeb/src/server.cpp @@ -372,13 +372,15 @@ bool WhatsAppProto::ServerThreadWorker() { 0, 0 } }; - m_hServerConn = WebSocket_Connect(m_hNetlibUser, "web.whatsapp.com/ws", hdrs); - if (m_hServerConn == nullptr) { + auto *pReply = WebSocket_Connect(m_hNetlibUser, "web.whatsapp.com/ws", hdrs); + if (pReply == nullptr) { debugLogA("Server connection failed, exiting"); return false; } debugLogA("Server connection succeeded"); + m_hServerConn = pReply->nlc; + Netlib_FreeHttpRequest(pReply); m_iLoginTime = time(0); m_szClientToken = getMStringA(DBKEY_CLIENT_TOKEN); diff --git a/src/mir_app/src/netlib_websocket.cpp b/src/mir_app/src/netlib_websocket.cpp index 72979bc5e0..8fe51ca62a 100644 --- a/src/mir_app/src/netlib_websocket.cpp +++ b/src/mir_app/src/netlib_websocket.cpp @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../../libs/zlib/src/zlib.h" -MIR_APP_DLL(HNETLIBCONN) WebSocket_Connect(HNETLIBUSER nlu, const char *szHost, NETLIBHTTPHEADER *pHeaders) +MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER nlu, const char *szHost, NETLIBHTTPHEADER *pHeaders) { CMStringA tmpHost(szHost); @@ -35,69 +35,38 @@ MIR_APP_DLL(HNETLIBCONN) WebSocket_Connect(HNETLIBUSER nlu, const char *szHost, if (!mir_strncmp(tmpHost, "wss://", 6)) tmpHost.Delete(0, 6); - NETLIBOPENCONNECTION conn = {}; - conn.flags = NLOCF_V2 | NLOCF_SSL; - conn.timeout = 5; - - int pos = tmpHost.Find(':'); - if (pos != -1) { - conn.wPort = atoi(tmpHost.GetBuffer() + pos + 1); - tmpHost.Truncate(pos); - } - else conn.wPort = 443; - - CMStringA args; - if ((pos = tmpHost.Find('/')) != -1) { - args = tmpHost.Mid(pos); - tmpHost.Truncate(pos); - } - - conn.szHost = tmpHost; - - HNETLIBCONN res = Netlib_OpenConnection(nlu, &conn); - if (res == nullptr) { - Netlib_Logf(nlu, "WebSocket connection failed to connect to %s:%d, exiting", tmpHost.c_str(), conn.wPort); - return false; - } - - CMStringA szBuf; - szBuf.AppendFormat("GET https://%s%s HTTP/1.1\r\n", tmpHost.c_str(), args.c_str()); - szBuf.AppendFormat("Host: %s\r\n", tmpHost.c_str()); - szBuf.AppendFormat("Upgrade: websocket\r\n"); - szBuf.AppendFormat("Pragma: no-cache\r\n"); - szBuf.AppendFormat("Cache-Control: no-cache\r\n"); - szBuf.AppendFormat("Connection: Upgrade\r\n"); - szBuf.AppendFormat("Sec-WebSocket-Version: 13\r\n"); - szBuf.AppendFormat("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n"); + auto *nlr = new MHttpRequest; + nlr->flags = NLHRF_PERSISTENT | NLHRF_HTTP11 | NLHRF_SSL; + nlr->szUrl = tmpHost.GetBuffer(); + nlr->AddHeader("Upgrade", "websocket"); + nlr->AddHeader("Pragma", "no-cache"); + nlr->AddHeader("Cache-Control", "no-cache"); + nlr->AddHeader("Connection", "Upgrade"); + nlr->AddHeader("Sec-WebSocket-Version", "13"); + nlr->AddHeader("Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits"); + if (pHeaders) { while (pHeaders->szName != nullptr) { - szBuf.AppendFormat("%s: %s\r\n", pHeaders->szName, pHeaders->szValue); + nlr->AddHeader(pHeaders->szName, pHeaders->szValue); pHeaders++; } } - szBuf.AppendFormat("\r\n"); - if (Netlib_Send(res, szBuf, szBuf.GetLength(), MSG_DUMPASTEXT) == SOCKET_ERROR) { - Netlib_Logf(nlu, "Error establishing WebSocket connection to %s:%d, send failed", tmpHost.c_str(), conn.wPort); - Netlib_CloseHandle(res); - return nullptr; - } - char buf[1024]; - int bufSize = Netlib_Recv(res, buf, _countof(buf), MSG_DUMPASTEXT); - if (bufSize <= 0) { - Netlib_Logf(nlu, "Error establishing WebSocket connection to %s:%d, read failed", tmpHost.c_str(), conn.wPort); - Netlib_CloseHandle(res); + auto *pReply = Netlib_HttpTransaction(nlu, nlr); + delete nlr; + + if (pReply == nullptr) { + Netlib_Logf(nlu, "Error establishing WebSocket connection to %s, send failed", tmpHost.c_str()); return nullptr; } - int status = 0; - if (sscanf(buf, "HTTP/1.1 %d", &status) != 1 || status != 101) { - Netlib_Logf(nlu, "Error establishing WebSocket connection to %s:%d, status %d", tmpHost.c_str(), conn.wPort, status); - Netlib_CloseHandle(res); + if (pReply->resultCode != 101) { + Netlib_Logf(nlu, "Error establishing WebSocket connection to %s, status %d", tmpHost.c_str(), pReply->resultCode); + Netlib_FreeHttpRequest(pReply); return nullptr; } - return res; + return pReply; } MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize) |