summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2013-10-13 11:54:13 +0000
committerGeorge Hazan <george.hazan@gmail.com>2013-10-13 11:54:13 +0000
commitd04a944cedf1e405ffa8879ea6ae139f675b8616 (patch)
tree01dfc58c103c27301cb836d434b66d6063d11302
parent27c56000557f31b16358107754515e409b68a71b (diff)
VK: quick-n-dirty cookie parser
git-svn-id: http://svn.miranda-ng.org/main/trunk@6488 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/VKontakte/src/misc.cpp70
-rw-r--r--protocols/VKontakte/src/vk_proto.cpp1
-rw-r--r--protocols/VKontakte/src/vk_proto.h21
-rw-r--r--protocols/VKontakte/src/vk_queue.cpp2
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp16
5 files changed, 84 insertions, 26 deletions
diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp
index 64dc4d006a..2f063e414c 100644
--- a/protocols/VKontakte/src/misc.cpp
+++ b/protocols/VKontakte/src/misc.cpp
@@ -298,13 +298,12 @@ CMStringA CVkProto::AutoFillForm(char *pBody, CMStringA &szAction)
/////////////////////////////////////////////////////////////////////////////////////////
-CMStringA loginCookie;
-
CVkProto::AsyncHttpRequest::AsyncHttpRequest()
{
cbSize = sizeof(NETLIBHTTPREQUEST);
AddHeader("Connection", "keep-alive");
+ AddHeader("Accept-Encoding", "booo");
}
CVkProto::AsyncHttpRequest::~AsyncHttpRequest()
@@ -328,26 +327,65 @@ void CVkProto::AsyncHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue)
void CVkProto::AsyncHttpRequest::Redirect(NETLIBHTTPREQUEST *nhr)
{
- CMStringA szCookie;
-
for (int i=0; i < nhr->headersCount; i++) {
LPCSTR szValue = nhr->headers[i].szValue;
if (!_stricmp(nhr->headers[i].szName, "Location"))
replaceStr(szUrl, szValue);
- else if (!_stricmp(nhr->headers[i].szName, "Set-cookie")) {
- if ( strstr(szValue, "login.vk.com")) {
- if (!szCookie.IsEmpty())
- szCookie.Append("; ");
-
- LPCSTR p = strchr(szValue, ';');
- if (p == NULL)
- szCookie += szValue;
- else
- szCookie.Append(szValue, p-szValue);
+ }
+}
+
+void CVkProto::GrabCookies(NETLIBHTTPREQUEST *nhr)
+{
+ for (int i=0; i < nhr->headersCount; i++) {
+ if ( _stricmp(nhr->headers[i].szName, "Set-cookie"))
+ continue;
+
+ CMStringA szValue = nhr->headers[i].szValue, szCookieName, szCookieVal, szDomain;
+ int iStart = 0;
+ while (true) {
+ bool bFirstToken = iStart == 0;
+ CMStringA szToken = szValue.Tokenize(";", iStart).Trim();
+ if (iStart == -1)
+ break;
+
+ if (bFirstToken) {
+ int iStart2 = 0;
+ szCookieName = szToken.Tokenize("=", iStart2);
+ szCookieVal = szToken.Tokenize("=", iStart2);
}
+ else if ( !strncmp(szToken, "domain=", 7))
+ szDomain = szToken.Mid(7);
}
+
+ if ( !szCookieName.IsEmpty() && !szDomain.IsEmpty()) {
+ int k;
+ for (k=0; k < m_cookies.getCount(); k++) {
+ if (m_cookies[k].m_name == szCookieName) {
+ m_cookies[k].m_value = szCookieVal;
+ break;
+ }
+ }
+ if (k == m_cookies.getCount())
+ m_cookies.insert( new Cookie(szCookieName, szCookieVal, szDomain));
+ }
+ }
+}
+
+void CVkProto::ApplyCookies(AsyncHttpRequest *pReq)
+{
+ CMStringA szCookie;
+
+ for (int i=0; i < m_cookies.getCount(); i++) {
+ if ( !strstr(pReq->szUrl, m_cookies[i].m_domain))
+ continue;
+
+ if (!szCookie.IsEmpty())
+ szCookie.Append("; ");
+ szCookie.Append(m_cookies[i].m_name);
+ szCookie.AppendChar('=');
+ szCookie.Append(m_cookies[i].m_value);
}
- if (!szCookie.IsEmpty())
- loginCookie = szCookie;
+ if ( !szCookie.IsEmpty())
+ pReq->AddHeader("Cookie", szCookie);
}
diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp
index ebc02964c3..c566a72504 100644
--- a/protocols/VKontakte/src/vk_proto.cpp
+++ b/protocols/VKontakte/src/vk_proto.cpp
@@ -21,6 +21,7 @@ CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) :
PROTO<CVkProto>(szModuleName, ptszUserName),
m_arRequestsQueue(10),
m_sendIds(3, PtrKeySortT),
+ m_cookies(5),
m_msgId(1)
{
InitQueue();
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h
index fe499ee558..e6d309424b 100644
--- a/protocols/VKontakte/src/vk_proto.h
+++ b/protocols/VKontakte/src/vk_proto.h
@@ -128,11 +128,25 @@ private:
};
LIST<AsyncHttpRequest> m_arRequestsQueue;
CRITICAL_SECTION m_csRequestsQueue;
- CMStringA m_prevUrl, m_savedCookie;
+ CMStringA m_prevUrl;
HANDLE m_evRequestsQueue;
HANDLE m_hWorkerThread;
bool m_bTerminated;
+ struct Cookie
+ {
+ Cookie(const CMStringA& name, const CMStringA& value, const CMStringA& domain) :
+ m_name(name),
+ m_value(value),
+ m_domain(domain)
+ {}
+
+ CMStringA m_name, m_value, m_domain;
+ };
+ OBJLIST<Cookie> m_cookies;
+ void GrabCookies(NETLIBHTTPREQUEST *nhr);
+ void ApplyCookies(AsyncHttpRequest*);
+
void InitQueue();
void UninitQueue();
void ExecuteRequest(AsyncHttpRequest*);
@@ -142,8 +156,8 @@ private:
CMStringA RunCaptchaForm(LPCSTR szUrl);
CMStringA AutoFillForm(char*, CMStringA&);
-
- void ConnectionFailed(int iReason);
+
+ void ConnectionFailed(int iReason);
bool CheckJsonResult(JSONNODE*);
void OnLoggedIn();
void OnLoggedOut();
@@ -167,6 +181,7 @@ private:
ptrA m_pollingServer, m_pollingKey, m_pollingTs;
HANDLE m_pollingConn, m_hPollingThread;
ULONG m_msgId;
+ bool m_prevError;
LIST<void> m_sendIds;
bool CheckMid(int msgid);
diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp
index e1574141c4..6979a5ac46 100644
--- a/protocols/VKontakte/src/vk_queue.cpp
+++ b/protocols/VKontakte/src/vk_queue.cpp
@@ -88,7 +88,7 @@ bool CVkProto::PushAsyncHttpRequest(AsyncHttpRequest *pReq, int iTimeout)
void CVkProto::WorkerThread(void*)
{
debugLogA("CVkProto::WorkerThread: entering");
- m_bTerminated = false;
+ m_bTerminated = m_prevError = false;
m_szAccessToken = getStringA("AccessToken");
if (m_szAccessToken != NULL)
OnLoggedIn();
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index caaa8d8e91..876454439a 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -82,12 +82,12 @@ int CVkProto::SetServerStatus(int iStatus)
/////////////////////////////////////////////////////////////////////////////////////////
-extern CMStringA loginCookie;
-
static char VK_TOKEN_BEG[] = "access_token=";
void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, void*)
{
+ GrabCookies(reply);
+
if (reply->resultCode == 302) { // manual redirect
LPCSTR pszLocation = findHeader(reply, "Location");
if (pszLocation) {
@@ -118,10 +118,10 @@ void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, void*)
pReq->AddHeader("Referer", m_prevUrl);
pReq->Redirect(reply);
if (pReq->szUrl) {
- if ( strstr(pReq->szUrl, "login.vk.com"))
- pReq->AddHeader("Cookie", loginCookie);
+ ApplyCookies(pReq);
m_prevUrl = pReq->szUrl;
}
+
PushAsyncHttpRequest(pReq);
}
}
@@ -148,8 +148,11 @@ LBL_NoForm:
CMStringA szAction;
CMStringA szBody = AutoFillForm(reply->pData, szAction);
- if (szAction.IsEmpty() || szBody.IsEmpty())
- goto LBL_NoForm;
+ if (szAction.IsEmpty() || szBody.IsEmpty()) {
+ if (m_prevError)
+ goto LBL_NoForm;
+ m_prevError = true;
+ }
AsyncHttpRequest *pReq = new AsyncHttpRequest();
pReq->requestType = REQUEST_POST;
@@ -160,6 +163,7 @@ LBL_NoForm:
pReq->m_pFunc = &CVkProto::OnOAuthAuthorize;
pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
pReq->Redirect(reply);
+ ApplyCookies(pReq);
PushAsyncHttpRequest(pReq);
}