diff options
author | George Hazan <ghazan@miranda.im> | 2016-12-28 16:57:55 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2016-12-28 16:58:16 +0300 |
commit | e7a87b3c82204e048f23750a18b456e567a6f436 (patch) | |
tree | faf10111046c42cd4fcffb23d2e749effa10e540 /protocols/Discord/src/connection.cpp | |
parent | 4efdd531337b74d819a40c87c454a0fa1f6ca838 (diff) |
http framework
Diffstat (limited to 'protocols/Discord/src/connection.cpp')
-rw-r--r-- | protocols/Discord/src/connection.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/protocols/Discord/src/connection.cpp b/protocols/Discord/src/connection.cpp index a7e3babd41..13a12129e2 100644 --- a/protocols/Discord/src/connection.cpp +++ b/protocols/Discord/src/connection.cpp @@ -17,7 +17,149 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h" +void CDiscordProto::ExecuteRequest(AsyncHttpRequest *pReq) +{ + CMStringA str; + + pReq->szUrl = pReq->m_szUrl.GetBuffer(); + if (!pReq->m_szParam.IsEmpty()) { + if (pReq->requestType == REQUEST_GET) { + str.Format("%s?%s", pReq->m_szUrl, pReq->m_szParam); + pReq->szUrl = str.GetBuffer(); + } + else { + pReq->pData = mir_strdup(pReq->m_szParam); + pReq->dataLength = pReq->m_szParam.GetLength(); + } + } + + pReq->flags |= NLHRF_PERSISTENT; + pReq->nlc = m_hAPIConnection; + + debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->szUrl); + NETLIBHTTPREQUEST *reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)pReq); + if (reply != NULL) { + if (pReq->m_pCallback != NULL) + (this->*(pReq->m_pCallback))(reply, pReq); + + m_hAPIConnection = reply->nlc; + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply); + } + else { + debugLogA("Request %d failed", pReq->m_iReqNum); + + if (IsStatusConnecting(m_iStatus)) + ConnectionFailed(LOGINERR_NONETWORK); + else + ShutdownSession(); + m_hAPIConnection = NULL; + } + delete pReq; +} + +void CDiscordProto::OnLoggedIn() +{ + debugLogA("CDiscordProto::OnLoggedIn"); + m_bOnline = true; + SetServerStatus(m_iDesiredStatus); +} + +void CDiscordProto::OnLoggedOut() +{ + debugLogA("CDiscordProto::OnLoggedOut"); + m_bOnline = false; + m_hWorkerThread = NULL; + + if (m_hAPIConnection) + Netlib_CloseHandle(m_hAPIConnection); + + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; +} + +void CDiscordProto::ShutdownSession() +{ + debugLogA("CDiscordProto::ShutdownSession"); + m_bTerminated = true; + if (m_hWorkerThread) + SetEvent(m_evRequestsQueue); + OnLoggedOut(); +} + +void CDiscordProto::ConnectionFailed(int iReason) +{ + debugLogA("CDiscordProto::ConnectionFailed -> reason %d", iReason); + delSetting("AccessToken"); + + ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, iReason); + ShutdownSession(); +} + +bool CDiscordProto::TryToConnect(void) +{ + ptrW wszLogin(getWStringA(DB_KEY_EMAIL)), wszPassword(getWStringA(DB_KEY_PASSWORD)); + if (wszLogin == NULL) { + ConnectionFailed(LOGINERR_BADUSERID); + return false; + } + if (wszPassword == NULL) { + ConnectionFailed(LOGINERR_WRONGPASSWORD); + return false; + } + + Push(new AsyncHttpRequest(this, REQUEST_GET, "/user/login", &CDiscordProto::OnReceiveToken) + << WCHAR_PARAM("email", wszLogin) + << WCHAR_PARAM("password", wszPassword)); + return true; +} + void CDiscordProto::ServerThread(void*) { + m_szAccessToken = getStringA("AccessToken"); + m_hAPIConnection = NULL; + m_bTerminated = false; + + debugLogA("CDiscordProto::WorkerThread: %s", "entering"); + + if (m_szAccessToken != NULL) + // try to receive a response from server + RetrieveMyInfo(); + else if (!TryToConnect()) + return; + + while (true) { + WaitForSingleObject(m_evRequestsQueue, 1000); + if (m_bTerminated) + break; + + AsyncHttpRequest *pReq; + bool need_sleep = false; + while (true) { + { + mir_cslock lck(m_csHttpQueue); + if (m_arHttpQueue.getCount() == 0) + break; + + pReq = m_arHttpQueue[0]; + m_arHttpQueue.remove(0); + need_sleep = (m_arHttpQueue.getCount() > 1); + } + if (m_bTerminated) + break; + ExecuteRequest(pReq); + if (need_sleep) { + Sleep(330); + debugLogA("CDiscordProto::WorkerThread: %s", "need to sleep"); + } + } + } + + m_hWorkerThread = NULL; + if (m_hAPIConnection) { + Netlib_CloseHandle(m_hAPIConnection); + m_hAPIConnection = NULL; + } + debugLogA("CDiscordProto::WorkerThread: %s", "leaving"); } |