summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-01-07 16:29:37 +0200
committerGeorge Hazan <ghazan@miranda.im>2019-01-07 16:29:37 +0200
commitdc2267b1fb5bc6e43914f7a0709fbe48bf4b9a09 (patch)
tree64f7339aa091a8bad7fbc41b6b59ead5b64a5106 /protocols
parentb156c043fbf64ff4451c5e59c4724c6ff5182909 (diff)
ICQ: connection manager (must fix #1728 completely)
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Icq10/src/http.cpp44
-rw-r--r--protocols/Icq10/src/proto.h8
-rw-r--r--protocols/Icq10/src/server.cpp10
3 files changed, 42 insertions, 20 deletions
diff --git a/protocols/Icq10/src/http.cpp b/protocols/Icq10/src/http.cpp
index 4b560b6617..51ad947e26 100644
--- a/protocols/Icq10/src/http.cpp
+++ b/protocols/Icq10/src/http.cpp
@@ -35,7 +35,6 @@ void __cdecl CIcqProto::ServerThread(void*)
break;
AsyncHttpRequest *pReq;
- bool need_sleep = false;
while (true) {
{
mir_cslock lck(m_csHttpQueue);
@@ -44,24 +43,29 @@ void __cdecl CIcqProto::ServerThread(void*)
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("CIcqProto::WorkerThread: %s", "need to sleep");
+ }
+
+ int ts = time(0);
+ for (auto &it : m_ConnPool) {
+ if (it.s && it.lastTs + it.timeout < ts) {
+ Netlib_CloseHandle(it.s);
+ it.s = nullptr;
+ it.lastTs = 0;
}
}
}
m_hWorkerThread = nullptr;
- for (auto &it : m_ConnPool)
- if (it) {
- Netlib_CloseHandle(it);
- it = nullptr;
- }
+ for (auto &it : m_ConnPool) {
+ if (it.s)
+ Netlib_CloseHandle(it.s);
+ it.s = nullptr;
+ it.lastTs = it.timeout = 0;
+ }
debugLogA("CIcqProto::WorkerThread: %s", "leaving");
}
@@ -110,7 +114,8 @@ void CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
if (pReq->m_conn != CONN_NONE) {
pReq->flags |= NLHRF_PERSISTENT;
- pReq->nlc = m_ConnPool[pReq->m_conn];
+ pReq->nlc = m_ConnPool[pReq->m_conn].s;
+ m_ConnPool[pReq->m_conn].lastTs = time(0);
}
debugLogA("Executing request %s:\n%s", pReq->m_reqId, pReq->szUrl);
@@ -151,8 +156,19 @@ void CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
if (pReq->m_pFunc != nullptr)
(this->*(pReq->m_pFunc))(reply, pReq);
- if (pReq->m_conn != CONN_NONE)
- m_ConnPool[pReq->m_conn] = reply->nlc;
+ if (pReq->m_conn != CONN_NONE) {
+ auto &conn = m_ConnPool[pReq->m_conn];
+ conn.s = reply->nlc;
+ conn.timeout = 0;
+ for (int i = 0; i < reply->headersCount; i++) {
+ if (!mir_strcmp(reply->headers[i].szName, "Keep-Alive")) {
+ int timeout;
+ if (1 == sscanf(reply->headers[i].szValue, "timeout=%d", &timeout))
+ conn.timeout = timeout;
+ break;
+ }
+ }
+ }
Netlib_FreeHttpRequest(reply);
}
@@ -162,7 +178,7 @@ void CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
if (pReq->m_conn != CONN_NONE) {
if (IsStatusConnecting(m_iStatus))
ConnectionFailed(LOGINERR_NONETWORK);
- m_ConnPool[pReq->m_conn] = nullptr;
+ m_ConnPool[pReq->m_conn].s = nullptr;
}
}
diff --git a/protocols/Icq10/src/proto.h b/protocols/Icq10/src/proto.h
index 425830b85a..53a27f80a1 100644
--- a/protocols/Icq10/src/proto.h
+++ b/protocols/Icq10/src/proto.h
@@ -62,6 +62,12 @@ struct IcqOwnMessage
char m_guid[50];
};
+struct IcqConn
+{
+ HNETLIBCONN s;
+ int lastTs, timeout;
+};
+
class CIcqProto : public PROTO<CIcqProto>
{
friend struct CIcqRegistrationDlg;
@@ -113,7 +119,7 @@ class CIcqProto : public PROTO<CIcqProto>
void ProcessPresence(const JSONNode&);
void ProcessTyping(const JSONNode&);
- HNETLIBCONN m_ConnPool[CONN_LAST];
+ IcqConn m_ConnPool[CONN_LAST];
CMStringA m_szSessionKey;
CMStringA m_szAToken;
CMStringA m_szRToken;
diff --git a/protocols/Icq10/src/server.cpp b/protocols/Icq10/src/server.cpp
index b868d2ff5d..1d5bda5521 100644
--- a/protocols/Icq10/src/server.cpp
+++ b/protocols/Icq10/src/server.cpp
@@ -232,7 +232,7 @@ bool CIcqProto::RefreshRobustToken()
<< CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", ts);
CalcHash(tmp);
tmp->flags |= NLHRF_PERSISTENT;
- tmp->nlc = m_ConnPool[CONN_RAPI];
+ tmp->nlc = m_ConnPool[CONN_RAPI].s;
tmp->dataLength = tmp->m_szParam.GetLength();
tmp->pData = tmp->m_szParam.Detach();
tmp->szUrl = tmp->m_szUrl.GetBuffer();
@@ -241,7 +241,7 @@ bool CIcqProto::RefreshRobustToken()
tmp->AddHeader("User-Agent", szAgent);
NETLIBHTTPREQUEST *reply = Netlib_HttpTransaction(m_hNetlibUser, tmp);
- m_ConnPool[CONN_RAPI] = nullptr;
+ m_ConnPool[CONN_RAPI].s = nullptr;
if (reply != nullptr) {
RobustReply result(reply);
if (result.error() == 20000) {
@@ -258,7 +258,7 @@ bool CIcqProto::RefreshRobustToken()
ExecuteRequest(add);
}
- m_ConnPool[CONN_RAPI] = reply->nlc;
+ m_ConnPool[CONN_RAPI].s = reply->nlc;
Netlib_FreeHttpRequest(reply);
}
@@ -336,8 +336,8 @@ void CIcqProto::ShutdownSession()
SetEvent(m_evRequestsQueue);
for (auto &it : m_ConnPool)
- if (it)
- Netlib_Shutdown(it);
+ if (it.s)
+ Netlib_Shutdown(it.s);
OnLoggedOut();
}