diff options
author | George Hazan <ghazan@miranda.im> | 2018-12-21 15:59:56 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-12-21 15:59:56 +0300 |
commit | d30afe819abb03b139190c020db271888fab5eb1 (patch) | |
tree | ded6ed9860a4ea622a08450113400f9cbf9f47e9 | |
parent | d78ec3edaa1f6c3d6cb80aa2767a38afda76bc25 (diff) |
attempt to unify AsyncHttpRequest in various protocols
-rw-r--r-- | include/m_netlib.h | 29 | ||||
-rw-r--r-- | libs/win32/mir_app.lib | bin | 186428 -> 189168 bytes | |||
-rw-r--r-- | libs/win64/mir_app.lib | bin | 181650 -> 184494 bytes | |||
-rw-r--r-- | protocols/Discord/src/connection.cpp | 4 | ||||
-rw-r--r-- | protocols/Discord/src/http.cpp | 68 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 17 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_chats.cpp | 5 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_files.cpp | 25 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_messages.cpp | 5 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_proto.h | 2 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_queue.cpp | 37 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_search.cpp | 21 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_struct.cpp | 23 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_struct.h | 18 | ||||
-rw-r--r-- | protocols/VKontakte/src/vk_wallpost.cpp | 5 | ||||
-rw-r--r-- | src/mir_app/src/MHttpRequest.cpp | 93 | ||||
-rw-r--r-- | src/mir_app/src/mir_app.def | 9 | ||||
-rw-r--r-- | src/mir_app/src/mir_app64.def | 9 | ||||
-rwxr-xr-x | src/mir_core/src/http.cpp | 25 |
19 files changed, 196 insertions, 199 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h index c23d0fddc1..6c504e2702 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -550,6 +550,35 @@ public: Netlib_FreeHttpRequest(_p);
}
};
+
+struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+{
+ MHttpRequest();
+ ~MHttpRequest();
+
+ CMStringA m_szUrl;
+ CMStringA m_szParam;
+ void *pUserInfo;
+
+ void AddHeader(const char *szName, const char *szValue);
+};
+
+template <class T>
+class MTHttpRequest : public MHttpRequest
+{
+public:
+ __inline MTHttpRequest()
+ {}
+
+ typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
+ MTHttpRequestHandler m_pFunc = nullptr;
+};
+
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT64_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const CHAR_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
+
#endif
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib Binary files differindex 0b3694c692..7d1f32b898 100644 --- a/libs/win32/mir_app.lib +++ b/libs/win32/mir_app.lib diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib Binary files differindex c03d0b753b..50cddcd753 100644 --- a/libs/win64/mir_app.lib +++ b/libs/win64/mir_app.lib diff --git a/protocols/Discord/src/connection.cpp b/protocols/Discord/src/connection.cpp index 80ec0c172a..b986921046 100644 --- a/protocols/Discord/src/connection.cpp +++ b/protocols/Discord/src/connection.cpp @@ -43,8 +43,8 @@ void CDiscordProto::ExecuteRequest(AsyncHttpRequest *pReq) debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->szUrl); NETLIBHTTPREQUEST *reply = Netlib_HttpTransaction(m_hNetlibUser, pReq); if (reply != nullptr) { - if (pReq->m_pCallback != nullptr) - (this->*(pReq->m_pCallback))(reply, pReq); + if (pReq->m_pFunc != nullptr) + (this->*(pReq->m_pFunc))(reply, pReq); if (pReq->m_bMainSite) m_hAPIConnection = reply->nlc; diff --git a/protocols/Discord/src/http.cpp b/protocols/Discord/src/http.cpp index 743c615605..cf368a5270 100644 --- a/protocols/Discord/src/http.cpp +++ b/protocols/Discord/src/http.cpp @@ -38,7 +38,7 @@ AsyncHttpRequest::AsyncHttpRequest() m_iReqNum = ::InterlockedIncrement(&g_reqNum); } -AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR _url, HttpCallback pFunc, JSONNode *pRoot) +AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR _url, MTHttpRequestHandler pFunc, JSONNode *pRoot) { cbSize = sizeof(NETLIBHTTPREQUEST); @@ -66,72 +66,8 @@ AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR } AddHeader("Content-Type", "application/json"); + m_pFunc = pFunc; requestType = iRequestType; - m_pCallback = pFunc; - pUserInfo = nullptr; m_iErrorCode = 0; m_iReqNum = ::InterlockedIncrement(&g_reqNum); } - -AsyncHttpRequest::~AsyncHttpRequest() -{ - for (int i = 0; i < headersCount; i++) { - mir_free(headers[i].szName); - mir_free(headers[i].szValue); - } - mir_free(headers); - mir_free(pData); -} - -void AsyncHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue) -{ - for (int i = 0; i < headersCount; i++) - if (!mir_strcmp(headers[i].szName, szName)) { - replaceStr(headers[i].szValue, szValue); - return; - } - - headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); - headers[headersCount].szName = mir_strdup(szName); - headers[headersCount].szValue = mir_strdup(szValue); - headersCount++; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const INT_PARAM ¶m) -{ - CMStringA &s = pReq->m_szParam; - if (!s.IsEmpty()) - s.AppendChar('&'); - s.AppendFormat("%s=%i", param.szName, param.iValue); - return pReq; -} - -AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const INT64_PARAM ¶m) -{ - CMStringA &s = pReq->m_szParam; - if (!s.IsEmpty()) - s.AppendChar('&'); - s.AppendFormat("%s=%lld", param.szName, param.iValue); - return pReq; -} - -AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const CHAR_PARAM ¶m) -{ - CMStringA &s = pReq->m_szParam; - if (!s.IsEmpty()) - s.AppendChar('&'); - s.AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(param.szValue))); - return pReq; -} - -AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const WCHAR_PARAM ¶m) -{ - T2Utf szValue(param.wszValue); - CMStringA &s = pReq->m_szParam; - if (!s.IsEmpty()) - s.AppendChar('&'); - s.AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(szValue))); - return pReq; -} diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index fd9bc8d632..7321e9efa2 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -8,30 +8,17 @@ __forceinline int compareInt64(const SnowFlake i1, const SnowFlake i2) } class CDiscordProto; -typedef void (CDiscordProto::*HttpCallback)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*); typedef void (CDiscordProto::*GatewayHandlerFunc)(const JSONNode&); -struct AsyncHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject +struct AsyncHttpRequest : public MTHttpRequest<CDiscordProto> { AsyncHttpRequest(); - AsyncHttpRequest(CDiscordProto*, int iRequestType, LPCSTR szUrl, HttpCallback pFunc, JSONNode *pNode = nullptr); - ~AsyncHttpRequest(); + AsyncHttpRequest(CDiscordProto*, int iRequestType, LPCSTR szUrl, MTHttpRequestHandler pFunc, JSONNode *pNode = nullptr); - void AddHeader(LPCSTR, LPCSTR); - - CMStringA m_szUrl; - CMStringA m_szParam; - HttpCallback m_pCallback; int m_iErrorCode, m_iReqNum; bool m_bMainSite; - void *pUserInfo; }; -AsyncHttpRequest* operator<<(AsyncHttpRequest*, const INT_PARAM&); -AsyncHttpRequest* operator<<(AsyncHttpRequest*, const INT64_PARAM&); -AsyncHttpRequest* operator<<(AsyncHttpRequest*, const CHAR_PARAM&); -AsyncHttpRequest* operator<<(AsyncHttpRequest*, const WCHAR_PARAM&); - ///////////////////////////////////////////////////////////////////////////////////////// struct CDiscordRole : public MZeroedObject diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp index 46c990b205..a6f6d4cfd6 100644 --- a/protocols/VKontakte/src/vk_chats.cpp +++ b/protocols/VKontakte/src/vk_chats.cpp @@ -565,9 +565,8 @@ INT_PTR __cdecl CVkProto::OnJoinChat(WPARAM hContact, LPARAM) if (chat_id == VK_INVALID_USER)
return 1;
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh)
- << INT_PARAM("chat_id", chat_id)
- << WCHAR_PARAM("message", m_vkOptions.pwszReturnChatMessage);
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh);
+ pReq << INT_PARAM("chat_id", chat_id) << WCHAR_PARAM("message", m_vkOptions.pwszReturnChatMessage);
pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
Push(pReq);
db_unset(hContact, m_szModuleName, "off");
diff --git a/protocols/VKontakte/src/vk_files.cpp b/protocols/VKontakte/src/vk_files.cpp index 68fbe7da09..717ba18dcf 100644 --- a/protocols/VKontakte/src/vk_files.cpp +++ b/protocols/VKontakte/src/vk_files.cpp @@ -263,10 +263,8 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
- pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/photos.saveMessagesPhoto.json", true, &CVkProto::OnReciveUploadFile)
- << WCHAR_PARAM("server", server)
- << WCHAR_PARAM("photo", upload)
- << WCHAR_PARAM("hash", hash);
+ pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/photos.saveMessagesPhoto.json", true, &CVkProto::OnReciveUploadFile);
+ pUploadReq << WCHAR_PARAM("server", server) << WCHAR_PARAM("photo", upload) << WCHAR_PARAM("hash", hash);
break;
case CVkFileUploadParam::typeAudio:
upload = jnRoot["audio"].as_mstring();
@@ -274,10 +272,8 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
- pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/audio.save.json", true, &CVkProto::OnReciveUploadFile)
- << WCHAR_PARAM("server", server)
- << WCHAR_PARAM("audio", upload)
- << WCHAR_PARAM("hash", hash);
+ pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/audio.save.json", true, &CVkProto::OnReciveUploadFile);
+ pUploadReq << WCHAR_PARAM("server", server) << WCHAR_PARAM("audio", upload) << WCHAR_PARAM("hash", hash);
break;
case CVkFileUploadParam::typeDoc:
upload = jnRoot["file"].as_mstring();
@@ -285,9 +281,8 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) SendFileFiled(fup, VKERR_INVALID_PARAMETERS);
return;
}
- pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/docs.save.json", true, &CVkProto::OnReciveUploadFile)
- << CHAR_PARAM("title", fup->fileName())
- << WCHAR_PARAM("file", upload);
+ pUploadReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/docs.save.json", true, &CVkProto::OnReciveUploadFile);
+ pUploadReq << CHAR_PARAM("title", fup->fileName()) << WCHAR_PARAM("file", upload);
break;
default:
SendFileFiled(fup, VKERR_FTYPE_NOT_SUPPORTED);
@@ -359,8 +354,8 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR return;
}
- pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh)
- << INT_PARAM("chat_id", cc->m_chatid);
+ pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh);
+ pMsgReq << INT_PARAM("chat_id", cc->m_chatid);
pMsgReq->pUserInfo = pReq->pUserInfo;
}
@@ -371,8 +366,8 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR return;
}
- pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendMessage, AsyncHttpRequest::rpHigh)
- << INT_PARAM("user_id", userID);
+ pMsgReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendMessage, AsyncHttpRequest::rpHigh);
+ pMsgReq << INT_PARAM("user_id", userID);
pMsgReq->pUserInfo = new CVkSendMsgParam(fup->hContact, fup);
}
diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp index f6cdbf0fc1..63d5ce317b 100644 --- a/protocols/VKontakte/src/vk_messages.cpp +++ b/protocols/VKontakte/src/vk_messages.cpp @@ -47,9 +47,8 @@ int CVkProto::SendMsg(MCONTACT hContact, int, const char *szMsg) ULONG uMsgId = ::InterlockedIncrement(&m_msgId);
AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true,
- bIsChat ? &CVkProto::OnSendChatMsg : &CVkProto::OnSendMessage, AsyncHttpRequest::rpHigh)
- << INT_PARAM(bIsChat ? "chat_id" : "peer_id", iUserID)
- << INT_PARAM("random_id", ((LONG)time(0)) * 100 + uMsgId % 100);
+ bIsChat ? &CVkProto::OnSendChatMsg : &CVkProto::OnSendMessage, AsyncHttpRequest::rpHigh);
+ pReq << INT_PARAM(bIsChat ? "chat_id" : "peer_id", iUserID) << INT_PARAM("random_id", ((LONG)time(0)) * 100 + uMsgId % 100);
pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
if (StickerId)
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 6c3d632715..e77bea8472 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -361,7 +361,7 @@ private: void UninitQueue();
void ExecuteRequest(AsyncHttpRequest*);
void __cdecl WorkerThread(void*);
- AsyncHttpRequest* Push(AsyncHttpRequest *pReq, int iTimeout = 10000);
+ AsyncHttpRequest* Push(MHttpRequest *pReq, int iTimeout = 10000);
bool RunCaptchaForm(LPCSTR szUrl, CMStringA&);
bool ApplyCaptcha(AsyncHttpRequest *pReq, const JSONNode&);
void ConnectionFailed(int iReason);
diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp index ff6b62b9ab..c4ef960cc0 100644 --- a/protocols/VKontakte/src/vk_queue.cpp +++ b/protocols/VKontakte/src/vk_queue.cpp @@ -90,8 +90,10 @@ void CVkProto::ExecuteRequest(AsyncHttpRequest *pReq) /////////////////////////////////////////////////////////////////////////////////////////
-AsyncHttpRequest* CVkProto::Push(AsyncHttpRequest *pReq, int iTimeout)
+AsyncHttpRequest* CVkProto::Push(MHttpRequest *p, int iTimeout)
{
+ AsyncHttpRequest *pReq = (AsyncHttpRequest*)p;
+
debugLogA("CVkProto::Push");
pReq->timeout = iTimeout;
if (pReq->m_bApiReq) {
@@ -131,7 +133,8 @@ void CVkProto::WorkerThread(void*) else {
// Initialize new OAuth session
extern char szBlankUrl[];
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "https://oauth.vk.com/authorize", false, &CVkProto::OnOAuthAuthorize)
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "https://oauth.vk.com/authorize", false, &CVkProto::OnOAuthAuthorize);
+ pReq
<< INT_PARAM("client_id", VK_APP_ID)
<< CHAR_PARAM("scope", Score)
<< CHAR_PARAM("redirect_uri", szBlankUrl)
@@ -203,33 +206,3 @@ void CVkProto::WorkerThread(void*) m_hWorkerThread = nullptr;
}
}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const INT_PARAM ¶m)
-{
- CMStringA &s = pReq->m_szParam;
- if (!s.IsEmpty())
- s.AppendChar('&');
- s.AppendFormat("%s=%ld", param.szName, param.iValue);
- return pReq;
-}
-
-AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const CHAR_PARAM ¶m)
-{
- CMStringA &s = pReq->m_szParam;
- if (!s.IsEmpty())
- s.AppendChar('&');
- s.AppendFormat("%s=%s", param.szName, ptrA(pReq->bExpUrlEncode ? ExpUrlEncode(param.szValue) : mir_urlEncode(param.szValue)));
- return pReq;
-}
-
-AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const WCHAR_PARAM ¶m)
-{
- T2Utf szValue(param.wszValue);
- CMStringA &s = pReq->m_szParam;
- if (!s.IsEmpty())
- s.AppendChar('&');
- s.AppendFormat("%s=%s", param.szName, ptrA(pReq->bExpUrlEncode ? ExpUrlEncode(szValue) : mir_urlEncode(szValue)));
- return pReq;
-}
\ No newline at end of file diff --git a/protocols/VKontakte/src/vk_search.cpp b/protocols/VKontakte/src/vk_search.cpp index 3796fbb530..9cba181b6f 100644 --- a/protocols/VKontakte/src/vk_search.cpp +++ b/protocols/VKontakte/src/vk_search.cpp @@ -46,11 +46,9 @@ void CVkProto::SearchBasicThread(void *id) debugLogA("CVkProto::OnSearchBasicThread");
if (!IsOnline())
return;
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/users.get.json", true, &CVkProto::OnSearch)
- << WCHAR_PARAM("user_ids", (wchar_t *)id)
- << CHAR_PARAM("fields", "nickname, domain");
- pReq->pUserInfo = nullptr;
- Push(pReq);
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/users.get.json", true, &CVkProto::OnSearch)
+ << WCHAR_PARAM("user_ids", (wchar_t *)id) << CHAR_PARAM("fields", "nickname, domain"));
}
void CVkProto::SearchByMailThread(void *email)
@@ -58,10 +56,9 @@ void CVkProto::SearchByMailThread(void *email) debugLogA("CVkProto::OnSearchBasicThread");
if (!IsOnline())
return;
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/account.lookupContacts.json", true, &CVkProto::OnSearchByMail)
- << WCHAR_PARAM("contacts", (wchar_t *)email)
- << CHAR_PARAM("service", "email");
- Push(pReq);
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/account.lookupContacts.json", true, &CVkProto::OnSearchByMail)
+ << WCHAR_PARAM("contacts", (wchar_t *)email) << CHAR_PARAM("service", "email"));
}
void __cdecl CVkProto::SearchThread(void *p)
@@ -74,12 +71,10 @@ void __cdecl CVkProto::SearchThread(void *p) if (!IsOnline())
return;
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/users.search.json", true, &CVkProto::OnSearch)
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/users.search.json", true, &CVkProto::OnSearch)
<< WCHAR_PARAM("q", (wchar_t *)arg)
<< CHAR_PARAM("fields", "nickname, domain")
- << INT_PARAM("count", 200);
- pReq->pUserInfo = p;
- Push(pReq);
+ << INT_PARAM("count", 200))->pUserInfo = p;
}
void CVkProto::FreeProtoShearchStruct(PROTOSEARCHBYNAME *pParam)
diff --git a/protocols/VKontakte/src/vk_struct.cpp b/protocols/VKontakte/src/vk_struct.cpp index 4f7a58001a..e02430914b 100644 --- a/protocols/VKontakte/src/vk_struct.cpp +++ b/protocols/VKontakte/src/vk_struct.cpp @@ -32,17 +32,15 @@ AsyncHttpRequest::AsyncHttpRequest() bNeedsRestart = false;
bIsMainConn = false;
m_pFunc = nullptr;
- bExpUrlEncode = true;
m_reqNum = ::InterlockedIncrement(&m_reqCount);
m_priority = rpLow;
}
-AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority)
+AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url, bool bSecure, MTHttpRequestHandler pFunc, RequestPriority rpPriority)
{
cbSize = sizeof(NETLIBHTTPREQUEST);
m_bApiReq = true;
bIsMainConn = false;
- bExpUrlEncode = (BYTE)ppro->m_vkOptions.bUseStandardUrlEncode == 0;
AddHeader("Connection", "keep-alive");
if (*_url == '/') { // relative url leads to a site
@@ -69,24 +67,6 @@ AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url m_priority = rpPriority;
}
-AsyncHttpRequest::~AsyncHttpRequest()
-{
- for (int i = 0; i < headersCount; i++) {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(headers);
- mir_free(pData);
-}
-
-void AsyncHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue)
-{
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup(szName);
- headers[headersCount].szValue = mir_strdup(szValue);
- headersCount++;
-}
-
void AsyncHttpRequest::Redirect(NETLIBHTTPREQUEST *nhr)
{
for (int i = 0; i < nhr->headersCount; i++) {
@@ -208,7 +188,6 @@ CVKOptions::CVKOptions(PROTO_INTERFACE *proto) : bSendVKLinksAsAttachments(proto, "SendVKLinksAsAttachments", true),
bLoadSentAttachments(proto, "LoadSentAttachments", bSendVKLinksAsAttachments),
bUseNonStandardNotifications(proto, "UseNonStandardNotifications", false),
- bUseStandardUrlEncode(proto, "UseStandardUrlEncode", false),
bShortenLinksForAudio(proto, "ShortenLinksForAudio", true),
bAddMessageLinkToMesWAtt(proto, "AddMessageLinkToMesWAtt", true),
bSplitFormatFwdMsg(proto, "SplitFormatFwdMsg", true),
diff --git a/protocols/VKontakte/src/vk_struct.h b/protocols/VKontakte/src/vk_struct.h index 00e24f5b90..96916c6fd3 100644 --- a/protocols/VKontakte/src/vk_struct.h +++ b/protocols/VKontakte/src/vk_struct.h @@ -18,37 +18,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h"
#pragma once
-typedef void (CVkProto::*VK_REQUEST_HANDLER)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
-
-struct AsyncHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+struct AsyncHttpRequest : public MTHttpRequest<CVkProto>
{
enum RequestPriority { rpLow, rpMedium, rpHigh };
AsyncHttpRequest();
- AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, VK_REQUEST_HANDLER pFunc, RequestPriority rpPriority = rpMedium);
- ~AsyncHttpRequest();
+ AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, MTHttpRequestHandler pFunc, RequestPriority rpPriority = rpMedium);
- void AddHeader(LPCSTR, LPCSTR);
void Redirect(NETLIBHTTPREQUEST*);
- CMStringA m_szUrl;
- CMStringA m_szParam;
- VK_REQUEST_HANDLER m_pFunc;
- void *pUserInfo;
int m_iRetry;
int m_iErrorCode;
RequestPriority m_priority;
static ULONG m_reqCount;
ULONG m_reqNum;
bool m_bApiReq;
- bool bExpUrlEncode;
bool bNeedsRestart, bIsMainConn;
};
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const INT_PARAM&);
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const CHAR_PARAM&);
-AsyncHttpRequest* operator<<(AsyncHttpRequest*, const WCHAR_PARAM&);
-
struct CVkFileUploadParam : public MZeroedObject {
enum VKFileType { typeInvalid, typeImg, typeAudio, typeDoc, typeNotSupported };
wchar_t *FileName;
@@ -301,7 +288,6 @@ struct CVKOptions { CMOption<BYTE> bNotificationFilterInvites;
CMOption<BYTE> bNotificationFilterAcceptedFriends;
CMOption<BYTE> bUseNonStandardNotifications;
- CMOption<BYTE> bUseStandardUrlEncode;
CMOption<BYTE> bShortenLinksForAudio;
CMOption<BYTE> bAddMessageLinkToMesWAtt;
CMOption<BYTE> bSplitFormatFwdMsg;
diff --git a/protocols/VKontakte/src/vk_wallpost.cpp b/protocols/VKontakte/src/vk_wallpost.cpp index e90296b151..aa41fcec2a 100644 --- a/protocols/VKontakte/src/vk_wallpost.cpp +++ b/protocols/VKontakte/src/vk_wallpost.cpp @@ -40,9 +40,8 @@ void CVkProto::WallPost(MCONTACT hContact, wchar_t *pwszMsg, wchar_t *pwszUrl, b if (userID == VK_INVALID_USER || userID == VK_FEED_USER)
return;
- AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/wall.post.json", true, &CVkProto::OnReceiveSmth)
- << INT_PARAM("owner_id", userID)
- << INT_PARAM("friends_only", bFriendsOnly ? 1 : 0);
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/wall.post.json", true, &CVkProto::OnReceiveSmth);
+ pReq << INT_PARAM("owner_id", userID) << INT_PARAM("friends_only", bFriendsOnly ? 1 : 0);
if (!IsEmpty(pwszMsg))
pReq << WCHAR_PARAM("message", pwszMsg);
diff --git a/src/mir_app/src/MHttpRequest.cpp b/src/mir_app/src/MHttpRequest.cpp new file mode 100644 index 0000000000..ce511f8e4b --- /dev/null +++ b/src/mir_app/src/MHttpRequest.cpp @@ -0,0 +1,93 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-18 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +MHttpRequest::MHttpRequest() +{ + cbSize = sizeof(NETLIBHTTPREQUEST); + requestType = REQUEST_GET; +} + +MHttpRequest::~MHttpRequest() +{ + for (int i = 0; i < headersCount; i++) { + mir_free(headers[i].szName); + mir_free(headers[i].szValue); + } + mir_free(headers); + mir_free(pData); +} + +void MHttpRequest::AddHeader(LPCSTR szName, LPCSTR szValue) +{ + for (int i = 0; i < headersCount; i++) + if (!mir_strcmp(headers[i].szName, szName)) { + replaceStr(headers[i].szValue, szValue); + return; + } + + headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); + headers[headersCount].szName = mir_strdup(szName); + headers[headersCount].szValue = mir_strdup(szValue); + headersCount++; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest *pReq, const INT_PARAM ¶m) +{ + CMStringA &s = pReq->m_szParam; + if (!s.IsEmpty()) + s.AppendChar('&'); + s.AppendFormat("%s=%ld", param.szName, param.iValue); + return pReq; +} + +MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest *pReq, const INT64_PARAM ¶m) +{ + CMStringA &s = pReq->m_szParam; + if (!s.IsEmpty()) + s.AppendChar('&'); + s.AppendFormat("%s=%lld", param.szName, param.iValue); + return pReq; +} + +MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest *pReq, const CHAR_PARAM ¶m) +{ + CMStringA &s = pReq->m_szParam; + if (!s.IsEmpty()) + s.AppendChar('&'); + s.AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(param.szValue))); + return pReq; +} + +MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest *pReq, const WCHAR_PARAM ¶m) +{ + T2Utf szValue(param.wszValue); + CMStringA &s = pReq->m_szParam; + if (!s.IsEmpty()) + s.AppendChar('&'); + s.AppendFormat("%s=%s", param.szName, ptrA(mir_urlEncode(szValue))); + return pReq; +} diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index e3be5f3916..673016746d 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -671,3 +671,12 @@ g_hevSettingChanged @696 NONAME ?MetaRemoveSubHistory@MDatabaseReadonly@@UAGHPAUDBCachedContact@@@Z @704 NONAME
Chat_GetGroup @705
Chat_SetGroup @706
+??0MHttpRequest@@QAE@ABU0@@Z @707 NONAME
+??0MHttpRequest@@QAE@XZ @708 NONAME
+??1MHttpRequest@@QAE@XZ @709 NONAME
+??4MHttpRequest@@QAEAAU0@ABU0@@Z @710 NONAME
+??6@YGPAUMHttpRequest@@PAU0@ABUCHAR_PARAM@@@Z @711 NONAME
+??6@YGPAUMHttpRequest@@PAU0@ABUINT_PARAM@@@Z @712 NONAME
+??6@YGPAUMHttpRequest@@PAU0@ABUWCHAR_PARAM@@@Z @713 NONAME
+??6@YGPAUMHttpRequest@@PAU0@ABUINT64_PARAM@@@Z @714 NONAME
+?AddHeader@MHttpRequest@@QAEXPBD0@Z @715 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index bb0746bc4e..513a79e71c 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -671,3 +671,12 @@ g_hevSettingChanged @696 NONAME ?MetaRemoveSubHistory@MDatabaseReadonly@@UEAAHPEAUDBCachedContact@@@Z @704 NONAME
Chat_GetGroup @705
Chat_SetGroup @706
+??0MHttpRequest@@QEAA@AEBU0@@Z @707 NONAME
+??0MHttpRequest@@QEAA@XZ @708 NONAME
+??1MHttpRequest@@QEAA@XZ @709 NONAME
+??4MHttpRequest@@QEAAAEAU0@AEBU0@@Z @710 NONAME
+??6@YAPEAUMHttpRequest@@PEAU0@AEBUCHAR_PARAM@@@Z @711 NONAME
+??6@YAPEAUMHttpRequest@@PEAU0@AEBUINT_PARAM@@@Z @712 NONAME
+??6@YAPEAUMHttpRequest@@PEAU0@AEBUWCHAR_PARAM@@@Z @713 NONAME
+??6@YAPEAUMHttpRequest@@PEAU0@AEBUINT64_PARAM@@@Z @714 NONAME
+?AddHeader@MHttpRequest@@QEAAXPEBD0@Z @715 NONAME
diff --git a/src/mir_core/src/http.cpp b/src/mir_core/src/http.cpp index ae5a9f3ff4..fad969c680 100755 --- a/src/mir_core/src/http.cpp +++ b/src/mir_core/src/http.cpp @@ -29,11 +29,14 @@ MIR_CORE_DLL(char*) mir_urlEncode(const char *szUrl) const BYTE *s;
int outputLen;
for (outputLen = 0, s = (const BYTE*)szUrl; *s; s++) {
- if (('0' <= *s && *s <= '9') || //0-9
+ if ((*s & 0x80) ||
+ ('0' <= *s && *s <= '9') || //0-9
('A' <= *s && *s <= 'Z') || //ABC...XYZ
('a' <= *s && *s <= 'z') || //abc...xyz
- *s == '-' || *s == '_' || *s == '.' || *s == ' ' || *s == '~') outputLen++;
- else outputLen += 3;
+ *s == '-' || *s == '_' || *s == '.' || *s == ' ' || *s == '~')
+ outputLen++;
+ else
+ outputLen += 3;
}
char *szOutput = (char*)mir_alloc(outputLen+1);
@@ -42,11 +45,17 @@ MIR_CORE_DLL(char*) mir_urlEncode(const char *szUrl) char *d = szOutput;
for (s = (const BYTE*)szUrl; *s; s++) {
- if (('0' <= *s && *s <= '9') || //0-9
- ('A' <= *s && *s <= 'Z') || //ABC...XYZ
- ('a' <= *s && *s <= 'z') || //abc...xyz
- *s == '-' || *s == '_' || *s == '.' || *s == '~') *d++ = *s;
- else if (*s == ' ') *d++='+';
+ if ((*s & 0x80) ||
+ ('0' <= *s && *s <= '9') || //0-9
+ ('A' <= *s && *s <= 'Z') || //ABC...XYZ
+ ('a' <= *s && *s <= 'z') || //abc...xyz
+ *s == '-' || *s == '_' || *s == '.' || *s == '~')
+ {
+ *d++ = *s;
+ }
+ else if (*s == ' ') {
+ *d++ = '+';
+ }
else {
*d++ = '%';
*d++ = szHexDigits[*s >> 4];
|