diff options
| -rw-r--r-- | protocols/VKontakte/src/misc.cpp | 23 | ||||
| -rw-r--r-- | protocols/VKontakte/src/version.h | 2 | ||||
| -rw-r--r-- | protocols/VKontakte/src/vk_captcha.cpp | 32 | ||||
| -rw-r--r-- | protocols/VKontakte/src/vk_proto.cpp | 1 | ||||
| -rw-r--r-- | protocols/VKontakte/src/vk_proto.h | 8 | ||||
| -rw-r--r-- | protocols/VKontakte/src/vk_queue.cpp | 127 | ||||
| -rw-r--r-- | protocols/VKontakte/src/vk_struct.h | 2 |
7 files changed, 107 insertions, 88 deletions
diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index cb516b4479..b407cb7ac4 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -393,20 +393,16 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode) MsgPopup(TranslateT("Access denied! Data will not be sent or received."), TranslateT("Error"), true);
break;
case VKERR_CAPTCHA_NEEDED:
+ if (!pReq)
+ return false;
+
if (!ApplyCaptcha(pReq, jnError))
- if(pReq->m_iRetry > 0) {
- pReq->bNeedsRestart = true;
- Sleep(1000);
- debugLogA("CVkProto::CheckJsonResult Captcha processing error.");
- debugLogA("CVkProto::CheckJsonResult Retry = %d", pReq->m_iRetry);
- pReq->m_iRetry--;
- }
- else {
+ if(!pReq->m_iRetry) {
CMStringW wszMsg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), iErrorCode);
wszMsg += "\n";
wszMsg += TranslateT("Captcha processing error.");
MsgPopup(wszMsg, TranslateT("Error"), true);
- debugLogA("CVkProto::CheckJsonResult SendError");
+ debugLogA("CVkProto::CheckJsonResult Captcha processing error");
}
break;
@@ -426,12 +422,13 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode) case VKERR_UNKNOWN:
case VKERR_TOO_MANY_REQ_PER_SEC:
+ if (pReq->m_priority == AsyncHttpRequest::rpCaptcha)
+ break;
+ __fallthrough;
case VKERR_INTERNAL_SERVER_ERR:
if (pReq->m_iRetry > 0) {
pReq->bNeedsRestart = true;
- Sleep(1000); //Pause for fix err
- debugLogA("CVkProto::CheckJsonResult Retry = %d", pReq->m_iRetry);
- pReq->m_iRetry--;
+ debugLogA("CVkProto::CheckJsonResult Retry = %d", (MAX_RETRIES - pReq->m_iRetry + 1));
}
else {
CMStringW wszMsg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), iErrorCode);
@@ -659,7 +656,7 @@ void CVkProto::GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain) SaveCookies();
}
-void CVkProto::ApplyCookies(AsyncHttpRequest *pReq)
+void CVkProto::ApplyCookies(MHttpRequest *pReq)
{
debugLogA("CVkProto::ApplyCookies");
CMStringA szCookie;
diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h index b9d0306f1f..8f8e165fa4 100644 --- a/protocols/VKontakte/src/version.h +++ b/protocols/VKontakte/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0
#define __MINOR_VERSION 1
#define __RELEASE_NUM 18
-#define __BUILD_NUM 4
+#define __BUILD_NUM 5
#include <stdver.h>
diff --git a/protocols/VKontakte/src/vk_captcha.cpp b/protocols/VKontakte/src/vk_captcha.cpp index 7162a4cb11..90b4db548e 100644 --- a/protocols/VKontakte/src/vk_captcha.cpp +++ b/protocols/VKontakte/src/vk_captcha.cpp @@ -69,31 +69,33 @@ bool CVkProto::RunCaptchaForm(LPCSTR szUrl, CMStringA &result) bool CVkProto::ApplyCaptcha(AsyncHttpRequest *pReq, const JSONNode &jnErrorNode)
{
debugLogA("CVkProto::ApplyCaptcha");
+ if (m_bCaptchaReqInProgress)
+ return true;
+
+ m_bCaptchaReqInProgress = true;
CMStringA szUrl(jnErrorNode["captcha_img"].as_mstring());
CMStringA szSid(jnErrorNode["captcha_sid"].as_mstring());
- if (szUrl.IsEmpty() || szSid.IsEmpty())
+ if (szUrl.IsEmpty() || szSid.IsEmpty()) {
+ m_bCaptchaReqInProgress = false;
return false;
+ }
CMStringA userReply;
- if (!RunCaptchaForm(szUrl, userReply))
+ if (!RunCaptchaForm(szUrl, userReply)) {
+ m_bCaptchaReqInProgress = false;
return false;
+ }
- CMStringA szCapthaStr(FORMAT, "&captcha_sid=%s&captcha_key=%s", mir_urlEncode(szSid).c_str(), mir_urlEncode(userReply.GetString()).c_str());
-
- int iCaptchaBeg = pReq->m_szUrl.Find("&captcha_sid=", 0);
- int iCaptchaEnd = pReq->m_szUrl.Find("&v=", 0);
-
- if ((iCaptchaBeg > -1) && (iCaptchaEnd > iCaptchaBeg))
- pReq->m_szUrl.Replace(pReq->m_szUrl.Mid(iCaptchaBeg, iCaptchaEnd - iCaptchaBeg).c_str(), szCapthaStr);
- else if (iCaptchaEnd > -1)
- pReq->m_szUrl.Replace("&v=", szCapthaStr + "&v=");
- else
- pReq->m_szUrl += szCapthaStr;
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/account.setOnline.json", true, &CVkProto::OnReceiveSmth, AsyncHttpRequest::rpCaptcha)
+ << CHAR_PARAM("captcha_sid", szSid)
+ << CHAR_PARAM("captcha_key", userReply.GetString())
+ );
pReq->bNeedsRestart = true;
- debugLogA("CVkProto::ApplyCaptcha %s", pReq->m_szUrl);
-
+ debugLogA("CVkProto::ApplyCaptcha for %s", pReq->m_szUrl.c_str());
+ m_bCaptchaReqInProgress = false;
+
return true;
}
\ No newline at end of file diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index 0a6dd5525a..462de8a9d1 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -41,6 +41,7 @@ CVkProto::CVkProto(const char *szModuleName, const wchar_t *pwszUserName) : m_bSetBroadcast(false),
m_bNeedSendOnline(false),
m_bErr404Return(false),
+ m_bCaptchaReqInProgress(false),
m_vkOptions(this)
{
bIint64IDCompatibility = getBool("Iint64IDCompatibility");
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 6feaa2685a..a6fa6d1f69 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -46,7 +46,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define MAXHISTORYMIDSPERONE 100
-#define MAX_RETRIES 20
+#define MAX_RETRIES 10
#define MAX_CONTACTS_PER_REQUEST 530
struct CVkProto : public PROTO<CVkProto>
@@ -213,7 +213,8 @@ private: m_bNotifyForEndLoadingHistory,
m_bNotifyForEndLoadingHistoryAllContact,
m_bTerminated,
- m_bErr404Return;
+ m_bErr404Return,
+ m_bCaptchaReqInProgress;
VKUserID_t m_iMyUserId;
@@ -380,7 +381,7 @@ private: CMStringW RunConfirmationCode(LPCWSTR pwszTitle);
CMStringW RunRenameNick(LPCWSTR pwszOldName);
void GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain = "");
- void ApplyCookies(AsyncHttpRequest*);
+ void ApplyCookies(MHttpRequest*);
void SaveCookies();
void LoadCookies();
bool IsAuthContactLater(MCONTACT hContact);
@@ -417,6 +418,7 @@ private: void InitQueue();
void UninitQueue();
bool ExecuteRequest(AsyncHttpRequest*);
+ bool RestartRequest(AsyncHttpRequest*);
void __cdecl WorkerThread(void*);
AsyncHttpRequest* Push(MHttpRequest *pReq, int iTimeout = 10000);
bool RunCaptchaForm(LPCSTR szUrl, CMStringA&);
diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp index 28c3a5b361..d8cd125e2b 100644 --- a/protocols/VKontakte/src/vk_queue.cpp +++ b/protocols/VKontakte/src/vk_queue.cpp @@ -34,69 +34,85 @@ void CVkProto::UninitQueue() bool CVkProto::ExecuteRequest(AsyncHttpRequest *pReq)
{
- do {
- pReq->bNeedsRestart = false;
- pReq->m_iErrorCode = 0;
-
- if (pReq->m_bApiReq) {
- pReq->flags |= NLHRF_PERSISTENT;
- pReq->nlc = m_hAPIConnection;
- }
+ pReq->bNeedsRestart = false;
+ pReq->m_iErrorCode = 0;
- if (m_bTerminated)
- break;
+ if (pReq->m_bApiReq) {
+ pReq->flags |= NLHRF_PERSISTENT;
+ pReq->nlc = m_hAPIConnection;
+ }
- time_t tLocalWorkThreadTimer = 0;
- {
- mir_cslock lck(m_csWorkThreadTimer);
- tLocalWorkThreadTimer = m_tWorkThreadTimer = time(0);
- if (pReq->m_bApiReq)
- ApplyCookies(pReq);
- }
+ if (m_bTerminated) {
+ delete pReq;
+ return false;
+ }
- debugLogA("CVkProto::ExecuteRequest \n====\n%s\n====\n", pReq->m_szUrl.c_str());
- NLHR_PTR reply(Netlib_HttpTransaction(m_hNetlibUser, pReq));
- {
- mir_cslock lck(m_csWorkThreadTimer);
- if (pReq->m_bApiReq)
- GrabCookies(reply, "api.vk.com");
-
- if (tLocalWorkThreadTimer != m_tWorkThreadTimer) {
- debugLogA("CVkProto::WorkerThread is living Dead => return");
- delete pReq;
- return false;
- }
+ time_t tLocalWorkThreadTimer = 0;
+ {
+ mir_cslock lck(m_csWorkThreadTimer);
+ tLocalWorkThreadTimer = m_tWorkThreadTimer = time(0);
+ if (pReq->m_bApiReq)
+ ApplyCookies(pReq);
+ }
+
+ debugLogA("CVkProto::ExecuteRequest \n====\n%s\n====\n", pReq->m_szUrl.c_str());
+ NLHR_PTR reply(Netlib_HttpTransaction(m_hNetlibUser, pReq));
+ {
+ mir_cslock lck(m_csWorkThreadTimer);
+ if (pReq->m_bApiReq)
+ GrabCookies(reply, "api.vk.com");
+
+ if (tLocalWorkThreadTimer != m_tWorkThreadTimer) {
+ debugLogA("CVkProto::WorkerThread is living Dead => return");
+ delete pReq;
+ return false;
}
+ }
- if (reply != nullptr) {
- if (pReq->m_pFunc != nullptr)
- (this->*(pReq->m_pFunc))(reply, pReq); // may be set pReq->bNeedsRestart
+ if (reply != nullptr) {
+ if (pReq->m_pFunc != nullptr)
+ (this->*(pReq->m_pFunc))(reply, pReq); // may be set pReq->bNeedsRestart
- if (pReq->m_bApiReq)
- m_hAPIConnection = reply->nlc;
- }
- else if (pReq->bIsMainConn) {
- if (IsStatusConnecting(m_iStatus))
- ConnectionFailed(LOGINERR_NONETWORK);
- else if (pReq->m_iRetry && !m_bTerminated) {
- pReq->bNeedsRestart = true;
- Sleep(1000); //Pause for fix err
- pReq->m_iRetry--;
- debugLogA("CVkProto::ExecuteRequest restarting (retry = %d)", MAX_RETRIES - pReq->m_iRetry);
- }
- else {
- debugLogA("CVkProto::ExecuteRequest ShutdownSession");
- ShutdownSession();
- }
+ if (pReq->m_bApiReq)
+ m_hAPIConnection = reply->nlc;
+ }
+ else if (pReq->bIsMainConn) {
+ if (IsStatusConnecting(m_iStatus))
+ ConnectionFailed(LOGINERR_NONETWORK);
+ else if (pReq->m_iRetry && !m_bTerminated)
+ pReq->bNeedsRestart = true;
+ else {
+ debugLogA("CVkProto::ExecuteRequest ShutdownSession");
+ ShutdownSession();
+ return false;
}
- debugLogA("CVkProto::ExecuteRequest pReq->bNeedsRestart = %d", (int)pReq->bNeedsRestart);
+ }
+
+ if (pReq->bNeedsRestart)
+ RestartRequest(pReq);
+ else
+ delete pReq;
+
+ return true;
+}
+
+bool CVkProto::RestartRequest(AsyncHttpRequest* pReq)
+{
+ debugLogA("CVkProto::RestartRequest %d %s", (MAX_RETRIES - pReq->m_iRetry + 1), pReq->m_szUrl.c_str());
+
+ if (m_bTerminated || !pReq->m_iRetry) {
+ ShutdownSession();
+ delete pReq;
+ pReq = nullptr;
+ return false;
+ }
- if (!reply && pReq->m_bApiReq)
- CloseAPIConnection();
+ pReq->bNeedsRestart = false;
+ pReq->m_priority = AsyncHttpRequest::RequestPriority::rpRestart;
+ pReq->m_iRetry--;
- } while (pReq->bNeedsRestart && !m_bTerminated);
- delete pReq;
- return true;
+ Push(pReq);
+
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -107,7 +123,8 @@ AsyncHttpRequest* CVkProto::Push(MHttpRequest *p, int iTimeout) debugLogA("CVkProto::Push");
pReq->timeout = iTimeout;
- if (pReq->m_bApiReq) {
+
+ if (pReq->m_bApiReq && (pReq->m_iRetry == MAX_RETRIES)) {
pReq << VER_API;
if (!IsEmpty(m_vkOptions.pwszVKLang))
pReq << WCHAR_PARAM("lang", m_vkOptions.pwszVKLang);
diff --git a/protocols/VKontakte/src/vk_struct.h b/protocols/VKontakte/src/vk_struct.h index 168c79e925..aac60bf2ef 100644 --- a/protocols/VKontakte/src/vk_struct.h +++ b/protocols/VKontakte/src/vk_struct.h @@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. struct AsyncHttpRequest : public MTHttpRequest<CVkProto>
{
- enum RequestPriority { rpLowLow, rpLow, rpMedium, rpHigh };
+ enum RequestPriority { rpLowLow, rpLow, rpMedium, rpHigh, rpRestart, rpCaptcha };
AsyncHttpRequest();
AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, MTHttpRequestHandler pFunc, RequestPriority rpPriority = rpMedium);
|
