summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-01-05 15:54:03 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-01-05 15:54:03 +0300
commit14c4e44a0a91e1ad701d4ae3c58185d25118e64e (patch)
tree50f36035466f355c74373e757bc00b6610ce6267
parent94667140aeb3886d22e4c1301423fe99aaf3fba4 (diff)
Netlib:
- NETLIBHTTPHEADER & NETLIBHTTPREQUEST obsoleted; - NETLIBHTTPREQUEST divided into MHttpRequest & MHttpResponse; - MHttpHeaders now manager headers both for MHttpRequest & MHttpResponse;
-rw-r--r--include/m_netlib.h133
-rw-r--r--libs/win32/mir_app.libbin278210 -> 290906 bytes
-rw-r--r--libs/win64/mir_app.libbin277538 -> 290624 bytes
-rw-r--r--plugins/HTTPServer/src/GuiElements.cpp13
-rw-r--r--plugins/MirLua/src/Modules/m_http.cpp272
-rw-r--r--plugins/PackUpdater/Src/Utils.cpp26
-rw-r--r--plugins/PasteIt/src/PasteToWeb.cpp44
-rw-r--r--plugins/PluginUpdater/src/Utils.cpp25
-rw-r--r--plugins/SendScreenshotPlus/src/CSend.cpp175
-rw-r--r--plugins/SendScreenshotPlus/src/CSend.h3
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp12
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h2
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp11
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_imgur.h2
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp12
-rw-r--r--plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h2
-rw-r--r--plugins/SmileyAdd/src/download.cpp39
-rw-r--r--protocols/CloudFile/src/Services/dropbox_service.cpp4
-rw-r--r--protocols/CloudFile/src/Services/google_service.cpp8
-rw-r--r--protocols/CloudFile/src/Services/microsoft_service.cpp6
-rw-r--r--protocols/CloudFile/src/Services/yandex_service.cpp6
-rw-r--r--protocols/CloudFile/src/cloud_file.cpp12
-rw-r--r--protocols/CloudFile/src/cloud_file.h6
-rw-r--r--protocols/CloudFile/src/http_request.h82
-rw-r--r--protocols/CurrencyRates/src/HTTPSession.cpp38
-rw-r--r--protocols/Discord/src/avatars.cpp6
-rw-r--r--protocols/Discord/src/connection.cpp9
-rw-r--r--protocols/Discord/src/gateway.cpp18
-rw-r--r--protocols/Discord/src/http.cpp7
-rw-r--r--protocols/Discord/src/proto.cpp18
-rw-r--r--protocols/Discord/src/proto.h26
-rw-r--r--protocols/Discord/src/server.cpp16
-rw-r--r--protocols/Facebook/src/avatars.cpp16
-rw-r--r--protocols/Facebook/src/http.cpp29
-rw-r--r--protocols/Facebook/src/proto.h4
-rw-r--r--protocols/Facebook/src/server.cpp10
-rw-r--r--protocols/Gadu-Gadu/src/avatar.cpp104
-rw-r--r--protocols/Gadu-Gadu/src/oauth.cpp155
-rw-r--r--protocols/GmailNotifier/src/check.cpp41
-rw-r--r--protocols/ICQ-WIM/src/avatars.cpp16
-rw-r--r--protocols/ICQ-WIM/src/file.cpp5
-rw-r--r--protocols/ICQ-WIM/src/groupchats.cpp4
-rw-r--r--protocols/ICQ-WIM/src/http.cpp46
-rw-r--r--protocols/ICQ-WIM/src/http.h6
-rw-r--r--protocols/ICQ-WIM/src/ignore.cpp2
-rw-r--r--protocols/ICQ-WIM/src/mra.cpp8
-rw-r--r--protocols/ICQ-WIM/src/options.cpp10
-rw-r--r--protocols/ICQ-WIM/src/poll.cpp2
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp8
-rw-r--r--protocols/ICQ-WIM/src/proto.h62
-rw-r--r--protocols/ICQ-WIM/src/server.cpp44
-rw-r--r--protocols/JabberG/src/jabber_file.cpp26
-rw-r--r--protocols/JabberG/src/jabber_ft.cpp26
-rw-r--r--protocols/JabberG/src/jabber_util.cpp12
-rw-r--r--protocols/MinecraftDynmap/src/communication.cpp130
-rw-r--r--protocols/MinecraftDynmap/src/proto.h5
-rw-r--r--protocols/MinecraftDynmap/src/utils.h11
-rw-r--r--protocols/NewsAggregator/Src/Utils.cpp118
-rw-r--r--protocols/Non-IM Contact/src/http.cpp15
-rw-r--r--protocols/SkypeWeb/src/request_queue.cpp13
-rw-r--r--protocols/SkypeWeb/src/requests/avatars.h12
-rw-r--r--protocols/SkypeWeb/src/requests/files.h12
-rw-r--r--protocols/SkypeWeb/src/skype_avatars.cpp12
-rw-r--r--protocols/SkypeWeb/src/skype_chatrooms.cpp4
-rw-r--r--protocols/SkypeWeb/src/skype_contacts.cpp8
-rw-r--r--protocols/SkypeWeb/src/skype_files.cpp8
-rw-r--r--protocols/SkypeWeb/src/skype_history_sync.cpp4
-rw-r--r--protocols/SkypeWeb/src/skype_login.cpp30
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp6
-rw-r--r--protocols/SkypeWeb/src/skype_oauth.cpp38
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp8
-rw-r--r--protocols/SkypeWeb/src/skype_profile.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h56
-rw-r--r--protocols/SkypeWeb/src/skype_search.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_trouter.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp4
-rw-r--r--protocols/SkypeWeb/src/skype_utils.h2
-rw-r--r--protocols/Steam/src/http_request.h14
-rw-r--r--protocols/Steam/src/steam_proto.h2
-rw-r--r--protocols/Steam/src/steam_request.cpp23
-rw-r--r--protocols/Tox/src/http_request.h41
-rw-r--r--protocols/Tox/src/tox_bootstrap.cpp6
-rw-r--r--protocols/Twitter/src/http.cpp4
-rw-r--r--protocols/Twitter/src/oauth.cpp4
-rw-r--r--protocols/Twitter/src/proto.h4
-rw-r--r--protocols/Twitter/src/utility.cpp6
-rw-r--r--protocols/VKontakte/src/misc.cpp27
-rw-r--r--protocols/VKontakte/src/vk_avatars.cpp6
-rw-r--r--protocols/VKontakte/src/vk_captcha.cpp8
-rw-r--r--protocols/VKontakte/src/vk_chats.cpp10
-rw-r--r--protocols/VKontakte/src/vk_feed.cpp4
-rw-r--r--protocols/VKontakte/src/vk_files.cpp12
-rw-r--r--protocols/VKontakte/src/vk_history.cpp2
-rw-r--r--protocols/VKontakte/src/vk_messages.cpp6
-rw-r--r--protocols/VKontakte/src/vk_pollserver.cpp8
-rw-r--r--protocols/VKontakte/src/vk_proto.cpp2
-rw-r--r--protocols/VKontakte/src/vk_proto.h60
-rw-r--r--protocols/VKontakte/src/vk_queue.cpp10
-rw-r--r--protocols/VKontakte/src/vk_search.cpp4
-rw-r--r--protocols/VKontakte/src/vk_status.cpp4
-rw-r--r--protocols/VKontakte/src/vk_struct.cpp4
-rw-r--r--protocols/VKontakte/src/vk_struct.h2
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp26
-rw-r--r--protocols/Weather/src/weather_http.cpp37
-rw-r--r--protocols/WebView/src/webview_getdata.cpp22
-rw-r--r--protocols/WhatsApp/src/avatars.cpp10
-rw-r--r--protocols/WhatsApp/src/server.cpp9
-rw-r--r--protocols/WhatsApp/src/utils.cpp15
-rw-r--r--src/mir_app/mir_app.vcxproj2
-rw-r--r--src/mir_app/mir_app.vcxproj.filters6
-rw-r--r--src/mir_app/src/MHttpHeaders.cpp82
-rw-r--r--src/mir_app/src/MHttpRequest.cpp22
-rw-r--r--src/mir_app/src/MHttpResponse.cpp60
-rw-r--r--src/mir_app/src/mir_app.def58
-rw-r--r--src/mir_app/src/mir_app64.def58
-rw-r--r--src/mir_app/src/netlib.h55
-rw-r--r--src/mir_app/src/netlib_autoproxy.cpp12
-rw-r--r--src/mir_app/src/netlib_http.cpp328
-rw-r--r--src/mir_app/src/netlib_openconn.cpp9
-rw-r--r--src/mir_app/src/netlib_websocket.cpp13
121 files changed, 1335 insertions, 1935 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h
index 0f8cdc2015..3ccf546860 100644
--- a/include/m_netlib.h
+++ b/include/m_netlib.h
@@ -39,7 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// a pointer, I have decided to diverge from the rest of Miranda and go with
// the convention that functions return false on failure and nonzero on success.
-struct NETLIBHTTPREQUEST;
+struct MHttpRequest;
struct NETLIBOPENCONNECTION;
#define NETLIB_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.112 Safari/537.36"
@@ -402,16 +402,6 @@ EXTERN_C MIR_APP_DLL(NETLIBIPLIST*) Netlib_GetMyIp(bool bGlobalOnly);
/////////////////////////////////////////////////////////////////////////////////////////
-struct NETLIBHTTPHEADER
-{
- char *szName;
- char *szValue;
-};
-
-EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, const char *pszName);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
#define REQUEST_RESPONSE 0 // used by structure returned by MS_NETLIB_RECVHTTPHEADERS
#define REQUEST_GET 1
#define REQUEST_POST 2
@@ -434,80 +424,93 @@ EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, cons
#define NLHRF_DUMPASTEXT 0x00080000 // dump posted and reply data as text. Headers are always dumped as text.
#define NLHRF_NODUMPSEND 0x00100000 // do not dump sent message.
-struct MIR_APP_EXPORT NETLIBHTTPREQUEST
+struct MHttpHeader
{
- int requestType; // a REQUEST_
- uint32_t flags;
- char *szUrl;
- NETLIBHTTPHEADER *headers; // If this is a POST request and headers doesn't contain a Content-Length it'll be added automatically
- int headersCount;
- char *pData; // data to be sent in POST request.
- int dataLength; // must be 0 for REQUEST_GET/REQUEST_CONNECT
- int resultCode;
- char *szResultDescr;
- HNETLIBCONN nlc;
- int timeout;
+ MHttpHeader(const char *_1, const char *_2) :
+ szName(mir_strdup(_1)),
+ szValue(mir_strdup(_2))
+ {}
- CMStringA GetCookies() const;
+ ptrA szName, szValue;
+};
+
+struct MIR_APP_EXPORT MHttpHeaders : public OBJLIST<MHttpHeader>
+{
+ MHttpHeaders();
+ ~MHttpHeaders();
__forceinline const char *operator[](const char *pszName) {
- return Netlib_GetHeader(this, pszName);
+ return FindHeader(pszName);
}
+
+ void AddHeader(const char *pszName, const char *pszValue);
+ void DeleteHeader(const char *pszName);
+ char* FindHeader(const char *pszName) const;
+ CMStringA GetCookies() const;
};
-/////////////////////////////////////////////////////////////////////////////////////////
-// Free the memory used by a NETLIBHTTPREQUEST structure
-//
-// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
-// This should only be called on structures returned by
-// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
-// arbitrary structure will have disastrous results.
-// Errors: ERROR_INVALID_PARAMETER
+struct MIR_APP_EXPORT MHttpRequest : public MHttpHeaders, public MNonCopyable, public MZeroedObject
+{
+ MHttpRequest();
+ ~MHttpRequest();
-EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST*);
+ int requestType = REQUEST_GET; // a REQUEST_
+ uint32_t flags;
+ CMStringA m_szUrl, m_szParam;
+ HNETLIBCONN nlc;
+ int timeout;
+ void *pUserInfo;
-/////////////////////////////////////////////////////////////////////////////////////////
-// smart pointer for NETLIBHTTPREQUEST via a call of Netlib_FreeHttpRequest()
+ void SetData(const void *pData, size_t cbLen);
+};
+
+struct MIR_APP_EXPORT MHttpResponse : public MHttpHeaders, public MNonCopyable, public MZeroedObject
+{
+ MHttpResponse();
+ ~MHttpResponse();
+
+ int resultCode;
+ char *szUrl, *szResultDescr;
+ HNETLIBCONN nlc;
+ CMStringA body;
+};
-#ifdef __cplusplus
class NLHR_PTR
{
-protected:
- NETLIBHTTPREQUEST *_p;
+ MHttpResponse *_p;
public:
- __forceinline explicit NLHR_PTR(NETLIBHTTPREQUEST *p) : _p(p) {}
+ __forceinline explicit NLHR_PTR(MHttpResponse *p) : _p(p) {}
- __forceinline NETLIBHTTPREQUEST* operator=(INT_PTR i_p)
+ __forceinline MHttpResponse *operator=(INT_PTR i_p)
{
- return operator=((NETLIBHTTPREQUEST*)i_p);
+ return operator=((MHttpResponse *)i_p);
}
- __forceinline NETLIBHTTPREQUEST* operator=(NETLIBHTTPREQUEST *p)
+ __forceinline MHttpResponse* operator=(MHttpResponse *p)
{
if (_p)
- Netlib_FreeHttpRequest(_p);
+ delete _p;
_p = p;
return _p;
}
- __forceinline operator NETLIBHTTPREQUEST*() const { return _p; }
- __forceinline NETLIBHTTPREQUEST* operator->() const { return _p; }
+ __forceinline operator MHttpResponse*() const { return _p; }
+ __forceinline MHttpResponse* operator->() const { return _p; }
__forceinline ~NLHR_PTR()
{
- Netlib_FreeHttpRequest(_p);
+ delete _p;
}
};
-struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
-{
- MHttpRequest();
- ~MHttpRequest();
+EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(MHttpResponse *);
- CMStringA m_szUrl;
- CMStringA m_szParam;
- void *pUserInfo = nullptr;
-
- void AddHeader(const char *szName, const char *szValue);
-};
+/////////////////////////////////////////////////////////////////////////////////////////
+// Free the memory used by a MHttpRequest structure
+//
+// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This should only be called on structures returned by
+// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
+// arbitrary structure will have disastrous results.
+// Errors: ERROR_INVALID_PARAMETER
template <class T>
class MTHttpRequest : public MHttpRequest
@@ -516,21 +519,25 @@ public:
__forceinline MTHttpRequest()
{}
- typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
+ typedef void (T::*MTHttpRequestHandler)(MHttpResponse*, 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 INT64_PARAM&);
MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
-#endif
+__forceinline MHttpRequest* operator<<(MHttpRequest &req, const INT_PARAM &param) { return &req << param; }
+__forceinline MHttpRequest* operator<<(MHttpRequest &req, const CHAR_PARAM &param) { return &req << param; }
+__forceinline MHttpRequest* operator<<(MHttpRequest &req, const INT64_PARAM &param) { return &req << param; }
+__forceinline MHttpRequest* operator<<(MHttpRequest &req, const WCHAR_PARAM &param) { return &req << param; }
+
/////////////////////////////////////////////////////////////////////////////////////////
// Do an entire HTTP transaction
//
-// Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Returns a pointer to another MHttpRequest structure on success, NULL on failure.
// Call Netlib_FreeHttpRequest() to free this.
// hUser must have been returned by MS_NETLIB_REGISTERUSER
// nlhr.szUrl should be a full HTTP URL. If it does not start with http:// , that
@@ -555,7 +562,7 @@ MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above
// list of functions
-EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_HttpTransaction(HNETLIBUSER hNlu, NETLIBHTTPREQUEST *pRequest);
+EXTERN_C MIR_APP_DLL(MHttpResponse *) Netlib_HttpTransaction(HNETLIBUSER hNlu, MHttpRequest *pRequest);
/////////////////////////////////////////////////////////////////////////////////////////
// Send data over a connection
@@ -753,7 +760,7 @@ struct WSHeader
};
// connects to a WebSocket server
-EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
+EXTERN_C MIR_APP_DLL(MHttpResponse*) WebSocket_Connect(HNETLIBUSER, const char *szHost, const MHttpHeaders *pHeaders = nullptr);
// validates that the provided buffer contains full WebSocket datagram
EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize);
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 0adef99d45..6f707bba15 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index 5ed62c15f7..87a691b6e8 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/HTTPServer/src/GuiElements.cpp b/plugins/HTTPServer/src/GuiElements.cpp
index 329258e1b9..a3f02f86bb 100644
--- a/plugins/HTTPServer/src/GuiElements.cpp
+++ b/plugins/HTTPServer/src/GuiElements.cpp
@@ -141,11 +141,9 @@ unsigned long GetExternIP(const char *szURL, const char *szPattern)
{
HCURSOR hPrevCursor = ::SetCursor(::LoadCursor(nullptr, IDC_WAIT));
- NETLIBHTTPREQUEST nlhr;
- memset(&nlhr, 0, sizeof(nlhr));
- nlhr.requestType = REQUEST_GET;
+ MHttpRequest nlhr;
nlhr.flags = NLHRF_DUMPASTEXT;
- nlhr.szUrl = (char*)szURL;
+ nlhr.m_szUrl = szURL;
IN_ADDR externIP;
externIP.s_addr = 0;
@@ -153,16 +151,15 @@ unsigned long GetExternIP(const char *szURL, const char *szPattern)
NLHR_PTR nlreply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (nlreply) {
if (nlreply->resultCode >= 200 && nlreply->resultCode < 300) {
- nlreply->pData[nlreply->dataLength] = 0;// make sure its null terminated
- char * pszIp = strstr(nlreply->pData, szPattern);
+ char *pszIp = strstr(nlreply->body.GetBuffer(), szPattern);
if (pszIp == nullptr)
- pszIp = nlreply->pData;
+ pszIp = nlreply->body.GetBuffer();
else
pszIp += mir_strlen(szPattern);
while ((*pszIp < '0' || *pszIp > '9') && *pszIp)
pszIp++;
- char * pszEnd = pszIp;
+ char *pszEnd = pszIp;
while ((*pszEnd >= '0' && *pszEnd <= '9') || *pszEnd == '.')
pszEnd++;
*pszEnd = NULL;
diff --git a/plugins/MirLua/src/Modules/m_http.cpp b/plugins/MirLua/src/Modules/m_http.cpp
index 7526b29612..fcc0365078 100644
--- a/plugins/MirLua/src/Modules/m_http.cpp
+++ b/plugins/MirLua/src/Modules/m_http.cpp
@@ -2,154 +2,22 @@
#define MT_NETLIBHTTPHEADERS "NETLIBHTTPHEADERS"
-static NETLIBHTTPREQUEST* CreateRequest()
+static MHttpRequest* CreateRequest()
{
- NETLIBHTTPREQUEST *request = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST));
+ MHttpRequest *request = new MHttpRequest();
request->flags = NLHRF_HTTP11 | NLHRF_NODUMP;
return request;
}
-static void SetUrl(NETLIBHTTPREQUEST *request, const char *url)
+static void SetUrl(MHttpRequest *request, const char *url)
{
- request->szUrl = mir_strdup(url);
- if (mir_strncmpi(request->szUrl, "https", 5) == 0)
+ request->m_szUrl = url;
+ if (mir_strncmpi(request->m_szUrl, "https", 5) == 0)
request->flags |= NLHRF_SSL;
else
request->flags &= ~(NLHRF_SSL);
}
-static void SetHeader(NETLIBHTTPREQUEST *request, const char *name, const char *value)
-{
- for (int i = 0; i < request->headersCount; i++) {
- if (mir_strcmp(request->headers[i].szName, name) == 0) {
- mir_free(request->headers[i].szValue);
- request->headers[i].szValue = mir_strdup(value);
- return;
- }
- }
-
- request->headers = (NETLIBHTTPHEADER*)mir_realloc(request->headers,
- sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
- NETLIBHTTPHEADER &header = request->headers[request->headersCount];
- header.szName = mir_strdup(name);
- header.szValue = mir_strdup(value);
- request->headersCount++;
-}
-
-static void DropHeader(NETLIBHTTPREQUEST *request, const char *name)
-{
- for (int i = 0; i < request->headersCount - 1; i++) {
- if (mir_strcmp(request->headers[i].szName, name) == 0) {
- mir_free(request->headers[i].szName);
- mir_free(request->headers[i].szValue);
- request->headersCount--;
- request->headers[i].szName = request->headers[request->headersCount].szName;
- request->headers[i].szValue = request->headers[request->headersCount].szValue;
- }
- }
- request->headers = (NETLIBHTTPHEADER*)mir_realloc(request->headers,
- sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
-}
-
-static void ClearHeaders(NETLIBHTTPREQUEST *request)
-{
- for (int i = 0; i < request->headersCount; i++) {
- mir_free(request->headers[i].szName);
- mir_free(request->headers[i].szValue);
- }
- request->headersCount = 0;
- request->headers = (NETLIBHTTPHEADER*)mir_realloc(request->headers,
- sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
-}
-
-static void SetContent(NETLIBHTTPREQUEST *request, const char *data, size_t length)
-{
- if (request->pData != nullptr)
- mir_free(request->pData);
- request->pData = mir_strdup(data);
- request->dataLength = (int)length;
-}
-
-/***********************************************/
-
-struct NETLIBHTTPHEADERS
-{
- const NETLIBHTTPHEADER *headers;
- int count;
-};
-
-static int headers_Iterator(lua_State *L)
-{
- NETLIBHTTPHEADER *headers = (NETLIBHTTPHEADER*)lua_touserdata(L, lua_upvalueindex(1));
- int count = lua_tointeger(L, lua_upvalueindex(2));
- int idx = lua_tointeger(L, lua_upvalueindex(3));
-
- if (idx < count) {
- lua_pushstring(L, headers[idx].szName);
- lua_pushstring(L, headers[idx].szValue);
- lua_pushinteger(L, idx + 1);
- lua_replace(L, lua_upvalueindex(3));
- return 2;
- }
-
- lua_pushnil(L);
-
- return 1;
-}
-
-static int headers__pairs(lua_State *L)
-{
- NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
-
- lua_pushlightuserdata(L, (void*)headers->headers);
- lua_pushinteger(L, headers->count);
- lua_pushinteger(L, 0);
- lua_pushcclosure(L, headers_Iterator, 3);
-
- return 1;
-}
-
-static int headers__index(lua_State *L)
-{
- NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
-
- if (lua_isinteger(L, 2)) {
- int idx = lua_tointeger(L, 2);
- if (idx > 0 && idx <= headers->count) {
- lua_pushstring(L, headers->headers[idx - 1].szValue);
- return 1;
- }
- }
-
- const char *key = lua_tostring(L, 2);
- for (int i = 0; i < headers->count; i++) {
- if (mir_strcmp(headers->headers[i].szName, key) == 0) {
- lua_pushstring(L, headers->headers[i].szValue);
- return 1;
- }
- }
-
- lua_pushnil(L);
-
- return 1;
-}
-
-static int headers__len(lua_State *L)
-{
- NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
- lua_pushinteger(L, headers->count);
- return 1;
-}
-
-static const luaL_Reg headersApi[] =
-{
- { "__pairs", headers__pairs },
- { "__index", headers__index },
- { "__len", headers__len },
-
- { nullptr, nullptr }
-};
-
/***********************************************/
#define MT_NETLIBHTTPCONTENT "NETLIBHTTPCONTENT"
@@ -202,10 +70,10 @@ static const luaL_Reg contentApi[] =
#define MT_NETLIBHTTPRESPONSE "NETLIBHTTPRESPONSE"
-static NETLIBHTTPREQUEST* response_Create(lua_State *L, NETLIBHTTPREQUEST *request)
+static MHttpResponse* response_Create(lua_State *L, MHttpRequest *request)
{
- NETLIBHTTPREQUEST *response = Netlib_HttpTransaction(g_plugin.hNetlib, request);
- NETLIBHTTPREQUEST **udata = (NETLIBHTTPREQUEST**)lua_newuserdata(L, sizeof(NETLIBHTTPREQUEST*));
+ auto *response = Netlib_HttpTransaction(g_plugin.hNetlib, request);
+ MHttpResponse **udata = (MHttpResponse **)lua_newuserdata(L, sizeof(MHttpResponse *));
*udata = response;
luaL_setmetatable(L, MT_NETLIBHTTPRESPONSE);
return response;
@@ -213,7 +81,7 @@ static NETLIBHTTPREQUEST* response_Create(lua_State *L, NETLIBHTTPREQUEST *reque
static int response__index(lua_State *L)
{
- NETLIBHTTPREQUEST *response = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
+ MHttpResponse *response = *(MHttpResponse **)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
const char *key = lua_tostring(L, 2);
if (mir_strcmpi(key, "IsSuccess") == 0) {
@@ -226,16 +94,16 @@ static int response__index(lua_State *L)
}
if (mir_strcmpi(key, "StatusCode") == 0)
lua_pushinteger(L, response->resultCode);
- else if (mir_strcmpi(key, "Headers") == 0) {
+ /*else if (mir_strcmpi(key, "Headers") == 0) {
NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)lua_newuserdata(L, sizeof(NETLIBHTTPHEADERS));
headers->headers = response->headers;
headers->count = response->headersCount;
luaL_setmetatable(L, MT_NETLIBHTTPHEADERS);
- }
+ }*/
else if (mir_strcmpi(key, "Content") == 0) {
NETLIBHTTPCONTENT *content = (NETLIBHTTPCONTENT*)lua_newuserdata(L, sizeof(NETLIBHTTPCONTENT));
- content->data = response->pData;
- content->length = response->dataLength;
+ content->data = response->body.GetBuffer();
+ content->length = response->body.GetLength();
luaL_setmetatable(L, MT_NETLIBHTTPCONTENT);
}
else
@@ -246,7 +114,7 @@ static int response__index(lua_State *L)
static int response__gc(lua_State *L)
{
- NETLIBHTTPREQUEST **response = (NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
+ MHttpResponse **response = (MHttpResponse **)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
Netlib_FreeHttpRequest(*response);
return 0;
}
@@ -267,7 +135,7 @@ struct HttpRequestParam
int threadRef;
int callbackRef;
- NETLIBHTTPREQUEST *request;
+ MHttpRequest *request;
};
static void __cdecl SendHttpRequestThread(HttpRequestParam *param)
@@ -280,11 +148,11 @@ static void __cdecl SendHttpRequestThread(HttpRequestParam *param)
luaL_unref(param->L, LUA_REGISTRYINDEX, param->callbackRef);
luaL_unref(param->L, LUA_REGISTRYINDEX, param->threadRef);
- Netlib_FreeHttpRequest(param->request);
+ delete param->request;
delete param;
}
-static void SendRequestAsync(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
+static void SendRequestAsync(lua_State *L, int idx, MHttpRequest *request)
{
HttpRequestParam *param = new HttpRequestParam();
param->request = request;
@@ -297,13 +165,13 @@ static void SendRequestAsync(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
/***********************************************/
-#define MT_NETLIBHTTPREQUEST "NETLIBHTTPREQUEST"
+#define MT_NETLIBHTTPREQUEST "MHttpRequest"
static const char *httpMethods[] = { "GET", "POST", "PUT", "DELETE", nullptr };
static int request_SetMethod(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
request->requestType = (1 << (luaL_checkoption(L, 2, nullptr, httpMethods)));
lua_pushvalue(L, 1);
return 1;
@@ -311,7 +179,7 @@ static int request_SetMethod(lua_State *L)
static int request_SetUrl(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
const char *url = luaL_checkstring(L, 2);
SetUrl(request, url);
@@ -322,14 +190,14 @@ static int request_SetUrl(lua_State *L)
static int request_SetHeaders(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
luaL_checktype(L, 2, LUA_TTABLE);
- ClearHeaders(request);
+ request->destroy();
for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
const char *name = lua_tostring(L, -2);
const char *value = lua_tostring(L, -1);
- SetHeader(request, name, value);
+ request->AddHeader(name, value);
}
lua_pushvalue(L, 1);
@@ -338,34 +206,34 @@ static int request_SetHeaders(lua_State *L)
static int request_SetContent(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
switch (lua_type(L, 2)) {
case LUA_TNONE:
case LUA_TNIL:
- SetContent(request, nullptr, 0);
- DropHeader(request, "Content-Type");
+ request->SetData(nullptr, 0);
+ request->DeleteHeader("Content-Type");
break;
case LUA_TSTRING:
- {
- const char *data = lua_tostring(L, 2);
- SetContent(request, data, mir_strlen(data));
- SetHeader(request, "Content-Type", "text/plain");
+ {
+ const char *data = lua_tostring(L, 2);
+ request->SetData(data, mir_strlen(data));
+ request->AddHeader("Content-Type", "text/plain");
+ }
break;
- }
case LUA_TTABLE:
- {
- CMStringA formData;
- for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
- const char *name = lua_tostring(L, -2);
- const char *value = lua_tostring(L, -1);
- formData.AppendFormat("&%s=%s", name, value);
+ {
+ CMStringA formData;
+ for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
+ const char *name = lua_tostring(L, -2);
+ const char *value = lua_tostring(L, -1);
+ formData.AppendFormat("&%s=%s", name, value);
+ }
+ formData.Delete(0);
+ request->SetData(formData.GetString(), formData.GetLength());
+ request->AddHeader("Content-Type", "application/x-www-form-urlencoded");
}
- formData.Delete(0);
- SetContent(request, formData.GetString(), formData.GetLength());
- SetHeader(request, "Content-Type", "application/x-www-form-urlencoded");
break;
- }
default:
luaL_argerror(L, 2, luaL_typename(L, 2));
}
@@ -376,14 +244,14 @@ static int request_SetContent(lua_State *L)
static int request_SetContentType(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
if (!lua_isstring(L, 2)) {
lua_pushvalue(L, 1);
return 1;
}
const char *type = lua_tostring(L, 2);
- SetHeader(request, "Content-Type", type);
+ request->AddHeader("Content-Type", type);
lua_pushvalue(L, 1);
return 1;
@@ -391,7 +259,7 @@ static int request_SetContentType(lua_State *L)
static int request_SetTimeout(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
request->timeout = luaL_optinteger(L, -1, 0);
lua_pushvalue(L, 1);
return 1;
@@ -399,22 +267,16 @@ static int request_SetTimeout(lua_State *L)
static int request_Send(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
- NETLIBHTTPREQUEST *newRequest = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST));
+ MHttpRequest *newRequest = new MHttpRequest();
newRequest->flags = request->flags;
newRequest->requestType = request->requestType;
- newRequest->szUrl = mir_strdup(request->szUrl);
- newRequest->headersCount = request->headersCount;
- newRequest->headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
- for (int i = 0; i < request->headersCount; i++) {
- newRequest->headers[i].szName = mir_strdup(request->headers[i].szName);
- newRequest->headers[i].szValue = mir_strdup(request->headers[i].szValue);
- }
- newRequest->dataLength = request->dataLength;
- newRequest->pData = (char*)mir_calloc(request->dataLength + 1);
- memcpy(newRequest->pData, request->pData, request->dataLength);
+ newRequest->m_szUrl = request->m_szUrl;
+ newRequest->m_szParam = request->m_szParam;
newRequest->timeout = request->timeout;
+ for (auto &it : *request)
+ newRequest->AddHeader(it->szName, it->szValue);
if (lua_isfunction(L, 2)) {
SendRequestAsync(L, 2, newRequest);
@@ -422,8 +284,7 @@ static int request_Send(lua_State *L)
}
response_Create(L, newRequest);
- Netlib_FreeHttpRequest(newRequest);
-
+ delete newRequest;
return 1;
}
@@ -454,8 +315,8 @@ static int request__index(lua_State *L)
static int request__gc(lua_State *L)
{
- NETLIBHTTPREQUEST *request = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
- Netlib_FreeHttpRequest(request);
+ MHttpRequest *request = *(MHttpRequest**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+ delete request;
return 0;
}
@@ -471,8 +332,8 @@ static const luaL_Reg requestApi[] =
static int http_Request(lua_State *L)
{
- NETLIBHTTPREQUEST *request = CreateRequest();
- NETLIBHTTPREQUEST **udata = (NETLIBHTTPREQUEST**)lua_newuserdata(L, sizeof(NETLIBHTTPREQUEST*));
+ MHttpRequest *request = CreateRequest();
+ MHttpRequest **udata = (MHttpRequest**)lua_newuserdata(L, sizeof(MHttpRequest*));
*udata = request;
request->requestType = (1 << (luaL_checkoption(L, 1, nullptr, httpMethods)));
SetUrl(request, luaL_checkstring(L, 2));
@@ -483,7 +344,7 @@ static int http_Request(lua_State *L)
static int http_Get(lua_State *L)
{
- NETLIBHTTPREQUEST *request = CreateRequest();
+ MHttpRequest *request = CreateRequest();
request->requestType = REQUEST_GET;
const char *url = luaL_checkstring(L, 1);
@@ -495,14 +356,13 @@ static int http_Get(lua_State *L)
}
response_Create(L, request);
- Netlib_FreeHttpRequest(request);
-
+ delete request;
return 1;
}
static int http_Post(lua_State *L)
{
- NETLIBHTTPREQUEST *request = CreateRequest();
+ MHttpRequest *request = CreateRequest();
request->requestType = REQUEST_POST;
const char *url = luaL_checkstring(L, 1);
@@ -524,14 +384,13 @@ static int http_Post(lua_State *L)
}
response_Create(L, request);
- Netlib_FreeHttpRequest(request);
-
+ delete request;
return 1;
}
static int http_Put(lua_State *L)
{
- NETLIBHTTPREQUEST *request = CreateRequest();
+ MHttpRequest *request = CreateRequest();
request->requestType = REQUEST_PUT;
const char *url = luaL_checkstring(L, 1);
@@ -553,14 +412,13 @@ static int http_Put(lua_State *L)
}
response_Create(L, request);
- Netlib_FreeHttpRequest(request);
-
+ delete request;
return 1;
}
static int http_Delete(lua_State *L)
{
- NETLIBHTTPREQUEST *request = CreateRequest();
+ MHttpRequest *request = CreateRequest();
request->requestType = REQUEST_DELETE;
const char *url = luaL_checkstring(L, 1);
@@ -609,9 +467,9 @@ LUAMOD_API int luaopen_m_http(lua_State *L)
luaL_setfuncs(L, responseApi, 0);
lua_pop(L, 1);
- luaL_newmetatable(L, MT_NETLIBHTTPHEADERS);
- luaL_setfuncs(L, headersApi, 0);
- lua_pop(L, 1);
+ // luaL_newmetatable(L, MT_NETLIBHTTPHEADERS);
+ // luaL_setfuncs(L, headersApi, 0);
+ // lua_pop(L, 1);
luaL_newmetatable(L, MT_NETLIBHTTPCONTENT);
luaL_setfuncs(L, contentApi, 0);
diff --git a/plugins/PackUpdater/Src/Utils.cpp b/plugins/PackUpdater/Src/Utils.cpp
index 1c24905cac..9e6a563606 100644
--- a/plugins/PackUpdater/Src/Utils.cpp
+++ b/plugins/PackUpdater/Src/Utils.cpp
@@ -107,38 +107,28 @@ void LoadOptions()
BOOL DownloadFile(LPCTSTR tszURL, LPCTSTR tszLocal)
{
- NETLIBHTTPREQUEST nlhr = { 0 };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_REDIRECT | NLHRF_DUMPASTEXT | NLHRF_HTTP11;
- char* szUrl = mir_u2a(tszURL);
- nlhr.szUrl = szUrl;
- nlhr.headersCount = 4;
- nlhr.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount);
- nlhr.headers[0].szName = "User-Agent";
- nlhr.headers[0].szValue = NETLIB_USER_AGENT;
- nlhr.headers[1].szName = "Connection";
- nlhr.headers[1].szValue = "close";
- nlhr.headers[2].szName = "Cache-Control";
- nlhr.headers[2].szValue = "no-cache";
- nlhr.headers[3].szName = "Pragma";
- nlhr.headers[3].szValue = "no-cache";
+ nlhr.m_szUrl = _T2A(tszURL);
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Connection", "close");
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
bool ret = false;
NLHR_PTR pReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (pReply) {
- if (200 == pReply->resultCode && pReply->dataLength > 0) {
+ if (200 == pReply->resultCode && !pReply->body.IsEmpty()) {
HANDLE hFile = CreateFile(tszLocal, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
DWORD dwBytes;
- WriteFile(hFile, pReply->pData, (uint32_t)pReply->dataLength, &dwBytes, nullptr);
+ WriteFile(hFile, pReply->body, pReply->body.GetLength(), &dwBytes, nullptr);
ret = true;
if (hFile)
CloseHandle(hFile);
}
}
- mir_free(szUrl);
- mir_free(nlhr.headers);
-
DlgDld = ret;
return ret;
}
diff --git a/plugins/PasteIt/src/PasteToWeb.cpp b/plugins/PasteIt/src/PasteToWeb.cpp
index 9d1ad7ac5f..5fdfc7afec 100644
--- a/plugins/PasteIt/src/PasteToWeb.cpp
+++ b/plugins/PasteIt/src/PasteToWeb.cpp
@@ -426,47 +426,19 @@ char *PasteToWeb::SendToWeb(char *url, std::map<std::string, std::string> &heade
WideCharToMultiByte(CP_UTF8, 0, content.c_str(), -1, contentBytes, cbLen, nullptr, nullptr);
--cbLen;
- int nHeaders = 0;
- for (std::map<std::string, std::string>::iterator it = headers.begin(); it != headers.end(); ++it) {
- ++nHeaders;
- }
-
- NETLIBHTTPHEADER *httpHeaders = new NETLIBHTTPHEADER[nHeaders];
-
- NETLIBHTTPREQUEST nlhr = { 0 };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_POST;
nlhr.flags = NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT | NLHPIF_HTTP11;
- nlhr.szUrl = url;
- nlhr.headers = httpHeaders;
- nlhr.pData = contentBytes;
- nlhr.dataLength = cbLen;
- nHeaders = 0;
- std::list<char *> mallBuf;
- for (std::map<std::string, std::string>::iterator it = headers.begin(); it != headers.end(); ++it) {
- char *b1 = new char[it->first.length() + 1];
- char *b2 = new char[it->second.length() + 1];
- mir_strncpy(b1, it->first.c_str(), it->first.length() + 1);
- mir_strncpy(b2, it->second.c_str(), it->second.length() + 1);
- httpHeaders[nHeaders].szName = b1;
- httpHeaders[nHeaders].szValue = b2;
- mallBuf.push_back(b1);
- mallBuf.push_back(b2);
- ++nHeaders;
- }
+ nlhr.m_szUrl = url;
+ nlhr.SetData(contentBytes, cbLen);
+ for (auto it : headers)
+ nlhr.AddHeader(it.first.c_str(), it.second.c_str());
char *resCont = nullptr;
- nlhr.headersCount = nHeaders;
NLHR_PTR nlhrReply(Netlib_HttpTransaction(g_hNetlibUser, &nlhr));
- if (nlhrReply != nullptr) {
- if (nlhrReply->resultCode == 200) {
- resCont = nlhrReply->pData;
- nlhrReply->pData = 0;
- }
- }
-
- delete[] httpHeaders;
- for (std::list<char *>::iterator it = mallBuf.begin(); it != mallBuf.end(); ++it)
- delete *it;
+ if (nlhrReply != nullptr)
+ if (nlhrReply->resultCode == 200)
+ resCont = nlhrReply->body.Detach();
mir_free(contentBytes);
return resCont;
diff --git a/plugins/PluginUpdater/src/Utils.cpp b/plugins/PluginUpdater/src/Utils.cpp
index 9a30007c66..4cc80eaec1 100644
--- a/plugins/PluginUpdater/src/Utils.cpp
+++ b/plugins/PluginUpdater/src/Utils.cpp
@@ -143,22 +143,17 @@ int DownloadFile(FILEURL *pFileURL, HNETLIBCONN &nlc)
#endif
szUserAgent.Append(")");
- NETLIBHTTPHEADER headers[4] = {
- { "User-Agent", szUserAgent.GetBuffer() },
- { "Connection", "close" },
- { "Cache-Control", "no-cache" },
- { "Pragma", "no-cache" }
- };
-
ptrA szUrl(mir_u2a(pFileURL->wszDownloadURL));
- NETLIBHTTPREQUEST nlhr = {};
+ MHttpRequest nlhr;
nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_PERSISTENT;
nlhr.requestType = REQUEST_GET;
nlhr.nlc = nlc;
- nlhr.szUrl = szUrl;
- nlhr.headersCount = _countof(headers);
- nlhr.headers = headers;
+ nlhr.m_szUrl = szUrl;
+ nlhr.AddHeader("User-Agent", szUserAgent);
+ nlhr.AddHeader("Connection", "close");
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
for (int i = 0; i < MAX_RETRIES; i++) {
Netlib_LogfW(g_hNetlibUser, L"Downloading file %s to %s (attempt %d)", pFileURL->wszDownloadURL, pFileURL->wszDiskPath, i + 1);
@@ -170,14 +165,14 @@ int DownloadFile(FILEURL *pFileURL, HNETLIBCONN &nlc)
}
nlc = pReply->nlc;
- if (pReply->resultCode != 200 || pReply->dataLength <= 0) {
+ if (pReply->resultCode != 200 || pReply->body.IsEmpty()) {
Netlib_LogfW(g_hNetlibUser, L"Downloading file %s failed with error %d", pFileURL->wszDownloadURL, pReply->resultCode);
return pReply->resultCode;
}
// Check CRC sum
if (pFileURL->CRCsum) {
- int crc = crc32(0, (unsigned char *)pReply->pData, pReply->dataLength);
+ int crc = crc32(0, (unsigned char *)pReply->body.c_str(), pReply->body.GetLength());
if (crc != pFileURL->CRCsum) {
// crc check failed, try again
Netlib_LogfW(g_hNetlibUser, L"crc check failed for file %s", pFileURL->wszDiskPath);
@@ -190,7 +185,7 @@ int DownloadFile(FILEURL *pFileURL, HNETLIBCONN &nlc)
HANDLE hFile = CreateFile(pFileURL->wszDiskPath, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE) {
// write the downloaded file directly
- WriteFile(hFile, pReply->pData, (DWORD)pReply->dataLength, &dwBytes, nullptr);
+ WriteFile(hFile, pReply->body, pReply->body.GetLength(), &dwBytes, nullptr);
CloseHandle(hFile);
}
else {
@@ -199,7 +194,7 @@ int DownloadFile(FILEURL *pFileURL, HNETLIBCONN &nlc)
mir_snwprintf(wszTempFile, L"%s\\pulocal.tmp", g_wszTempPath);
hFile = CreateFile(wszTempFile, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE) {
- WriteFile(hFile, pReply->pData, (DWORD)pReply->dataLength, &dwBytes, nullptr);
+ WriteFile(hFile, pReply->body, pReply->body.GetLength(), &dwBytes, nullptr);
CloseHandle(hFile);
PU::SafeMoveFile(wszTempFile, pFileURL->wszDiskPath);
}
diff --git a/plugins/SendScreenshotPlus/src/CSend.cpp b/plugins/SendScreenshotPlus/src/CSend.cpp
index 9290e8d923..23f2c19c5c 100644
--- a/plugins/SendScreenshotPlus/src/CSend.cpp
+++ b/plugins/SendScreenshotPlus/src/CSend.cpp
@@ -422,36 +422,10 @@ const char* CSend::GetHTMLContent(char* str, const char* startTag, const char* e
return begin;
}
-static void HTTPFormAppendData(NETLIBHTTPREQUEST* nlhr, size_t* dataMax, char** dataPos, const char* data, size_t len)
-{
- nlhr->dataLength = (*dataPos - nlhr->pData);
- if (nlhr->dataLength + len >= *dataMax) {
- *dataPos = nlhr->pData;
- *dataMax += 0x1000 + 0x1000 * (len >> 12);
- nlhr->pData = (char*)mir_realloc(nlhr->pData, *dataMax);
- if (!nlhr->pData) mir_free(*dataPos);
- *dataPos = nlhr->pData;
- if (!*dataPos)
- return;
- *dataPos += nlhr->dataLength;
- }
- if (data) {
- memcpy(*dataPos, data, sizeof(char)*len); *dataPos += len;
- nlhr->dataLength += (int)len; // not necessary
- }
-}
-
-void CSend::HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr)
-{
- mir_free(nlhr->headers[0].szValue), nlhr->headers[0].szValue = nullptr;
- mir_free(nlhr->headers), nlhr->headers = nullptr;
- mir_free(nlhr->pData), nlhr->pData = nullptr;
-}
-
-int CSend::HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum)
+int CSend::HTTPFormCreate(MHttpRequest* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum)
{
char boundary[16];
- memcpy(boundary, "--M461C/", 8);
+ strcpy(boundary, "--M461C/");
{
union
{
@@ -467,57 +441,40 @@ int CSend::HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char*
}
nlhr->requestType = requestType;
nlhr->flags = NLHRF_HTTP11;
- if (!strncmp(url, "https://", 8)) nlhr->flags |= NLHRF_SSL;
- nlhr->szUrl = (char*)url;
- nlhr->headersCount = 3;
+ if (!strncmp(url, "https://", 8))
+ nlhr->flags |= NLHRF_SSL;
+ nlhr->m_szUrl = url;
+ nlhr->AddHeader("Content-Type", CMStringA("multipart/form-data; boundary=") + boundary);
+ nlhr->AddHeader("User-Agent", __USER_AGENT_STRING);
+ nlhr->AddHeader("Accept-Language", "en-us,en;q=0.8");
for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (!(iter->flags&HTTPFF_HEADER)) break;
- ++nlhr->headersCount;
- }
- nlhr->headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr->headersCount);
- {
- char* contenttype = (char*)mir_alloc(sizeof(char)*(30 + 1 + sizeof(boundary)));
- memcpy(contenttype, "multipart/form-data; boundary=", 30);
- memcpy(contenttype + 30, boundary, sizeof(boundary));
- contenttype[30 + sizeof(boundary)] = '\0';
- nlhr->headers[0].szName = "Content-Type";
- nlhr->headers[0].szValue = contenttype;
- nlhr->headers[1].szName = "User-Agent";
- nlhr->headers[1].szValue = __USER_AGENT_STRING;
- nlhr->headers[2].szName = "Accept-Language";
- nlhr->headers[2].szValue = "en-us,en;q=0.8";
- int i = 3;
- for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (!(iter->flags&HTTPFF_HEADER)) break;
- nlhr->headers[i].szName = (char*)iter->name;
- nlhr->headers[i++].szValue = (char*)iter->value_str;
- }
+ if (!(iter->flags & HTTPFF_HEADER))
+ break;
+ nlhr->AddHeader(iter->name, iter->value_str);
}
- char* dataPos = nlhr->pData;
- size_t dataMax = 0;
- for (HTTPFormData* iter = frm, *end = frm + frmNum; iter != end; ++iter) {
- if (iter->flags&HTTPFF_HEADER) continue;
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 40);
- memset(dataPos, '-', 2); dataPos += 2;
- memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
- memcpy(dataPos, "\r\nContent-Disposition: form-data; name=\"", 40); dataPos += 40;
- size_t namelen = mir_strlen(iter->name), valuelen = 0;
- if (!(iter->flags&HTTPFF_INT))
- valuelen = mir_strlen(iter->value_str);
- if (iter->flags&HTTPFF_FILE) {
- const char* filename = strrchr(iter->value_str, '\\');
+
+ auto &str = nlhr->m_szParam;
+ for (HTTPFormData *iter = frm, *end = frm + frmNum; iter != end; ++iter) {
+ if (iter->flags & HTTPFF_HEADER)
+ continue;
+
+ str.AppendFormat("--%s", boundary);
+ str.Append("\r\nContent-Disposition: form-data; name=\"");
+
+ if (iter->flags & HTTPFF_FILE) {
+ const char *filename = strrchr(iter->value_str, '\\');
if (!filename) filename = strrchr(iter->value_str, '/');
if (!filename) filename = iter->value_str;
else ++filename;
- valuelen = mir_strlen(filename);
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 13 + valuelen + 17);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"; filename=\"", 13); dataPos += 13;
- memcpy(dataPos, filename, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\"\r\nContent-Type: ", 17); dataPos += 17;
+
+ str.Append(iter->name);
+ str.Append("\"; filename=\"");
+ str.Append(filename);
+ str.Append("\"\r\nContent-Type: ");
+
/// add mime type
- const char* mime = "application/octet-stream";
- const char* fileext = strrchr(filename, '.');
+ const char *mime = "application/octet-stream";
+ const char *fileext = strrchr(filename, '.');
if (fileext) {
if (!mir_strcmp(fileext, ".jpg") || !mir_strcmp(fileext, ".jpeg") || !mir_strcmp(fileext, ".jpe"))
mime = "image/jpeg";
@@ -530,71 +487,49 @@ int CSend::HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char*
else if (!mir_strcmp(fileext, ".tif") || !mir_strcmp(fileext, ".tiff"))
mime = "image/tiff";
}
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, mime, mir_strlen(mime));
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, "\r\n\r\n", 4);
+ str.Append(mime);
+ str.Append("\r\n\r\n");
+
/// add file content
size_t filesize = 0;
- FILE* fp = fopen(iter->value_str, "rb");
+ FILE *fp = fopen(iter->value_str, "rb");
if (fp) {
fseek(fp, 0, SEEK_END);
filesize = ftell(fp); fseek(fp, 0, SEEK_SET);
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, filesize + 2);
- if (fread(dataPos, 1, filesize, fp) != filesize) {
+ ptrA buf((char *)mir_alloc(filesize));
+ if (fread(buf, 1, filesize, fp) != filesize) {
+ str.Append(buf, filesize);
fclose(fp), fp = nullptr;
}
}
if (!fp) {
- HTTPFormDestroy(nlhr);
Error(L"Error occurred when opening local file.\nAborting file upload...");
Exit(ACKRESULT_FAILED);
return 1;
}
- else
- fclose(fp);
- dataPos += filesize;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ fclose(fp);
+ str.Append("\r\n");
}
- else if (iter->flags&HTTPFF_8BIT) {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 38 + valuelen + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n", 38); dataPos += 38;
- memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ else if (iter->flags & HTTPFF_8BIT) {
+ str.Append(iter->name);
+ str.Append("\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n");
+ str.Append(iter->value_str);
+ str.Append("\r\n");
}
- else if (iter->flags&HTTPFF_INT) {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + 17/*max numbers*/ + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
- int ret = snprintf(dataPos, 17, "%Id", iter->value_int);
- if (ret < 17 && ret>0) dataPos += ret;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ else if (iter->flags & HTTPFF_INT) {
+ str.Append(iter->name);
+ str.Append("\"\r\n\r\n");
+ str.AppendFormat("%Id", iter->value_int);
+ str.Append("\r\n");
}
else {
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, namelen + 5 + valuelen + 2);
- memcpy(dataPos, iter->name, namelen); dataPos += namelen;
- memcpy(dataPos, "\"\r\n\r\n", 5); dataPos += 5;
- memcpy(dataPos, iter->value_str, valuelen); dataPos += valuelen;
- memcpy(dataPos, "\r\n", 2); dataPos += 2;
+ str.Append(iter->name);
+ str.Append("\"\r\n\r\n");
+ str.Append(iter->value_str);
+ str.Append("\r\n");
}
}
- HTTPFormAppendData(nlhr, &dataMax, &dataPos, nullptr, 2 + sizeof(boundary) + 4);
- memset(dataPos, '-', 2); dataPos += 2;
- memcpy(dataPos, boundary, sizeof(boundary)); dataPos += sizeof(boundary);
- memcpy(dataPos, "--\r\n", 4); dataPos += 4;
- nlhr->dataLength = dataPos - nlhr->pData;
-#ifdef _DEBUG /// print request content to "_sendss_tmp" file for debugging
- {
- FILE* fp = fopen("_sendss_tmp", "wb");
- if (fp) {
- fprintf(fp, "--Target-- %s\n", nlhr->szUrl);
- for (int i = 0; i < nlhr->headersCount; ++i) {
- fprintf(fp, "%s: %s\n", nlhr->headers[i].szName, nlhr->headers[i].szValue);
- }
- fprintf(fp, "\n\n");
- fwrite(nlhr->pData, 1, nlhr->dataLength, fp);
- fclose(fp);
- }
- }
-#endif // _DEBUG
+
+ str.AppendFormat("--%s--\r\n", boundary);
return 0;
}
diff --git a/plugins/SendScreenshotPlus/src/CSend.h b/plugins/SendScreenshotPlus/src/CSend.h
index 9301811f17..c694167eae 100644
--- a/plugins/SendScreenshotPlus/src/CSend.h
+++ b/plugins/SendScreenshotPlus/src/CSend.h
@@ -130,8 +130,7 @@ protected:
};
static const char* GetHTMLContent(char* str, const char* startTag, const char* endTag); // changes "str", can be successfully used only once
- void HTTPFormDestroy(NETLIBHTTPREQUEST* nlhr); // use to free data inside "nlhr" created by HTTPFormCreate
- int HTTPFormCreate(NETLIBHTTPREQUEST* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum); // returns "0" on success, Exit() will be called on failure (stop processing)
+ int HTTPFormCreate(MHttpRequest* nlhr, int requestType, const char* url, HTTPFormData* frm, size_t frmNum); // returns "0" on success, Exit() will be called on failure (stop processing)
};
#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
index 5a2a4d8a34..6b604c33ba 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.cpp
@@ -76,12 +76,10 @@ void CSendHost_ImageShack::SendThread()
{
// send DATA and wait for m_nlreply
NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &m_nlhr));
- HTTPFormDestroy(&m_nlhr);
if (reply) {
- if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
- reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
+ if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->body.GetLength()) {
const char* url = nullptr;
- url = GetHTMLContent(reply->pData, "<image_link>", "</image_link>");
+ url = GetHTMLContent(reply->body.GetBuffer(), "<image_link>", "</image_link>");
if (url && *url) {
m_URLthumb = m_URL = url;
@@ -95,19 +93,19 @@ void CSendHost_ImageShack::SendThread()
return;
}
- url = GetHTMLContent(reply->pData, "<error ", "</error>");
+ url = GetHTMLContent(reply->body.GetBuffer(), "<error ", "</error>");
wchar_t* err = nullptr;
if (url) err = mir_a2u(url);
if (!err || !*err) { // fallback to server response mess
mir_free(err);
- err = mir_a2u(reply->pData);
+ err = mir_a2u(reply->body);
}
Error(L"%s", err);
mir_free(err);
}
else Error(SS_ERR_RESPONSE, m_pszSendTyp, reply->resultCode);
}
- else Error(SS_ERR_NORESPONSE, m_pszSendTyp, m_nlhr.resultCode);
+ else Error(SS_ERR_NORESPONSE, m_pszSendTyp, 500);
Exit(ACKRESULT_FAILED);
}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
index 7c58094aac..5197e8718a 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_ImageShack.h
@@ -40,7 +40,7 @@ public:
int Send() override;
protected:
- NETLIBHTTPREQUEST m_nlhr;
+ MHttpRequest m_nlhr;
void SendThread();
static void SendThreadWrapper(void * Obj);
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp b/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
index bde9f158bb..c4bb3897f7 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_imgur.cpp
@@ -15,8 +15,8 @@
*/
#include "stdafx.h"
-CSendHost_Imgur::CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync)
- : CSend(Owner, hContact, bAsync)
+CSendHost_Imgur::CSendHost_Imgur(HWND Owner, MCONTACT hContact, bool bAsync) :
+ CSend(Owner, hContact, bAsync)
{
m_EnableItem = SS_DLG_DESCRIPTION | SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND;
m_pszSendTyp = LPGENW("Image upload");
@@ -60,10 +60,9 @@ void CSendHost_Imgur::SendThread(void* obj)
CSendHost_Imgur *self = (CSendHost_Imgur*)obj;
// send DATA and wait for m_nlreply
NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
- self->HTTPFormDestroy(&self->m_nlhr);
if (reply) {
- if (reply->dataLength) {
- JSONROOT root(reply->pData);
+ if (reply->body.GetLength()) {
+ JSONROOT root(reply->body);
if (root) {
if ((*root)["success"].as_bool()) {
self->m_URL = (*root)["data"]["link"].as_mstring();
@@ -80,7 +79,7 @@ void CSendHost_Imgur::SendThread(void* obj)
}
else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
}
- else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
+ else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, 500);
self->Exit(ACKRESULT_FAILED);
}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_imgur.h b/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
index 544afecd53..fee457d00a 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_imgur.h
@@ -24,7 +24,7 @@ class CSendHost_Imgur : public CSend {
int Send() override;
protected:
- NETLIBHTTPREQUEST m_nlhr;
+ MHttpRequest m_nlhr;
static void SendThread(void* obj);
};
#endif
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
index 58651ae85d..4fcf8f7d8b 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
+++ b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.cpp
@@ -65,11 +65,9 @@ void CSendHost_UploadPie::SendThread(void* obj)
CSendHost_UploadPie* self = (CSendHost_UploadPie*)obj;
// send DATA and wait for m_nlreply
NLHR_PTR reply(Netlib_HttpTransaction(g_hNetlibUser, &self->m_nlhr));
- self->HTTPFormDestroy(&self->m_nlhr);
if (reply) {
- if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->dataLength) {
- reply->pData[reply->dataLength - 1] = '\0'; // make sure its null terminated
- char* url = reply->pData;
+ if (reply->resultCode >= 200 && reply->resultCode < 300 && reply->body.GetLength()) {
+ char* url = reply->body.GetBuffer();
do {
char* pos;
if ((url = strstr(url, kHostURL))) {
@@ -89,17 +87,17 @@ void CSendHost_UploadPie::SendThread(void* obj)
self->svcSendMsgExit(url); return;
}
else { // check error mess from server
- const char* err = GetHTMLContent(reply->pData, "<p id=\"error\"", "</p>");
+ const char* err = GetHTMLContent(reply->body.GetBuffer(), "<p id=\"error\"", "</p>");
wchar_t* werr;
if (err) werr = mir_a2u(err);
- else werr = mir_a2u(reply->pData);
+ else werr = mir_a2u(reply->body);
self->Error(L"%s", werr);
mir_free(werr);
}
}
else self->Error(SS_ERR_RESPONSE, self->m_pszSendTyp, reply->resultCode);
}
- else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, self->m_nlhr.resultCode);
+ else self->Error(SS_ERR_NORESPONSE, self->m_pszSendTyp, 500);
self->Exit(ACKRESULT_FAILED);
}
diff --git a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
index 94cfdf1fbc..8a4abd350f 100644
--- a/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
+++ b/plugins/SendScreenshotPlus/src/CSendHost_uploadpie.h
@@ -24,7 +24,7 @@ class CSendHost_UploadPie : public CSend {
protected:
int m_expire;
- NETLIBHTTPREQUEST m_nlhr;
+ MHttpRequest m_nlhr;
static void SendThread(void* obj);
};
#endif
diff --git a/plugins/SmileyAdd/src/download.cpp b/plugins/SmileyAdd/src/download.cpp
index ef0e4a0682..1aa2ac1fd4 100644
--- a/plugins/SmileyAdd/src/download.cpp
+++ b/plugins/SmileyAdd/src/download.cpp
@@ -42,22 +42,17 @@ static bool threadRunning;
bool InternetDownloadFile(const char *szUrl, char *szDest, HNETLIBCONN &hHttpDwnl)
{
int result = 0xBADBAD;
- char *szRedirUrl = nullptr;
- NETLIBHTTPREQUEST nlhr = {};
// initialize the netlib request
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT | NLHRF_REDIRECT;
- nlhr.szUrl = (char*)szUrl;
+ nlhr.m_szUrl = szUrl;
nlhr.nlc = hHttpDwnl;
// change the header so the plugin is pretended to be IE 6 + WinXP
- nlhr.headersCount = 2;
- nlhr.headers = (NETLIBHTTPHEADER*)alloca(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount);
- nlhr.headers[0].szName = "User-Agent";
- nlhr.headers[0].szValue = NETLIB_USER_AGENT;
- nlhr.headers[1].szName = "Connection";
- nlhr.headers[1].szValue = "close";
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Connection", "close");
while (result == 0xBADBAD) {
// download the page
@@ -73,7 +68,7 @@ bool InternetDownloadFile(const char *szUrl, char *szDest, HNETLIBCONN &hHttpDwn
int res = -1;
int fh = _open(szDest, _O_BINARY | _O_WRONLY | _O_CREAT, _S_IREAD | _S_IWRITE);
if (fh != -1) {
- res = _write(fh, nlhrReply->pData, nlhrReply->dataLength);
+ res = _write(fh, nlhrReply->body, nlhrReply->body.GetLength());
_close(fh);
}
if (res < 0)
@@ -81,28 +76,6 @@ bool InternetDownloadFile(const char *szUrl, char *szDest, HNETLIBCONN &hHttpDwn
else
result = 0;
}
- // if the recieved code is 302 Moved, Found, etc
- // workaround for url forwarding
- else if (nlhrReply->resultCode == 302 || nlhrReply->resultCode == 301 || nlhrReply->resultCode == 307) { // page moved
- // get the url for the new location and save it to szInfo
- // look for the reply header "Location"
- if (auto *pszUrl = Netlib_GetHeader(nlhrReply, "Location")) {
- size_t rlen = 0;
- if (pszUrl[0] == '/') {
- const char *szPref = strstr(szUrl, "://");
- szPref = szPref ? szPref + 3 : szUrl;
- const char *szPath = strchr(szPref, '/');
- rlen = szPath != nullptr ? szPath - szUrl : mir_strlen(szUrl);
- }
-
- szRedirUrl = (char *)mir_realloc(szRedirUrl, rlen + mir_strlen(pszUrl) * 3 + 1);
-
- strncpy(szRedirUrl, szUrl, rlen);
- mir_strcpy(szRedirUrl + rlen, pszUrl);
-
- nlhr.szUrl = szRedirUrl;
- }
- }
else result = 1;
}
else {
@@ -111,8 +84,6 @@ bool InternetDownloadFile(const char *szUrl, char *szDest, HNETLIBCONN &hHttpDwn
}
}
- mir_free(szRedirUrl);
-
return result == 0;
}
diff --git a/protocols/CloudFile/src/Services/dropbox_service.cpp b/protocols/CloudFile/src/Services/dropbox_service.cpp
index 805a7f2800..92b00fc493 100644
--- a/protocols/CloudFile/src/Services/dropbox_service.cpp
+++ b/protocols/CloudFile/src/Services/dropbox_service.cpp
@@ -85,7 +85,7 @@ void CDropboxService::RequestAccessTokenThread(void *param)
return;
}
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.empty()) {
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), HttpStatusToError(response->resultCode));
ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR);
@@ -206,7 +206,7 @@ auto CDropboxService::CreateSharedLink(const std::string &path)
if (!response || response->resultCode != HTTP_CODE_CONFLICT)
HttpResponseToError(response);
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.isnull())
throw Exception(HttpStatusToError());
diff --git a/protocols/CloudFile/src/Services/google_service.cpp b/protocols/CloudFile/src/Services/google_service.cpp
index 58b32eaa7f..fea2c3b2b4 100644
--- a/protocols/CloudFile/src/Services/google_service.cpp
+++ b/protocols/CloudFile/src/Services/google_service.cpp
@@ -100,8 +100,8 @@ void CGDriveService::RequestAccessTokenThread(void *param)
NLHR_PTR response(request.Send(m_hConnection));
if (response == nullptr || response->resultCode != HTTP_CODE_OK) {
- const char *error = response && response->dataLength
- ? response->pData
+ const char *error = response && response->body.GetLength()
+ ? response->body
: HttpStatusToError(response ? response->resultCode : 0);
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), error);
@@ -110,7 +110,7 @@ void CGDriveService::RequestAccessTokenThread(void *param)
return;
}
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.empty()) {
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), HttpStatusToError(response->resultCode));
ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR);
@@ -180,7 +180,7 @@ auto CGDriveService::CreateUploadSession(const std::string &parentId, const std:
HandleHttpError(response);
if (HTTP_CODE_SUCCESS(response->resultCode))
- if (auto *pszHdr = Netlib_GetHeader(response, "Location"))
+ if (auto *pszHdr = response->FindHeader("Location"))
return std::string(pszHdr);
HttpResponseToError(response);
diff --git a/protocols/CloudFile/src/Services/microsoft_service.cpp b/protocols/CloudFile/src/Services/microsoft_service.cpp
index 8d63f4a23f..17115235cd 100644
--- a/protocols/CloudFile/src/Services/microsoft_service.cpp
+++ b/protocols/CloudFile/src/Services/microsoft_service.cpp
@@ -100,8 +100,8 @@ void COneDriveService::RequestAccessTokenThread(void *param)
NLHR_PTR response(request.Send(m_hConnection));
if (response == nullptr || response->resultCode != HTTP_CODE_OK) {
- const char *error = response->dataLength
- ? response->pData
+ const char *error = response->body.GetLength()
+ ? response->body
: HttpStatusToError(response->resultCode);
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), error);
@@ -110,7 +110,7 @@ void COneDriveService::RequestAccessTokenThread(void *param)
return;
}
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.empty()) {
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), HttpStatusToError(response->resultCode));
ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR);
diff --git a/protocols/CloudFile/src/Services/yandex_service.cpp b/protocols/CloudFile/src/Services/yandex_service.cpp
index f21e9ef2e0..892821e0c4 100644
--- a/protocols/CloudFile/src/Services/yandex_service.cpp
+++ b/protocols/CloudFile/src/Services/yandex_service.cpp
@@ -102,8 +102,8 @@ void CYandexService::RequestAccessTokenThread(void *param)
NLHR_PTR response(request.Send(m_hConnection));
if (response == nullptr || response->resultCode != HTTP_CODE_OK) {
- const char *error = response->dataLength
- ? response->pData
+ const char *error = response->body.GetLength()
+ ? response->body
: HttpStatusToError(response->resultCode);
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), error);
@@ -112,7 +112,7 @@ void CYandexService::RequestAccessTokenThread(void *param)
return;
}
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.empty()) {
Netlib_Logf(m_hConnection, "%s: %s", GetAccountName(), HttpStatusToError(response->resultCode));
ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR);
diff --git a/protocols/CloudFile/src/cloud_file.cpp b/protocols/CloudFile/src/cloud_file.cpp
index 9f66caaf82..772b42ae36 100644
--- a/protocols/CloudFile/src/cloud_file.cpp
+++ b/protocols/CloudFile/src/cloud_file.cpp
@@ -129,16 +129,16 @@ char* CCloudService::HttpStatusToError(int status)
return "Unknown error";
}
-void CCloudService::HttpResponseToError(NETLIBHTTPREQUEST *response)
+void CCloudService::HttpResponseToError(MHttpResponse *response)
{
if (response == nullptr)
throw Exception(HttpStatusToError());
- if (response->dataLength)
- throw Exception(response->pData);
+ if (response->body.GetLength())
+ throw Exception(response->body.c_str());
throw Exception(HttpStatusToError(response->resultCode));
}
-void CCloudService::HandleHttpError(NETLIBHTTPREQUEST *response)
+void CCloudService::HandleHttpError(MHttpResponse *response)
{
if (response == nullptr)
throw Exception(HttpStatusToError());
@@ -152,11 +152,11 @@ void CCloudService::HandleHttpError(NETLIBHTTPREQUEST *response)
HttpResponseToError(response);
}
-JSONNode CCloudService::GetJsonResponse(NETLIBHTTPREQUEST *response)
+JSONNode CCloudService::GetJsonResponse(MHttpResponse *response)
{
HandleHttpError(response);
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.isnull())
throw Exception(HttpStatusToError());
diff --git a/protocols/CloudFile/src/cloud_file.h b/protocols/CloudFile/src/cloud_file.h
index de053af431..4a5b91da72 100644
--- a/protocols/CloudFile/src/cloud_file.h
+++ b/protocols/CloudFile/src/cloud_file.h
@@ -18,15 +18,15 @@ protected:
std::string PreparePath(const std::string &path) const;
virtual char* HttpStatusToError(int status = 0);
- virtual void HttpResponseToError(NETLIBHTTPREQUEST *response);
- virtual void HandleHttpError(NETLIBHTTPREQUEST *response);
+ virtual void HttpResponseToError(MHttpResponse *response);
+ virtual void HandleHttpError(MHttpResponse *response);
virtual void HandleJsonError(JSONNode &node) = 0;
// events
void OnModulesLoaded() override;
MWindow OnCreateAccMgrUI(MWindow) override;
- JSONNode GetJsonResponse(NETLIBHTTPREQUEST *response);
+ JSONNode GetJsonResponse(MHttpResponse *response);
virtual void Upload(FileTransferParam *ftp) = 0;
diff --git a/protocols/CloudFile/src/http_request.h b/protocols/CloudFile/src/http_request.h
index 68be404921..214ecea761 100644
--- a/protocols/CloudFile/src/http_request.h
+++ b/protocols/CloudFile/src/http_request.h
@@ -17,7 +17,7 @@ public:
}
};
-class HttpRequest : protected NETLIBHTTPREQUEST
+class HttpRequest : public MHttpRequest
{
private:
CMStringA m_szUrl;
@@ -26,28 +26,11 @@ private:
{
requestType = type;
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP;
- szUrl = NULL;
- headers = NULL;
- headersCount = 0;
- pData = NULL;
- dataLength = 0;
- resultCode = 0;
- szResultDescr = NULL;
nlc = NULL;
timeout = 0;
}
protected:
- enum HttpRequestUrlFormat { FORMAT };
-
- void 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 AddBasicAuthHeader(LPCSTR szLogin, LPCSTR szPassword)
{
size_t length = mir_strlen(szLogin) + mir_strlen(szPassword) + 1;
@@ -60,47 +43,17 @@ protected:
szPassword);
ptrA ePair(mir_base64_encode(cPair, length));
-
- length = mir_strlen(ePair) + 7;
- char *value = (char*)mir_calloc(length + 1);
- mir_snprintf(value, length, "Basic %s", ePair.get());
-
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup("Authorization");
- headers[headersCount].szValue = value;
- headersCount++;
+ AddHeader("Authorization", CMStringA(FORMAT, "Basic %s", ePair.get()));
}
void AddBearerAuthHeader(LPCSTR szValue)
{
- size_t length = mir_strlen(szValue) + 8;
- char *value = (char*)mir_calloc(length + 1);
- mir_snprintf(
- value,
- length,
- "Bearer %s",
- szValue);
-
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup("Authorization");
- headers[headersCount].szValue = value;
- headersCount++;
+ AddHeader("Authorization", CMStringA(FORMAT, "Bearer %s", szValue));
}
void AddOAuthHeader(LPCSTR szValue)
{
- size_t length = mir_strlen(szValue) + 7;
- char *value = (char*)mir_calloc(length + 1);
- mir_snprintf(
- value,
- length,
- "OAuth %s",
- szValue);
-
- headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
- headers[headersCount].szName = mir_strdup("Authorization");
- headers[headersCount].szValue = value;
- headersCount++;
+ AddHeader("Authorization", CMStringA(FORMAT, "OAuth %s", szValue));
}
void AddUrlParameter(const char *urlFormat, ...)
@@ -124,16 +77,6 @@ protected:
va_end(valueArgs);
}
- void SetData(const char *data, size_t size)
- {
- if (pData != NULL)
- mir_free(pData);
-
- dataLength = (int)size;
- pData = (char*)mir_alloc(size);
- memcpy(pData, data, size);
- }
-
public:
HttpRequest(int type, LPCSTR url)
{
@@ -142,7 +85,7 @@ public:
m_szUrl = url;
}
- HttpRequest(int type, HttpRequestUrlFormat, LPCSTR urlFormat, ...)
+ HttpRequest(int type, CMStringDataFormat, LPCSTR urlFormat, ...)
{
Init(type);
@@ -152,22 +95,9 @@ public:
va_end(formatArgs);
}
- ~HttpRequest()
- {
- for (int i = 0; i < headersCount; i++)
- {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(headers);
- if (pData)
- mir_free(pData);
- }
-
- NETLIBHTTPREQUEST* Send(HNETLIBUSER hConnection)
+ MHttpResponse* Send(HNETLIBUSER hConnection)
{
m_szUrl.Replace('\\', '/');
- szUrl = m_szUrl.GetBuffer();
return Netlib_HttpTransaction(hConnection, this);
}
};
diff --git a/protocols/CurrencyRates/src/HTTPSession.cpp b/protocols/CurrencyRates/src/HTTPSession.cpp
index beee03b47c..a00a71d635 100644
--- a/protocols/CurrencyRates/src/HTTPSession.cpp
+++ b/protocols/CurrencyRates/src/HTTPSession.cpp
@@ -9,15 +9,6 @@ void CALLBACK waitStub()
show_popup(g_pCurrentProvider, 0, -1, TranslateW(ERROR_MSG));
}
-static int find_header(const NETLIBHTTPREQUEST* pRequest, const char* hdr)
-{
- for (int i = 0; i < pRequest->headersCount; ++i)
- if (0 == _stricmp(pRequest->headers[i].szName, hdr))
- return i;
-
- return -1;
-}
-
bool CHTTPSession::OpenURL(const CMStringW &rsURL)
{
m_szUrl = rsURL;
@@ -29,20 +20,14 @@ bool CHTTPSession::ReadResponce(CMStringW &rsResponce)
if (m_szUrl.IsEmpty())
return false;
- NETLIBHTTPHEADER headers[] =
- {
- { "User-Agent", NETLIB_USER_AGENT },
- { "Connection", "close" },
- { "Cache-Control", "no-cache" },
- { "Pragma", "no-cache" }
- };
-
- NETLIBHTTPREQUEST nlhr = {};
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
- nlhr.szUrl = m_szUrl.GetBuffer();
- nlhr.headersCount = _countof(headers);
- nlhr.headers = headers;
+ nlhr.m_szUrl = m_szUrl;
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Connection", "close");
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
bool bResult = false;
NLHR_PTR pReply(0);
@@ -52,13 +37,12 @@ bool CHTTPSession::ReadResponce(CMStringW &rsResponce)
}
if (pReply) {
- if ((200 == pReply->resultCode) && (pReply->dataLength > 0)) {
- CMStringA buf(pReply->pData, pReply->dataLength);
- int nIndex = find_header(pReply, "Content-Type");
- if ((-1 != nIndex) && (nullptr != strstr(_strlwr(pReply->headers[nIndex].szValue), "utf-8")))
- rsResponce = ptrW(mir_utf8decodeW(buf));
+ if ((200 == pReply->resultCode) && !pReply->body.IsEmpty()) {
+ auto *pEncoding = pReply->FindHeader("Content-Type");
+ if (pEncoding && strstr(pEncoding, "utf-8"))
+ rsResponce = ptrW(mir_utf8decodeW(pReply->body));
else
- rsResponce = _A2T(buf);
+ rsResponce = _A2T(pReply->body);
bResult = true;
}
diff --git a/protocols/Discord/src/avatars.cpp b/protocols/Discord/src/avatars.cpp
index a131b23856..fd2d57181c 100644
--- a/protocols/Discord/src/avatars.cpp
+++ b/protocols/Discord/src/avatars.cpp
@@ -52,7 +52,7 @@ INT_PTR CDiscordProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
/////////////////////////////////////////////////////////////////////////////////////////
-void CDiscordProto::OnReceiveAvatar(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CDiscordProto::OnReceiveAvatar(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
PROTO_AVATAR_INFORMATION ai = { 0 };
ai.format = PA_FORMAT_UNKNOWN;
@@ -64,7 +64,7 @@ LBL_Error:
return;
}
- if (auto *pszHdr = Netlib_GetHeader(reply, "Content-Type"))
+ if (auto *pszHdr = reply->FindHeader("Content-Type"))
ai.format = ProtoGetAvatarFormatByMimeType(pszHdr);
if (ai.format == PA_FORMAT_UNKNOWN) {
@@ -81,7 +81,7 @@ LBL_Error:
goto LBL_Error;
}
- fwrite(reply->pData, 1, reply->dataLength, out);
+ fwrite(reply->body, 1, reply->body.GetLength(), out);
fclose(out);
if (ai.hContact)
diff --git a/protocols/Discord/src/connection.cpp b/protocols/Discord/src/connection.cpp
index d98d6e4ec8..00c9214b2c 100644
--- a/protocols/Discord/src/connection.cpp
+++ b/protocols/Discord/src/connection.cpp
@@ -21,15 +21,10 @@ 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.c_str(), pReq->m_szParam.c_str());
- pReq->szUrl = str.GetBuffer();
- }
- else {
- pReq->pData = mir_strdup(pReq->m_szParam);
- pReq->dataLength = pReq->m_szParam.GetLength();
+ pReq->m_szUrl = str.GetBuffer();
}
}
@@ -40,7 +35,7 @@ void CDiscordProto::ExecuteRequest(AsyncHttpRequest *pReq)
}
bool bRetryable = pReq->nlc != nullptr;
- debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->szUrl);
+ debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->m_szUrl.c_str());
LBL_Retry:
NLHR_PTR reply(Netlib_HttpTransaction(m_hNetlibUser, pReq));
diff --git a/protocols/Discord/src/gateway.cpp b/protocols/Discord/src/gateway.cpp
index e76de2848a..759afed573 100644
--- a/protocols/Discord/src/gateway.cpp
+++ b/protocols/Discord/src/gateway.cpp
@@ -43,19 +43,15 @@ void CDiscordProto::GatewayThread(void*)
bool CDiscordProto::GatewayThreadWorker()
{
- NETLIBHTTPHEADER hdrs[] =
- {
- { "Origin", "https://discord.com" },
- { 0, 0 },
- { 0, 0 },
- };
-
+ bool bHasCookie = false;
+ MHttpHeaders hdrs;
+ hdrs.AddHeader("Origin", "https://discord.com");
if (!m_szWSCookie.IsEmpty()) {
- hdrs[1].szName = "Cookie";
- hdrs[1].szValue = m_szWSCookie.GetBuffer();
+ bHasCookie = true;
+ hdrs.AddHeader("Cookie", m_szWSCookie);
}
- NLHR_PTR pReply(WebSocket_Connect(m_hGatewayNetlibUser, m_szGateway + "/?encoding=json&v=8", hdrs));
+ NLHR_PTR pReply(WebSocket_Connect(m_hGatewayNetlibUser, m_szGateway + "/?encoding=json&v=8", &hdrs));
if (pReply == nullptr) {
debugLogA("Gateway connection failed, exiting");
return false;
@@ -66,7 +62,7 @@ bool CDiscordProto::GatewayThreadWorker()
if (pReply->resultCode != 101) {
// if there's no cookie & Miranda is bounced with error 404, simply apply the cookie and try again
if (pReply->resultCode == 404) {
- if (hdrs[1].szName == nullptr)
+ if (!bHasCookie)
return true;
m_szWSCookie.Empty(); // don't use the same cookie twice
diff --git a/protocols/Discord/src/http.cpp b/protocols/Discord/src/http.cpp
index f65451f9ce..82e8d495d0 100644
--- a/protocols/Discord/src/http.cpp
+++ b/protocols/Discord/src/http.cpp
@@ -59,8 +59,7 @@ AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR
if (pRoot != nullptr) {
ptrW text(json_write(pRoot));
- pData = mir_utf8encodeW(text);
- dataLength = (int)mir_strlen(pData);
+ m_szParam = ptrA(mir_utf8encodeW(text));
AddHeader("Content-Type", "application/json");
}
@@ -71,7 +70,7 @@ AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR
m_iReqNum = ::InterlockedIncrement(&g_reqNum);
}
-JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
+JsonReply::JsonReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -80,7 +79,7 @@ JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
m_errorCode = pReply->resultCode;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr)
m_errorCode = 500;
}
diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp
index 1e76ead10d..210d649d00 100644
--- a/protocols/Discord/src/proto.cpp
+++ b/protocols/Discord/src/proto.cpp
@@ -329,7 +329,7 @@ HANDLE CDiscordProto::SearchAdvanced(HWND hwndDlg)
/////////////////////////////////////////////////////////////////////////////////////////
// Basic search - by SnowFlake
-void CDiscordProto::OnReceiveUserinfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveUserinfo(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (!root) {
@@ -459,7 +459,7 @@ MCONTACT CDiscordProto::AddToListByEvent(int flags, int, MEVENT hDbEvent)
////////////////////////////////////////////////////////////////////////////////////////
// SendMsg
-void CDiscordProto::OnSendMsg(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CDiscordProto::OnSendMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
JsonReply root(pReply);
if (!root) {
@@ -574,7 +574,7 @@ int CDiscordProto::UserIsTyping(MCONTACT hContact, int type)
/////////////////////////////////////////////////////////////////////////////////////////
-void CDiscordProto::OnReceiveMarkRead(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CDiscordProto::OnReceiveMarkRead(MHttpResponse *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
if (root)
@@ -712,10 +712,10 @@ void CDiscordProto::SendFileThread(void *param)
szBoundary.Insert(0, "\r\n");
szBoundary.Append("--\r\n");
- pReq->dataLength = int(szBody.GetLength() + szBoundary.GetLength() + cbBytes);
- pReq->pData = (char*)mir_alloc(pReq->dataLength+1);
- memcpy(pReq->pData, szBody.c_str(), szBody.GetLength());
- size_t cbRead = fread(pReq->pData + szBody.GetLength(), 1, cbBytes, in);
+ pReq->m_szParam.Truncate(int(szBody.GetLength() + szBoundary.GetLength() + cbBytes));
+
+ memcpy(pReq->m_szParam.GetBuffer(), szBody.c_str(), szBody.GetLength());
+ size_t cbRead = fread(pReq->m_szParam.GetBuffer() + szBody.GetLength(), 1, cbBytes, in);
fclose(in);
if (cbBytes != cbRead) {
debugLogA("cannot read file %S: %d bytes read instead of %d", p->wszFileName.c_str(), cbRead, cbBytes);
@@ -723,14 +723,14 @@ void CDiscordProto::SendFileThread(void *param)
goto LBL_Error;
}
- memcpy(pReq->pData + szBody.GetLength() + cbBytes, szBoundary, szBoundary.GetLength());
+ memcpy(pReq->m_szParam.GetBuffer() + szBody.GetLength() + cbBytes, szBoundary, szBoundary.GetLength());
pReq->pUserInfo = p;
Push(pReq);
ProtoBroadcastAck(p->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, param);
}
-void CDiscordProto::OnReceiveFile(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CDiscordProto::OnReceiveFile(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
SendFileThreadParam *p = (SendFileThreadParam*)pReq->pUserInfo;
if (pReply->resultCode != 200) {
diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h
index e34f6cbfa9..fdb5e6a33b 100644
--- a/protocols/Discord/src/proto.h
+++ b/protocols/Discord/src/proto.h
@@ -80,7 +80,7 @@ class JsonReply
int m_errorCode = 0;
public:
- JsonReply(NETLIBHTTPREQUEST *);
+ JsonReply(MHttpResponse *);
~JsonReply();
__forceinline int error() const { return m_errorCode; }
@@ -495,25 +495,25 @@ public:
void OnLoggedIn();
void OnLoggedOut();
- void OnReceiveCreateChannel(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveGateway(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveLogout(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveMarkRead(NETLIBHTTPREQUEST*, AsyncHttpRequest *);
- void OnReceiveMessageAck(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveToken(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveUserinfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveCreateChannel(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveFile(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveGateway(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveLogout(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveMarkRead(MHttpResponse*, AsyncHttpRequest *);
+ void OnReceiveMessageAck(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveToken(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveUserinfo(MHttpResponse*, AsyncHttpRequest*);
void RetrieveMyInfo();
- void OnReceiveMyInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveMyInfo(MHttpResponse*, AsyncHttpRequest*);
void RetrieveHistory(CDiscordUser *pUser, CDiscordHistoryOp iOp = MSG_NOFILTER, SnowFlake msgid = 0, int iLimit = 50);
- void OnReceiveHistory(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveHistory(MHttpResponse*, AsyncHttpRequest*);
bool RetrieveAvatar(MCONTACT hContact);
- void OnReceiveAvatar(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveAvatar(MHttpResponse*, AsyncHttpRequest*);
- void OnSendMsg(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnSendMsg(MHttpResponse*, AsyncHttpRequest*);
//////////////////////////////////////////////////////////////////////////////////////
// Misc
diff --git a/protocols/Discord/src/server.cpp b/protocols/Discord/src/server.cpp
index 1ef3517822..104d45435d 100644
--- a/protocols/Discord/src/server.cpp
+++ b/protocols/Discord/src/server.cpp
@@ -54,7 +54,7 @@ static int compareMsgHistory(const JSONNode *p1, const JSONNode *p2)
return wcscmp((*p1)["id"].as_mstring(), (*p2)["id"].as_mstring());
}
-void CDiscordProto::OnReceiveHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CDiscordProto::OnReceiveHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
CDiscordUser *pUser = (CDiscordUser*)pReq->pUserInfo;
@@ -147,7 +147,7 @@ void CDiscordProto::RetrieveMyInfo()
Push(new AsyncHttpRequest(this, REQUEST_GET, "/users/@me", &CDiscordProto::OnReceiveMyInfo));
}
-void CDiscordProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveMyInfo(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (!root) {
@@ -179,7 +179,7 @@ void CDiscordProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*
/////////////////////////////////////////////////////////////////////////////////////////
// finds a gateway address
-void CDiscordProto::OnReceiveGateway(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveGateway(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (!root) {
@@ -195,7 +195,7 @@ void CDiscordProto::OnReceiveGateway(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest
/////////////////////////////////////////////////////////////////////////////////////////
// logs a session out
-void CDiscordProto::OnReceiveLogout(NETLIBHTTPREQUEST *, AsyncHttpRequest *)
+void CDiscordProto::OnReceiveLogout(MHttpResponse *, AsyncHttpRequest *)
{
delSetting("AccessToken");
}
@@ -213,7 +213,7 @@ void CDiscordProto::SetServerStatus(int iStatus)
/////////////////////////////////////////////////////////////////////////////////////////
// channels
-void CDiscordProto::OnReceiveCreateChannel(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveCreateChannel(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (root)
@@ -222,7 +222,7 @@ void CDiscordProto::OnReceiveCreateChannel(NETLIBHTTPREQUEST *pReply, AsyncHttpR
/////////////////////////////////////////////////////////////////////////////////////////
-void CDiscordProto::OnReceiveMessageAck(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveMessageAck(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (!root)
@@ -243,10 +243,10 @@ void CDiscordProto::OnReceiveMessageAck(NETLIBHTTPREQUEST *pReply, AsyncHttpRequ
#define RECAPTCHA_API_KEY "6Lef5iQTAAAAAKeIvIY-DeexoO3gj7ryl9rLMEnn"
#define RECAPTCHA_SITE_URL "https://discord.com"
-void CDiscordProto::OnReceiveToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CDiscordProto::OnReceiveToken(MHttpResponse *pReply, AsyncHttpRequest*)
{
if (pReply->resultCode != 200) {
- JSONNode root = JSONNode::parse(pReply->pData);
+ JSONNode root = JSONNode::parse(pReply->body);
if (root) {
const JSONNode &captcha = root["captcha_key"].as_array();
if (captcha) {
diff --git a/protocols/Facebook/src/avatars.cpp b/protocols/Facebook/src/avatars.cpp
index 6759d20468..224bd707b0 100644
--- a/protocols/Facebook/src/avatars.cpp
+++ b/protocols/Facebook/src/avatars.cpp
@@ -33,7 +33,7 @@ void FacebookProto::GetAvatarFilename(MCONTACT hContact, wchar_t *pwszFileName)
void __cdecl FacebookProto::AvatarsUpdate(void *)
{
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.flags = NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
req.requestType = REQUEST_GET;
@@ -48,13 +48,11 @@ void __cdecl FacebookProto::AvatarsUpdate(void *)
continue;
delSetting(cc, "UpdateNeeded");
-
- CMStringA szUrl(FORMAT, "https://graph.facebook.com/%s/picture?%s", getMStringA(cc, DBKEY_ID).c_str(), szParams.c_str());
- req.szUrl = szUrl.GetBuffer();
+ req.m_szUrl.Format("https://graph.facebook.com/%s/picture?%s", getMStringA(cc, DBKEY_ID).c_str(), szParams.c_str());
NLHR_PTR pReply(Netlib_HttpTransaction(m_hNetlibUser, &req));
if (pReply == nullptr) {
- debugLogA("Failed to retrieve avatar from url: %s", szUrl.c_str());
+ debugLogA("Failed to retrieve avatar from url: %s", req.m_szUrl.c_str());
continue;
}
@@ -64,14 +62,14 @@ void __cdecl FacebookProto::AvatarsUpdate(void *)
GetAvatarFilename(cc, ai.filename);
bool bSuccess = false;
- if (pReply->resultCode == 200 && pReply->pData && pReply->dataLength) {
- if (auto *pszHdr = Netlib_GetHeader(pReply, "Content-Type"))
+ if (pReply->resultCode == 200 && !pReply->body.IsEmpty()) {
+ if (auto *pszHdr = pReply->FindHeader("Content-Type"))
ai.format = ProtoGetAvatarFormatByMimeType(pszHdr);
if (ai.format != PA_FORMAT_UNKNOWN) {
FILE *fout = _wfopen(ai.filename, L"wb");
if (fout) {
- fwrite(pReply->pData, 1, pReply->dataLength, fout);
+ fwrite(pReply->body, 1, pReply->body.GetLength(), fout);
fclose(fout);
bSuccess = true;
}
@@ -79,7 +77,7 @@ void __cdecl FacebookProto::AvatarsUpdate(void *)
}
else debugLogA("unknown avatar mime type");
}
- else debugLogA("Error %d reading avatar from url: %s", pReply->resultCode, szUrl.c_str());
+ else debugLogA("Error %d reading avatar from url: %s", pReply->resultCode, req.m_szUrl.c_str());
ProtoBroadcastAck(cc, ACKTYPE_AVATAR, bSuccess ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, &ai);
}
diff --git a/protocols/Facebook/src/http.cpp b/protocols/Facebook/src/http.cpp
index 55e8ce5a5c..caf8113ef7 100644
--- a/protocols/Facebook/src/http.cpp
+++ b/protocols/Facebook/src/http.cpp
@@ -69,7 +69,7 @@ AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const INT_PARAM &param)
/////////////////////////////////////////////////////////////////////////////////////////
-JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
+JsonReply::JsonReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -80,7 +80,7 @@ JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
if (m_errorCode != 200)
return;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr) {
m_errorCode = 500;
return;
@@ -96,10 +96,10 @@ JsonReply::~JsonReply()
/////////////////////////////////////////////////////////////////////////////////////////
-AsyncHttpRequest* FacebookProto::CreateRequest(const char *szUrl, const char *szName, const char *szMethod)
+AsyncHttpRequest* FacebookProto::CreateRequest(const char *url, const char *szName, const char *szMethod)
{
AsyncHttpRequest *pReq = new AsyncHttpRequest();
- pReq->m_szUrl = szUrl;
+ pReq->m_szUrl = url;
pReq->requestType = REQUEST_POST;
pReq << CHAR_PARAM("api_key", FB_API_KEY)
<< CHAR_PARAM("device_id", m_szDeviceID)
@@ -160,26 +160,15 @@ AsyncHttpRequest* FacebookProto::CreateRequestGQL(int64_t query_id) {
return pReq;
}
-NETLIBHTTPREQUEST* FacebookProto::ExecuteRequest(AsyncHttpRequest *pReq)
+MHttpResponse* FacebookProto::ExecuteRequest(AsyncHttpRequest *pReq)
{
- CMStringA str;
-
pReq->flags |= NLHRF_HTTP11;
- pReq->szUrl = pReq->m_szUrl.GetBuffer();
- if (!pReq->m_szParam.IsEmpty()) {
- if (pReq->requestType == REQUEST_GET) {
- str.Format("%s?%s", pReq->m_szUrl.c_str(), pReq->m_szParam.c_str());
- pReq->szUrl = str.GetBuffer();
- }
- else {
- pReq->dataLength = pReq->m_szParam.GetLength();
- pReq->pData = mir_strdup(pReq->m_szParam);
- }
- }
+ if (!pReq->m_szParam.IsEmpty() && pReq->requestType == REQUEST_GET)
+ pReq->m_szUrl.AppendFormat("?%s", pReq->m_szParam.c_str());
- debugLogA("Executing request:\n%s", pReq->szUrl);
+ debugLogA("Executing request:\n%s", pReq->m_szUrl.c_str());
- NETLIBHTTPREQUEST *reply = Netlib_HttpTransaction(m_hNetlibUser, pReq);
+ MHttpResponse *reply = Netlib_HttpTransaction(m_hNetlibUser, pReq);
delete pReq;
return reply;
}
diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h
index e8ea77d658..318ef336d6 100644
--- a/protocols/Facebook/src/proto.h
+++ b/protocols/Facebook/src/proto.h
@@ -332,7 +332,7 @@ class JsonReply
int m_errorCode = 0;
public:
- JsonReply(NETLIBHTTPREQUEST *);
+ JsonReply(MHttpResponse *);
~JsonReply();
__forceinline JSONNode &data() const { return *m_root; }
@@ -412,7 +412,7 @@ class FacebookProto : public PROTO<FacebookProto>
AsyncHttpRequest *CreateRequest(const char *szUrl, const char *szName, const char *szMethod);
AsyncHttpRequest *CreateRequestGQL(int64_t id);
- NETLIBHTTPREQUEST *ExecuteRequest(AsyncHttpRequest *pReq);
+ MHttpResponse *ExecuteRequest(AsyncHttpRequest *pReq);
CMStringA GetAgentString();
// Avatars
diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp
index 72ff76ac1f..db725ba6a0 100644
--- a/protocols/Facebook/src/server.cpp
+++ b/protocols/Facebook/src/server.cpp
@@ -760,16 +760,16 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root)
// wszFileName.Format(L"%s\\STK{%S}.webp", wszPath.c_str(), stickerId.c_str());
std::string szUrl = sticker["thread_image"]["uri"].as_string();
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.flags = NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
req.requestType = REQUEST_GET;
- req.szUrl = (char*)szUrl.c_str();
+ req.m_szUrl = szUrl.c_str();
- NETLIBHTTPREQUEST *pReply = Netlib_HttpTransaction(m_hNetlibUser, &req);
- if (pReply != nullptr && pReply->resultCode == 200 && pReply->pData && pReply->dataLength) {
+ MHttpResponse *pReply = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ if (pReply != nullptr && pReply->resultCode == 200 && !pReply->body.IsEmpty()) {
bSuccess = true;
FILE *out = _wfopen(wszFileName, L"wb");
- fwrite(pReply->pData, 1, pReply->dataLength, out);
+ fwrite(pReply->body, 1, pReply->body.GetLength(), out);
fclose(out);
}
}
diff --git a/protocols/Gadu-Gadu/src/avatar.cpp b/protocols/Gadu-Gadu/src/avatar.cpp
index 3ab82cd50f..c9887a1da4 100644
--- a/protocols/Gadu-Gadu/src/avatar.cpp
+++ b/protocols/Gadu-Gadu/src/avatar.cpp
@@ -51,9 +51,9 @@ bool GaduProto::getAvatarFileInfo(uin_t uin, char **avatarurl, char **avatarts)
char szUrl[128];
mir_snprintf(szUrl, "http://api.gadu-gadu.pl/avatars/%d/0.xml", uin);
- NETLIBHTTPREQUEST req = { sizeof(req) };
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = szUrl;
+ req.m_szUrl = szUrl;
req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_REDIRECT;
NLHR_PTR resp(Netlib_HttpTransaction(m_hNetlibUser, &req));
@@ -62,15 +62,15 @@ bool GaduProto::getAvatarFileInfo(uin_t uin, char **avatarurl, char **avatarts)
return false;
}
- if (resp->resultCode != 200 || !resp->dataLength || !resp->pData) {
+ if (resp->resultCode != 200 || resp->body.IsEmpty()) {
debugLogA("getAvatarFileInfo(): Invalid response code from HTTP request");
return false;
}
- if ((strncmp(resp->pData, "<result>", 8) == 0) || (strncmp(resp->pData, "<?xml", 5) == 0)) {
+ if ((strncmp(resp->body, "<result>", 8) == 0) || (strncmp(resp->body, "<?xml", 5) == 0)) {
// if this url returned xml data (before and after 11.2013 gg convention)
TiXmlDocument doc;
- if (doc.Parse(resp->pData) == 0) {
+ if (doc.Parse(resp->body) == 0) {
auto *node = TiXmlConst(doc.FirstChildElement("result"))["users"]["user"]["avatars"]["avatar"].ToElement();
const char *blank = (node != nullptr) ? node->Attribute("blank") : nullptr;
if (mir_strcmp(blank, "1")) {
@@ -84,9 +84,9 @@ bool GaduProto::getAvatarFileInfo(uin_t uin, char **avatarurl, char **avatarts)
}
}
}
- else if (strncmp(resp->pData, "{\"result\":", 10) == 0) {
+ else if (strncmp(resp->body, "{\"result\":", 10) == 0) {
// if this url returns json data (11.2013 gg convention)
- JSONNode root = JSONNode::parse(resp->pData);
+ JSONNode root = JSONNode::parse(resp->body);
if (root) {
const JSONNode &respJSONavatars = root["result"].at("users").at("user").at("avatars");
if (respJSONavatars) {
@@ -225,26 +225,26 @@ void __cdecl GaduProto::avatarrequestthread(void*)
ai.hContact = data->hContact;
ai.format = getByte(ai.hContact, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE);
- NETLIBHTTPREQUEST req = { sizeof(req) };
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = data->szAvatarURL;
+ req.m_szUrl = data->szAvatarURL;
req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_REDIRECT;
NLHR_PTR resp(Netlib_HttpTransaction(m_hNetlibUser, &req));
if (resp) {
- if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
+ if (resp->resultCode == 200 && !resp->body.IsEmpty()) {
int file_fd;
int avatarType = PA_FORMAT_UNKNOWN;
- if (strncmp(resp->pData, "\xFF\xD8", 2) == 0) avatarType = PA_FORMAT_JPEG;
- if (strncmp(resp->pData, "\x47\x49\x46\x38", 4) == 0) avatarType = PA_FORMAT_GIF;
- if (strncmp(resp->pData, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0) avatarType = PA_FORMAT_PNG;
+ if (strncmp(resp->body, "\xFF\xD8", 2) == 0) avatarType = PA_FORMAT_JPEG;
+ if (strncmp(resp->body, "\x47\x49\x46\x38", 4) == 0) avatarType = PA_FORMAT_GIF;
+ if (strncmp(resp->body, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) == 0) avatarType = PA_FORMAT_PNG;
setByte(data->hContact, GG_KEY_AVATARTYPE, (uint8_t)avatarType);
getAvatarFilename(ai.hContact, ai.filename, _countof(ai.filename));
file_fd = _wopen(ai.filename, _O_WRONLY | _O_TRUNC | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE);
if (file_fd != -1) {
- _write(file_fd, resp->pData, resp->dataLength);
+ _write(file_fd, resp->body, resp->body.GetLength());
_close(file_fd);
result = 1;
debugLogW(L"avatarrequestthread() new avatar_transfers item. Saved data to file=%s.", ai.filename);
@@ -367,49 +367,26 @@ void __cdecl GaduProto::setavatarthread(void *param)
CMStringA avatarFileB64Enc(mir_urlEncode(avatarFileB64));
- char dataPrefix[64];
- mir_snprintf(dataPrefix, "uin=%d&photo=", getDword(GG_KEY_UIN, 0));
- size_t dataPrefixLen = mir_strlen(dataPrefix);
-
- size_t dataLen = dataPrefixLen + avatarFileB64Enc.GetLength();
- char* data = (char*)mir_alloc(dataLen);
- memcpy(data, dataPrefix, dataPrefixLen);
- memcpy(data + dataPrefixLen, avatarFileB64Enc, avatarFileB64Enc.GetLength());
-
- //check if we have token, if no - receive new one
+ // check if we have token, if no - receive new one
oauth_checktoken(0);
char* token = getStringA(GG_KEY_TOKEN);
- //construct request
- NETLIBHTTPREQUEST req = {};
+ // construct request
+ MHttpRequest req = {};
req.requestType = REQUEST_POST;
- req.szUrl = "http://avatars.nowe.gg/upload";
+ req.m_szUrl = "http://avatars.nowe.gg/upload";
req.flags = NLHRF_NODUMP | NLHRF_HTTP11;
- req.headersCount = 10;
- NETLIBHTTPHEADER httpHeaders[10];
- httpHeaders[0].szName = "X-Request";
- httpHeaders[0].szValue = "JSON";
- httpHeaders[1].szName = "Authorization";
- httpHeaders[1].szValue = token;
- httpHeaders[2].szName = "X-Requested-With";
- httpHeaders[2].szValue = "XMLHttpRequest";
- httpHeaders[3].szName = "From";
- httpHeaders[3].szValue = "avatars to avatars";
- httpHeaders[4].szName = "X-IM-Web-App-Version";
- httpHeaders[4].szValue = "10,5,2,13164";
- httpHeaders[5].szName = "User-Agent";
- httpHeaders[5].szValue = "avatars to avatars";
- httpHeaders[6].szName = "From";
- httpHeaders[6].szValue = NETLIB_USER_AGENT;
- httpHeaders[7].szName = "Content-type";
- httpHeaders[7].szValue = "application/x-www-form-urlencoded; charset=utf-8";
- httpHeaders[8].szName = "Accept";
- httpHeaders[8].szValue = "application/json";
- httpHeaders[9].szName = "Referer";
- httpHeaders[9].szValue = "http://avatars.nowe.gg/.static/index_new_22.0.2_595nwh.html";
- req.headers = httpHeaders;
- req.pData = data;
- req.dataLength = int(dataLen);
+ req.AddHeader("X-Request", "JSON");
+ req.AddHeader("Authorization", token);
+ req.AddHeader("X-Requested-With", "XMLHttpRequest");
+ req.AddHeader("From", "avatars to avatars");
+ req.AddHeader("X-IM-Web-App-Version", "10,5,2,13164");
+ req.AddHeader("User-Agent", "avatars to avatars");
+ req.AddHeader("From", NETLIB_USER_AGENT);
+ req.AddHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
+ req.AddHeader("Accept", "application/json");
+ req.AddHeader("Referer", "http://avatars.nowe.gg/.static/index_new_22.0.2_595nwh.html");
+ req << INT_PARAM("uin", getDword(GG_KEY_UIN, 0)) << CHAR_PARAM("photo", avatarFileB64Enc);
// send request
int resultSuccess = 0;
@@ -417,8 +394,8 @@ void __cdecl GaduProto::setavatarthread(void *param)
{
NLHR_PTR resp(Netlib_HttpTransaction(m_hNetlibUser, &req));
if (resp) {
- if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
- debugLogA("setavatarthread(): 1 resp.data= %s", resp->pData);
+ if (resp->resultCode == 200 && !resp->body.IsEmpty()) {
+ debugLogA("setavatarthread(): 1 resp.data= %s", resp->body.c_str());
resultSuccess = 1;
}
else {
@@ -439,22 +416,14 @@ void __cdecl GaduProto::setavatarthread(void *param)
oauth_checktoken(1);
mir_free(token);
token = getStringA(GG_KEY_TOKEN);
- httpHeaders[1].szValue = token;
-
- //construct 2nd request
- memset(&req, 0, sizeof(req));
- req.requestType = REQUEST_POST;
- req.szUrl = "http://avatars.nowe.gg/upload";
- req.flags = NLHRF_NODUMP | NLHRF_HTTP11;
- req.headersCount = 10;
- req.headers = httpHeaders;
- req.pData = data;
- req.dataLength = int(dataLen);
+
+ // construct 2nd request
+ req.AddHeader("Authorization", token);
NLHR_PTR resp(Netlib_HttpTransaction(m_hNetlibUser, &req));
if (resp) {
- if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
- debugLogA("setavatarthread(): 2 resp.data= %s", resp->pData);
+ if (resp->resultCode == 200 && !resp->body.IsEmpty()) {
+ debugLogA("setavatarthread(): 2 resp.data= %s", resp->body.c_str());
resultSuccess = 1;
}
else debugLogA("setavatarthread(): Invalid response code from HTTP request [%d]", resp->resultCode);
@@ -464,7 +433,6 @@ void __cdecl GaduProto::setavatarthread(void *param)
//clean and end thread
mir_free(token);
- mir_free(data);
if (resultSuccess) {
debugLogA("setavatarthread(): User avatar set successfully.");
diff --git a/protocols/Gadu-Gadu/src/oauth.cpp b/protocols/Gadu-Gadu/src/oauth.cpp
index 932c9c1553..084b4df1bf 100644
--- a/protocols/Gadu-Gadu/src/oauth.cpp
+++ b/protocols/Gadu-Gadu/src/oauth.cpp
@@ -271,7 +271,7 @@ char *oauth_auth_header(const char *httpmethod, const char *url, OAUTHSIGNMETHOD
int GaduProto::oauth_receivetoken()
{
- char szUrl[256], uin[32], *token = nullptr, *token_secret = nullptr;
+ char uin[32], *token = nullptr, *token_secret = nullptr;
int res = 0;
HNETLIBCONN nlc = nullptr;
@@ -280,109 +280,90 @@ int GaduProto::oauth_receivetoken()
// 1. Obtaining an Unauthorized Request Token
debugLogA("oauth_receivetoken(): Obtaining an Unauthorized Request Token...");
- mir_strcpy(szUrl, "http://api.gadu-gadu.pl/request_token");
- char *str = oauth_auth_header("POST", szUrl, HMACSHA1, uin, password, nullptr, nullptr);
-
- NETLIBHTTPHEADER httpHeaders[3];
- httpHeaders[0].szName = "User-Agent";
- httpHeaders[0].szValue = GG8_VERSION;
- httpHeaders[1].szName = "Authorization";
- httpHeaders[1].szValue = str;
- httpHeaders[2].szName = "Accept";
- httpHeaders[2].szValue = "*/*";
-
- NETLIBHTTPREQUEST req = { sizeof(req) };
- req.requestType = REQUEST_POST;
- req.szUrl = szUrl;
- req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT;
- req.headersCount = 3;
- req.headers = httpHeaders;
-
- NLHR_PTR resp(Netlib_HttpTransaction(m_hNetlibUser, &req));
- if (resp) {
- nlc = resp->nlc;
- if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
- TiXmlDocument doc;
- if (0 == doc.Parse(resp->pData)) {
- TiXmlConst hXml(doc.FirstChildElement("result"));
- if (auto *p = hXml["oauth_token"].ToElement())
- token = mir_strdup(p->GetText());
-
- if (auto *p = hXml["oauth_token_secret"].ToElement())
- token_secret = mir_strdup(p->GetText());
+
+ NLHR_PTR resp(0);
+ {
+ MHttpRequest req;
+ req.requestType = REQUEST_POST;
+ req.m_szUrl = "http://api.gadu-gadu.pl/request_token";
+ req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT;
+ req.AddHeader("User-Agent", GG8_VERSION);
+ req.AddHeader("Authorization", ptrA(oauth_auth_header("POST", req.m_szUrl, HMACSHA1, uin, password, nullptr, nullptr)));
+ req.AddHeader("Accept", "*/*");
+
+ resp = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ if (resp) {
+ nlc = resp->nlc;
+ if (resp->resultCode == 200 && !resp->body.IsEmpty()) {
+ TiXmlDocument doc;
+ if (0 == doc.Parse(resp->body)) {
+ TiXmlConst hXml(doc.FirstChildElement("result"));
+ if (auto *p = hXml["oauth_token"].ToElement())
+ token = mir_strdup(p->GetText());
+
+ if (auto *p = hXml["oauth_token_secret"].ToElement())
+ token_secret = mir_strdup(p->GetText());
+ }
}
+ else debugLogA("oauth_receivetoken(): Invalid response code from HTTP request");
}
- else debugLogA("oauth_receivetoken(): Invalid response code from HTTP request");
+ else debugLogA("oauth_receivetoken(): No response from HTTP request");
}
- else debugLogA("oauth_receivetoken(): No response from HTTP request");
// 2. Obtaining User Authorization
debugLogA("oauth_receivetoken(): Obtaining User Authorization...");
- mir_free(str);
- str = oauth_uri_escape("http://www.mojageneracja.pl");
-
- mir_snprintf(szUrl, "callback_url=%s&request_token=%s&uin=%s&password=%s",
- str, token, uin, password);
- mir_free(str);
- str = mir_strdup(szUrl);
-
- memset(&req, 0, sizeof(req));
- req.requestType = REQUEST_POST;
- req.szUrl = szUrl;
- req.flags = NLHRF_NODUMP | NLHRF_HTTP11;
- req.headersCount = 3;
- req.headers = httpHeaders;
- mir_strcpy(szUrl, "https://login.gadu-gadu.pl/authorize");
- httpHeaders[1].szName = "Content-Type";
- httpHeaders[1].szValue = "application/x-www-form-urlencoded";
- req.pData = str;
- req.dataLength = (int)mir_strlen(str);
-
- resp = Netlib_HttpTransaction(m_hNetlibUser, &req);
- if (!resp)
- debugLogA("oauth_receivetoken(): No response from HTTP request");
+ {
+ MHttpRequest req;
+ req.requestType = REQUEST_POST;
+ req.m_szUrl = "https://login.gadu-gadu.pl/authorize";
+ req.flags = NLHRF_NODUMP | NLHRF_HTTP11;
+ req.m_szParam.Format("callback_url=%s&request_token=%s&uin=%s&password=%s", ptrA(oauth_uri_escape("http://www.mojageneracja.pl")), token, uin, password);
+ req.AddHeader("User-Agent", GG8_VERSION);
+ req.AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ req.AddHeader("Accept", "*/*");
+
+ resp = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ if (!resp)
+ debugLogA("oauth_receivetoken(): No response from HTTP request");
+ }
// 3. Obtaining an Access Token
debugLogA("oauth_receivetoken(): Obtaining an Access Token...");
- mir_strcpy(szUrl, "http://api.gadu-gadu.pl/access_token");
- mir_free(str);
- str = oauth_auth_header("POST", szUrl, HMACSHA1, uin, password, token, token_secret);
+
mir_free(token);
mir_free(token_secret);
token = nullptr;
token_secret = nullptr;
-
- memset(&req, 0, sizeof(req));
- req.requestType = REQUEST_POST;
- req.szUrl = szUrl;
- req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT;
- req.nlc = nlc;
- req.headersCount = 3;
- req.headers = httpHeaders;
- httpHeaders[1].szName = "Authorization";
- httpHeaders[1].szValue = str;
-
- resp = Netlib_HttpTransaction(m_hNetlibUser, &req);
- if (resp) {
- if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
- TiXmlDocument doc;
- if (0 == doc.Parse(resp->pData)) {
- TiXmlConst hXml(doc.FirstChildElement("result"));
- if (auto *p = hXml["oauth_token"].ToElement())
- token = mir_strdup(p->GetText());
-
- if (auto *p = hXml["oauth_token_secret"].ToElement())
- token_secret = mir_strdup(p->GetText());
+ {
+ MHttpRequest req;
+ req.requestType = REQUEST_POST;
+ req.m_szUrl = "http://api.gadu-gadu.pl/access_token";
+ req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT;
+ req.nlc = nlc;
+ req.AddHeader("User-Agent", GG8_VERSION);
+ req.AddHeader("Authorization", ptrA(oauth_auth_header("POST", req.m_szUrl, HMACSHA1, uin, password, token, token_secret)));
+ req.AddHeader("Accept", "*/*");
+
+ resp = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ if (resp) {
+ if (resp->resultCode == 200 && !resp->body.IsEmpty()) {
+ TiXmlDocument doc;
+ if (0 == doc.Parse(resp->body)) {
+ TiXmlConst hXml(doc.FirstChildElement("result"));
+ if (auto *p = hXml["oauth_token"].ToElement())
+ token = mir_strdup(p->GetText());
+
+ if (auto *p = hXml["oauth_token_secret"].ToElement())
+ token_secret = mir_strdup(p->GetText());
+ }
}
- }
- else debugLogA("oauth_receivetoken(): Invalid response code from HTTP request");
+ else debugLogA("oauth_receivetoken(): Invalid response code from HTTP request");
- Netlib_CloseHandle(resp->nlc);
+ Netlib_CloseHandle(resp->nlc);
+ }
+ else debugLogA("oauth_receivetoken(): No response from HTTP request");
}
- else debugLogA("oauth_receivetoken(): No response from HTTP request");
-
mir_free(password);
- mir_free(str);
if (token != nullptr && token_secret != nullptr) {
setString(GG_KEY_TOKEN, token);
diff --git a/protocols/GmailNotifier/src/check.cpp b/protocols/GmailNotifier/src/check.cpp
index b5fa2d2dee..df86f3fa0d 100644
--- a/protocols/GmailNotifier/src/check.cpp
+++ b/protocols/GmailNotifier/src/check.cpp
@@ -67,19 +67,13 @@ void CheckMailInbox(Account *curAcc)
szBody.Append("&password=");
szBody.Append(curAcc->pass);
- NETLIBHTTPHEADER headers[1] = {
- { "Content-Type", "application/x-www-form-urlencoded" }
- };
-
- NETLIBHTTPREQUEST nlr = {};
- nlr.szUrl = szUrl.GetBuffer();
- nlr.requestType = REQUEST_POST;
- nlr.headersCount = _countof(headers);
- nlr.headers = headers;
- nlr.dataLength = szBody.GetLength();
- nlr.pData = szBody.GetBuffer();
-
- NLHR_PTR nlu(Netlib_HttpTransaction(hNetlibUser, &nlr));
+ MHttpRequest nlhr;
+ nlhr.m_szUrl = szUrl.GetBuffer();
+ nlhr.m_szParam = szBody;
+ nlhr.requestType = REQUEST_POST;
+ nlhr.AddHeader("Content-Type", "application/x-www-form-urlencoded");
+
+ NLHR_PTR nlu(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (nlu == nullptr || nlu->resultCode != 200) {
mir_strcpy(curAcc->results.content, Translate("Can't send account data!"));
@@ -99,25 +93,18 @@ void CheckMailInbox(Account *curAcc)
else
szUrl.Append("/mail/feed/atom");
- NETLIBHTTPHEADER headers[1] = {
- { "Authorization", szAuth.GetBuffer() }
- };
-
- NETLIBHTTPREQUEST nlr = {};
- nlr.szUrl = szUrl.GetBuffer();
- nlr.requestType = REQUEST_GET;
- nlr.headers = headers;
- nlr.headersCount = _countof(headers);
+ MHttpRequest nlhr;
+ nlhr.m_szUrl = szUrl.GetBuffer();
+ nlhr.requestType = REQUEST_GET;
+ nlhr.AddHeader("Authorization", szAuth.GetBuffer());
- NLHR_PTR nlu(Netlib_HttpTransaction(hNetlibUser, &nlr));
+ NLHR_PTR nlu(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (nlu == nullptr) {
- mir_snprintf(curAcc->results.content, "%s [%s]", szNick.get(),
- (nlr.resultCode == 401) ? Translate("Wrong name or password!") : Translate("Can't get RSS feed!"));
-
+ mir_snprintf(curAcc->results.content, "%s [%s]", szNick.get(), Translate("Wrong name or password!"));
curAcc->results_num = -1;
}
else {
- curAcc->results_num = ParsePage(nlu->pData, &curAcc->results);
+ curAcc->results_num = ParsePage(nlu->body.GetBuffer(), &curAcc->results);
mir_snprintf(curAcc->results.content, "%s [%d]", szNick.get(), curAcc->results_num);
}
diff --git a/protocols/ICQ-WIM/src/avatars.cpp b/protocols/ICQ-WIM/src/avatars.cpp
index 452a9da444..73766e7ec8 100644
--- a/protocols/ICQ-WIM/src/avatars.cpp
+++ b/protocols/ICQ-WIM/src/avatars.cpp
@@ -106,23 +106,13 @@ INT_PTR __cdecl CIcqProto::SetAvatar(WPARAM, LPARAM lParam)
}
unsigned dwSize = (unsigned)_filelengthi64(fileId);
- char *pData = (char *)mir_alloc(dwSize);
- if (pData == nullptr) {
- _close(fileId);
- delete pReq;
- return 2;
- }
-
- _read(fileId, pData, dwSize);
+ pReq->m_szParam.Truncate(dwSize);
+ _read(fileId, pReq->m_szParam.GetBuffer(), dwSize);
_close(fileId);
- pReq->pData = pData;
- pReq->dataLength = dwSize;
-
- int iAvatarType = ProtoGetBufferFormat(pData);
+ int iAvatarType = ProtoGetBufferFormat(pReq->m_szParam);
if (iAvatarType == PA_FORMAT_UNKNOWN) {
delete pReq;
- delete pData;
return 3;
}
diff --git a/protocols/ICQ-WIM/src/file.cpp b/protocols/ICQ-WIM/src/file.cpp
index 1dc58ba06b..eb20c4c18b 100644
--- a/protocols/ICQ-WIM/src/file.cpp
+++ b/protocols/ICQ-WIM/src/file.cpp
@@ -51,10 +51,9 @@ void IcqFileTransfer::FillHeaders(AsyncHttpRequest *pReq)
pReq->AddHeader("Content-Range", CMStringA(FORMAT, "bytes %lld-%lld/%lld", pfts.currentFileProgress, pfts.currentFileProgress + dwPortion - 1, pfts.currentFileSize));
pReq->AddHeader("Content-Length", CMStringA(FORMAT, "%d", dwPortion));
- pReq->dataLength = dwPortion;
- pReq->pData = (char *)mir_alloc(dwPortion);
+ pReq->m_szParam.Truncate(dwPortion);
_lseek(m_fileId, pfts.currentFileProgress, SEEK_SET);
- _read(m_fileId, pReq->pData, dwPortion);
+ _read(m_fileId, pReq->m_szParam.GetBuffer(), dwPortion);
pfts.currentFileProgress += dwPortion;
pfts.totalProgress += dwPortion;
diff --git a/protocols/ICQ-WIM/src/groupchats.cpp b/protocols/ICQ-WIM/src/groupchats.cpp
index 968182e63b..a765426045 100644
--- a/protocols/ICQ-WIM/src/groupchats.cpp
+++ b/protocols/ICQ-WIM/src/groupchats.cpp
@@ -60,7 +60,7 @@ INT_PTR CIcqProto::SvcLeaveChat(WPARAM hContact, LPARAM)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetChatInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
if (root.error() != 20000)
@@ -191,7 +191,7 @@ void CIcqProto::InviteUserToChat(SESSION_INFO *si)
dlg.DoModal();
}
-void CIcqProto::OnLeaveChat(NETLIBHTTPREQUEST*, AsyncHttpRequest *pReq)
+void CIcqProto::OnLeaveChat(MHttpResponse*, AsyncHttpRequest *pReq)
{
db_delete_contact(INT_PTR(pReq->pUserInfo));
}
diff --git a/protocols/ICQ-WIM/src/http.cpp b/protocols/ICQ-WIM/src/http.cpp
index b422c0d57b..97fc58875d 100644
--- a/protocols/ICQ-WIM/src/http.cpp
+++ b/protocols/ICQ-WIM/src/http.cpp
@@ -147,12 +147,8 @@ AsyncHttpRequest::AsyncHttpRequest(IcqConnection conn, int iType, const char *sz
strncpy_s(m_reqId, (char*)szId, _TRUNCATE);
RpcStringFreeA(&szId);
- if (iType == REQUEST_POST) {
+ if (iType == REQUEST_POST)
AddHeader("Content-Type", "application/x-www-form-urlencoded");
-
- dataLength = m_szParam.GetLength();
- pData = m_szParam.Detach();
- }
}
void AsyncHttpRequest::ReplaceJsonParam(const JSONNode &n)
@@ -166,29 +162,15 @@ void AsyncHttpRequest::ReplaceJsonParam(const JSONNode &n)
else
root.push_back(n);
m_szParam = root.write().c_str();
-
- replaceStr(pData, nullptr);
- dataLength = 0;
}
bool CIcqProto::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.c_str(), pReq->m_szParam.c_str());
- pReq->szUrl = str.GetBuffer();
- }
- else {
- pReq->dataLength = pReq->m_szParam.GetLength();
- pReq->pData = mir_strdup(pReq->m_szParam);
- }
- }
+ if (!pReq->m_szParam.IsEmpty() && pReq->requestType == REQUEST_GET)
+ pReq->m_szUrl.AppendFormat("?%s", pReq->m_szParam.c_str());
// replace credentials inside JSON body for pure RAPI requests
- if (pReq->m_conn == CONN_RAPI && !mir_strcmp(pReq->szUrl, ICQ_ROBUST_SERVER) && !getByte(DB_KEY_PHONEREG)) {
+ if (pReq->m_conn == CONN_RAPI && !mir_strcmp(pReq->m_szUrl, ICQ_ROBUST_SERVER) && !getByte(DB_KEY_PHONEREG)) {
CMStringA szAgent(FORMAT, "%S Mail.ru Windows ICQ (version 10.0.1999)", (wchar_t*)m_szOwnId);
pReq->AddHeader("User-Agent", szAgent);
pReq->AddHeader("Content-Type", "application/json");
@@ -203,11 +185,9 @@ bool CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
if (m_iRClientId)
pReq->ReplaceJsonParam(JSONNode("clientId", m_iRClientId));
pReq->ReplaceJsonParam(JSONNode("authToken", m_szRToken));
- pReq->dataLength = pReq->m_szParam.GetLength();
- pReq->pData = mir_strdup(pReq->m_szParam);
}
- debugLogA("Executing request %s:\n%s", pReq->m_reqId, pReq->szUrl);
+ debugLogA("Executing request %s:\n%s", pReq->m_reqId, pReq->m_szUrl.c_str());
if (pReq->m_conn != CONN_NONE) {
pReq->flags |= NLHRF_PERSISTENT;
@@ -222,14 +202,14 @@ bool CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
auto &conn = m_ConnPool[pReq->m_conn];
conn.s = reply->nlc;
conn.timeout = 0;
- if (auto *pszHdr = Netlib_GetHeader(reply, "Keep-Alive")) {
+ if (auto *pszHdr = reply->FindHeader("Keep-Alive")) {
int timeout;
if (1 == sscanf(pszHdr, "timeout=%d", &timeout))
conn.timeout = timeout;
}
}
- if (pReq->m_conn == CONN_RAPI && reply->pData && strstr(reply->pData, "\"code\": 40201")) {
+ if (pReq->m_conn == CONN_RAPI && reply->body.Find("\"code\": 40201") != -1) {
RobustReply r(reply);
if (r.error() == 40201) { // robust token expired
m_szRToken.Empty();
@@ -305,7 +285,7 @@ MHttpRequest* operator<<(MHttpRequest *pReq, const GROUP_PARAM &param)
/////////////////////////////////////////////////////////////////////////////////////////
-JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
+JsonReply::JsonReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -316,7 +296,7 @@ JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
if (m_errorCode != 200)
return;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr) {
m_errorCode = 500;
return;
@@ -336,7 +316,7 @@ JsonReply::~JsonReply()
/////////////////////////////////////////////////////////////////////////////////////////
-FileReply::FileReply(NETLIBHTTPREQUEST *pReply)
+FileReply::FileReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -347,7 +327,7 @@ FileReply::FileReply(NETLIBHTTPREQUEST *pReply)
if (m_errorCode != 200)
return;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr) {
m_errorCode = 500;
return;
@@ -364,7 +344,7 @@ FileReply::~FileReply()
/////////////////////////////////////////////////////////////////////////////////////////
-RobustReply::RobustReply(NETLIBHTTPREQUEST *pReply)
+RobustReply::RobustReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -375,7 +355,7 @@ RobustReply::RobustReply(NETLIBHTTPREQUEST *pReply)
if (m_errorCode != 200)
return;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr) {
m_errorCode = 500;
return;
diff --git a/protocols/ICQ-WIM/src/http.h b/protocols/ICQ-WIM/src/http.h
index 5bbccd0be7..1b201d097a 100644
--- a/protocols/ICQ-WIM/src/http.h
+++ b/protocols/ICQ-WIM/src/http.h
@@ -49,7 +49,7 @@ class JsonReply
CMStringA m_requestId;
public:
- JsonReply(NETLIBHTTPREQUEST*);
+ JsonReply(MHttpResponse*);
~JsonReply();
__forceinline const CMStringA& requestId() const { return m_requestId; }
@@ -65,7 +65,7 @@ class FileReply
JSONNode* m_data = nullptr;
public:
- FileReply(NETLIBHTTPREQUEST*);
+ FileReply(MHttpResponse*);
~FileReply();
__forceinline JSONNode& data() const { return *m_data; }
@@ -80,7 +80,7 @@ class RobustReply
JSONNode *m_results = nullptr;
public:
- RobustReply(NETLIBHTTPREQUEST*);
+ RobustReply(MHttpResponse*);
~RobustReply();
__forceinline JSONNode &result() const { return *m_result; }
diff --git a/protocols/ICQ-WIM/src/ignore.cpp b/protocols/ICQ-WIM/src/ignore.cpp
index 6dd86c51fb..a07b5271c7 100644
--- a/protocols/ICQ-WIM/src/ignore.cpp
+++ b/protocols/ICQ-WIM/src/ignore.cpp
@@ -26,7 +26,7 @@ void CIcqProto::GetPermitDeny()
Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/preference/getPermitDeny", &CIcqProto::OnGetPermitDeny) << AIMSID(this));
}
-void CIcqProto::OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CIcqProto::OnGetPermitDeny(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (root.error() == 200)
diff --git a/protocols/ICQ-WIM/src/mra.cpp b/protocols/ICQ-WIM/src/mra.cpp
index b65ae238dc..751734e43b 100644
--- a/protocols/ICQ-WIM/src/mra.cpp
+++ b/protocols/ICQ-WIM/src/mra.cpp
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-void CIcqProto::SendMrimLogin(NETLIBHTTPREQUEST *pReply)
+void CIcqProto::SendMrimLogin(MHttpResponse *pReply)
{
m_szMraCookie = pReply->GetCookies();
@@ -33,7 +33,7 @@ void CIcqProto::SendMrimLogin(NETLIBHTTPREQUEST *pReply)
Push(pReq);
}
-void CIcqProto::OnCheckMrimLogin(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CIcqProto::OnCheckMrimLogin(MHttpResponse *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
switch (root.error()) {
@@ -98,7 +98,7 @@ void CIcqProto::OnCheckMrimLogin(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
StartSession();
}
-void CIcqProto::OnCheckMraAuth(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CIcqProto::OnCheckMraAuth(MHttpResponse *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
switch (root.error()) {
@@ -113,7 +113,7 @@ void CIcqProto::OnCheckMraAuth(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
}
}
-void CIcqProto::OnCheckMraAuthFinal(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CIcqProto::OnCheckMraAuthFinal(MHttpResponse *pReply, AsyncHttpRequest *)
{
switch (pReply->resultCode) {
case 200:
diff --git a/protocols/ICQ-WIM/src/options.cpp b/protocols/ICQ-WIM/src/options.cpp
index b06ee210a1..9036ed95c9 100644
--- a/protocols/ICQ-WIM/src/options.cpp
+++ b/protocols/ICQ-WIM/src/options.cpp
@@ -133,7 +133,7 @@ struct CIcqRegistrationDlg : public CIcqDlgBase
}
};
-void CIcqProto::OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnCheckPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
if (pReply == nullptr || pReply->resultCode != 200)
return;
@@ -142,7 +142,7 @@ void CIcqProto::OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
pDlg->btnSendSms.Disable();
pDlg->edtCode.Disable();
- JSONROOT root(pReply->pData);
+ JSONROOT root(pReply->body);
CMStringW wszStatus((*root)["status"].as_mstring());
if (wszStatus != L"OK") {
pDlg->edtCode.SetText((*root)["printable"].as_mstring());
@@ -159,7 +159,7 @@ void CIcqProto::OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
Push(pNew);
}
-void CIcqProto::OnNormalizePhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnNormalizePhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
@@ -173,7 +173,7 @@ void CIcqProto::OnNormalizePhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pR
pDlg->btnSendSms.Enable();
}
-void CIcqProto::OnValidateSms(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnValidateSms(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
JsonReply root(pReply);
if (root.error() != 200)
@@ -187,7 +187,7 @@ void CIcqProto::OnValidateSms(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
pDlg->edtCode.SetText(L"");
}
-void CIcqProto::OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnLoginViaPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp
index 2f2d8fdf32..1be03cc30d 100644
--- a/protocols/ICQ-WIM/src/poll.cpp
+++ b/protocols/ICQ-WIM/src/poll.cpp
@@ -362,7 +362,7 @@ void CIcqProto::ProcessTyping(const JSONNode &ev)
}
}
-void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CIcqProto::OnFetchEvents(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
if (root.error() != 200) {
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 68567975b1..ac913a8afe 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -242,7 +242,7 @@ void CIcqProto::OnEventDeleted(MCONTACT hContact, MEVENT hEvent)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnFileRecv(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnFileRecv(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
if (pReply->resultCode != 200)
return;
@@ -255,10 +255,10 @@ void CIcqProto::OnFileRecv(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
return;
}
- int cbWritten = _write(fileId, pReply->pData, pReply->dataLength);
+ int cbWritten = _write(fileId, pReply->body, pReply->body.GetLength());
_close(fileId);
- if (cbWritten != pReply->dataLength) {
- debugLogW(L"Error writing data into [%s]: %d instead of %d", ofd->wszPath.c_str(), cbWritten, pReply->dataLength);
+ if (cbWritten != pReply->body.GetLength()) {
+ debugLogW(L"Error writing data into [%s]: %d instead of %d", ofd->wszPath.c_str(), cbWritten, pReply->body.GetLength());
return;
}
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index 44def39b16..3ca731e905 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -229,7 +229,7 @@ class CIcqProto : public PROTO<CIcqProto>
void RetrieveUserCaps(IcqUser *pUser);
void RetrieveUserHistory(MCONTACT, __int64 startMsgId, bool bCreateRead);
void RetrieveUserInfo(MCONTACT hContact);
- void SendMrimLogin(NETLIBHTTPREQUEST *pReply);
+ void SendMrimLogin(MHttpResponse *pReply);
void SendMessageParts(MCONTACT hContact, const JSONNode &parts, IcqOwnMessage *pOwn = nullptr);
void SetOwnId(const CMStringW &wszId);
void SetServerStatus(int iNewStatus);
@@ -263,36 +263,36 @@ class CIcqProto : public PROTO<CIcqProto>
__int64 getId(MCONTACT hContact, const char *szSetting);
void setId(MCONTACT hContact, const char *szSetting, __int64 iValue);
- void OnAddBuddy(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnAddClient(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnCheckMraAuth(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnCheckMraAuthFinal(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnCheckMrimLogin(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnCheckPassword(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnFileInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnFileRecv(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetPatches(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGePresence(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetUserCaps(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnLeaveChat(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnNormalizePhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnSearchResults(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnSendMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnSessionEnd(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
- void OnValidateSms(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
+ void OnAddBuddy(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnAddClient(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnCheckMraAuth(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnCheckMraAuthFinal(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnCheckMrimLogin(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnCheckPassword(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnCheckPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnFetchEvents(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnFileContinue(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnFileInit(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnFileInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnFileRecv(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGenToken(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetChatInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetPatches(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetPermitDeny(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGePresence(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetSticker(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetUserCaps(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetUserHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnGetUserInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnLeaveChat(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnLoginViaPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnNormalizePhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnReceiveAvatar(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnSearchResults(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnSendMessage(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnSessionEnd(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnStartSession(MHttpResponse *pReply, AsyncHttpRequest *pReq);
+ void OnValidateSms(MHttpResponse *pReply, AsyncHttpRequest *pReq);
void ProcessBuddyList(const JSONNode &pRoot);
void ProcessDiff(const JSONNode &pRoot);
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 36887220fa..e62a609cc4 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -133,7 +133,7 @@ void CIcqProto::CheckPassword()
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnFileInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnFileInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
IcqFileInfo **res = (IcqFileInfo **)pReq->pUserInfo;
*res = nullptr;
@@ -691,7 +691,7 @@ LBL_Error:
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGetUserCaps(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetUserCaps(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
JsonReply root(pReply);
if (root.error() != 200)
@@ -718,7 +718,7 @@ void CIcqProto::RetrieveUserCaps(IcqUser *pUser)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGePresence(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGePresence(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
JsonReply root(pReply);
if (root.error() != 200)
@@ -744,7 +744,7 @@ void CIcqProto::RetrievePresence(MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetUserInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
if (root.error() != 20000) {
@@ -774,7 +774,7 @@ void CIcqProto::RetrieveUserInfo(MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGetPatches(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetPatches(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
if (root.error() != 20000)
@@ -828,7 +828,7 @@ void CIcqProto::ProcessPatchVersion(MCONTACT hContact, __int64 currPatch)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetUserHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
if (root.error() != 20000)
@@ -998,7 +998,7 @@ void CIcqProto::StartSession()
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnAddBuddy(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnAddBuddy(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
JsonReply root(pReply);
if (root.error() != 200)
@@ -1032,7 +1032,7 @@ void CIcqProto::OnAddBuddy(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
}
}
-void CIcqProto::OnAddClient(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnAddClient(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
bool *pRet = (bool*)pReq->pUserInfo;
@@ -1048,7 +1048,7 @@ void CIcqProto::OnAddClient(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
*pRet = true;
}
-void CIcqProto::OnCheckPassword(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CIcqProto::OnCheckPassword(MHttpResponse *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
switch (root.error()) {
@@ -1087,7 +1087,7 @@ void CIcqProto::OnCheckPassword(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
StartSession();
}
-void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
+void CIcqProto::OnFileContinue(MHttpResponse *pReply, AsyncHttpRequest *pOld)
{
IcqFileTransfer *pTransfer = (IcqFileTransfer*)pOld->pUserInfo;
if (pTransfer->m_bCanceled) {
@@ -1155,7 +1155,7 @@ LBL_Error:
ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, pTransfer, (LPARAM)&pTransfer->pfts);
}
-void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
+void CIcqProto::OnFileInit(MHttpResponse *pReply, AsyncHttpRequest *pOld)
{
IcqFileTransfer *pTransfer = (IcqFileTransfer*)pOld->pUserInfo;
if (pTransfer->m_bCanceled) {
@@ -1192,7 +1192,7 @@ LBL_Error:
/////////////////////////////////////////////////////////////////////////////////////////
// Support for stickers
-void CIcqProto::OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnGetSticker(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
if (pReply->resultCode != 200) {
debugLogA("Error getting sticker: %d", pReply->resultCode);
@@ -1204,7 +1204,7 @@ void CIcqProto::OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
CMStringW wszFileName(FORMAT, L"%s\\STK{%s}.png", wszPath.c_str(), (wchar_t*)pReq->pUserInfo);
FILE *out = _wfopen(wszFileName, L"wb");
- fwrite(pReply->pData, 1, pReply->dataLength, out);
+ fwrite(pReply->body, 1, pReply->body.GetLength(), out);
fclose(out);
SmileyAdd_LoadContactSmileys(SMADD_FILE, m_szModuleName, wszFileName);
@@ -1212,7 +1212,7 @@ void CIcqProto::OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+void CIcqProto::OnGenToken(MHttpResponse *pReply, AsyncHttpRequest*)
{
RobustReply root(pReply);
if (root.error() != 20000)
@@ -1222,7 +1222,7 @@ void CIcqProto::OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
m_szRToken = results["authToken"].as_mstring();
}
-void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CIcqProto::OnStartSession(MHttpResponse *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
switch (root.error()) {
@@ -1279,18 +1279,18 @@ void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
ForkThread(&CIcqProto::PollThread);
}
-void CIcqProto::OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnReceiveAvatar(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
PROTO_AVATAR_INFORMATION ai = {};
ai.hContact = pReq->hContact;
- if (pReply->resultCode != 200 || pReply->pData == nullptr) {
+ if (pReply->resultCode != 200 || pReply->body.IsEmpty()) {
LBL_Error:
ProtoBroadcastAck(pReq->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai);
return;
}
- const char *szContentType = Netlib_GetHeader(pReply, "Content-Type");
+ const char *szContentType = pReply->FindHeader("Content-Type");
if (szContentType == nullptr)
szContentType = "image/jpeg";
@@ -1302,7 +1302,7 @@ LBL_Error:
if (out == nullptr)
goto LBL_Error;
- fwrite(pReply->pData, pReply->dataLength, 1, out);
+ fwrite(pReply->body, pReply->body.GetLength(), 1, out);
fclose(out);
if (pReq->hContact != 0) {
@@ -1312,7 +1312,7 @@ LBL_Error:
else ReportSelfAvatarChanged();
}
-void CIcqProto::OnSearchResults(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnSearchResults(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
if (root.error() != 20000) {
@@ -1347,7 +1347,7 @@ void CIcqProto::OnSearchResults(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pRe
/////////////////////////////////////////////////////////////////////////////////////////
// Send message
-void CIcqProto::OnSendMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+void CIcqProto::OnSendMessage(MHttpResponse *pReply, AsyncHttpRequest *pReq)
{
IcqOwnMessage *ownMsg = (IcqOwnMessage *)pReq->pUserInfo;
@@ -1394,7 +1394,7 @@ void CIcqProto::SendMessageParts(MCONTACT hContact, const JSONNode &parts, IcqOw
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::OnSessionEnd(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *)
+void CIcqProto::OnSessionEnd(MHttpResponse *pReply, AsyncHttpRequest *)
{
JsonReply root(pReply);
if (root.error() == 200) {
diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp
index ebd33b3d93..c35069a294 100644
--- a/protocols/JabberG/src/jabber_file.cpp
+++ b/protocols/JabberG/src/jabber_file.cpp
@@ -49,10 +49,10 @@ void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *ofd)
}
// initialize the netlib request
- NETLIBHTTPREQUEST nlhr = {};
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_REDIRECT;
- nlhr.szUrl = (char *)url;
+ nlhr.m_szUrl = url;
// download the page
NLHR_PTR nlhrReply(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
@@ -61,18 +61,18 @@ void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *ofd)
size_t written = 0;
if (f) {
if (encrypted) {
- int payload_len = nlhrReply->dataLength - 16;
+ int payload_len = nlhrReply->body.GetLength() - 16;
if (payload_len > 0) {
uint8_t ivkey[44];
hex2bin(hexkey, ivkey, 44);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
EVP_DecryptInit(ctx, EVP_aes_256_gcm(), ivkey + 12, ivkey);
- EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, nlhrReply->pData + payload_len);
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (uint8_t *)nlhrReply->body.c_str() + payload_len);
int outl = 0, round_len = 0;
uint8_t *out = (uint8_t *)mir_alloc(payload_len);
- EVP_DecryptUpdate(ctx, out, &outl, (uint8_t *)nlhrReply->pData, (int)payload_len);
+ EVP_DecryptUpdate(ctx, out, &outl, (uint8_t *)nlhrReply->body.c_str(), (int)payload_len);
int dec_success = EVP_DecryptFinal(ctx, out + outl, &round_len);
outl += round_len;
EVP_CIPHER_CTX_free(ctx);
@@ -82,8 +82,8 @@ void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *ofd)
mir_free(out);
}
}
- else if (fwrite(nlhrReply->pData, 1, nlhrReply->dataLength, f) == size_t(nlhrReply->dataLength))
- written = nlhrReply->dataLength;
+ else if (fwrite(nlhrReply->body, 1, nlhrReply->body.GetLength(), f) == size_t(nlhrReply->body.GetLength()))
+ written = nlhrReply->body.GetLength();
fclose(f);
}
@@ -127,16 +127,16 @@ void CJabberProto::OnReceiveOfflineFile(DB::FILE_BLOB &blob, void *pHandle)
void __cdecl CJabberProto::FileReceiveHttpThread(filetransfer *ft)
{
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = ft->httpPath;
+ req.m_szUrl = ft->httpPath;
NLHR_PTR pResp(Netlib_HttpTransaction(m_hNetlibUser, &req));
if (pResp && pResp->resultCode == 200) {
- ft->std.currentFileSize = pResp->dataLength;
+ ft->std.currentFileSize = pResp->body.GetLength();
ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft);
- FtReceive(ft, pResp->pData, pResp->dataLength);
+ FtReceive(ft, pResp->body.GetBuffer(), pResp->body.GetLength());
ft->complete();
}
@@ -154,9 +154,9 @@ void CJabberProto::FileProcessHttpDownload(MCONTACT hContact, const char *jid, c
szName.AppendChar(*b++);
auto *pszName = szName.c_str();
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.requestType = REQUEST_HEAD;
- req.szUrl = (char*)pszUrl;
+ req.m_szUrl = pszUrl;
filetransfer *ft = new filetransfer(this, 0);
ft->jid = mir_strdup(jid);
diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp
index 9ca292ca71..a489aa696c 100644
--- a/protocols/JabberG/src/jabber_ft.cpp
+++ b/protocols/JabberG/src/jabber_ft.cpp
@@ -691,22 +691,16 @@ LBL_Fail:
if (!szUrl)
goto LBL_Fail;
- NETLIBHTTPHEADER hdr[10];
-
- NETLIBHTTPREQUEST nlhr = {};
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_PUT;
nlhr.flags = NLHRF_NODUMPSEND | NLHRF_SSL | NLHRF_REDIRECT;
- nlhr.szUrl = (char *)szUrl;
+ nlhr.m_szUrl = szUrl;
for (auto *it : TiXmlFilter(putNode, "header")) {
auto *szName = it->Attribute("name");
auto *szValue = it->GetText();
- if (szName && szValue && nlhr.headersCount < _countof(hdr)) {
- nlhr.headers = hdr;
- hdr[nlhr.headersCount].szName = (char *)szName;
- hdr[nlhr.headersCount].szValue = (char *)szValue;
- nlhr.headersCount++;
- }
+ if (szName && szValue)
+ nlhr.AddHeader(szName, szValue);
}
const wchar_t *pwszFileName = ft->std.pszFiles.w[ft->std.currentFileNumber];
@@ -728,8 +722,8 @@ LBL_Fail:
EVP_EncryptInit(ctx, EVP_aes_256_gcm(), key, iv);
int tmp_len = 0, outl;
- //EVP_EncryptUpdate(ctx, nullptr, &outl, aad, _countof(aad));
- unsigned char *out = (unsigned char *)mir_alloc(_filelength(fileId) + _countof(key) - 1 + _countof(tag));
+ nlhr.m_szParam.Truncate(_filelength(fileId) + _countof(key) - 1 + _countof(tag));
+ unsigned char *out = (unsigned char *)nlhr.m_szParam.GetBuffer();
unsigned char *in = (unsigned char *)mir_alloc(128 * 1024);
for (;;) {
int inl = _read(fileId, in, 128 * 1024);
@@ -746,13 +740,11 @@ LBL_Fail:
EVP_CIPHER_CTX_free(ctx);
memcpy(out + tmp_len, tag, _countof(tag));
- nlhr.dataLength = tmp_len + _countof(tag);
- nlhr.pData = (char *)out;
}
else {
- nlhr.dataLength = _filelength(fileId);
- nlhr.pData = new char[nlhr.dataLength];
- _read(fileId, nlhr.pData, nlhr.dataLength);
+ int iLength = _filelength(fileId);
+ nlhr.m_szParam.Truncate(iLength);
+ _read(fileId, nlhr.m_szParam.GetBuffer(), iLength);
}
_close(fileId);
diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp
index e018c39b40..441b5de49c 100644
--- a/protocols/JabberG/src/jabber_util.cpp
+++ b/protocols/JabberG/src/jabber_util.cpp
@@ -881,17 +881,17 @@ void __cdecl CJabberProto::LoadHttpAvatars(void* param)
OBJLIST<JABBER_HTTP_AVATARS> &avs = *(OBJLIST<JABBER_HTTP_AVATARS>*)param;
HNETLIBCONN hHttpCon = nullptr;
for (auto &it : avs) {
- NETLIBHTTPREQUEST nlhr = { 0 };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_HTTP11 | NLHRF_REDIRECT | NLHRF_PERSISTENT;
- nlhr.szUrl = it->Url;
+ nlhr.m_szUrl = it->Url;
nlhr.nlc = hHttpCon;
NLHR_PTR res(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
if (res) {
hHttpCon = res->nlc;
- if (res->resultCode == 200 && res->dataLength) {
- int pictureType = ProtoGetBufferFormat(res->pData);
+ if (res->resultCode == 200 && !res->body.IsEmpty()) {
+ int pictureType = ProtoGetBufferFormat(res->body);
if (pictureType != PA_FORMAT_UNKNOWN) {
PROTO_AVATAR_INFORMATION ai;
ai.format = pictureType;
@@ -909,7 +909,7 @@ void __cdecl CJabberProto::LoadHttpAvatars(void* param)
uint8_t digest[MIR_SHA1_HASH_SIZE];
mir_sha1_ctx sha;
mir_sha1_init(&sha);
- mir_sha1_append(&sha, (uint8_t*)res->pData, res->dataLength);
+ mir_sha1_append(&sha, (uint8_t*)res->body.c_str(), res->body.GetLength());
mir_sha1_finish(&sha, digest);
bin2hex(digest, sizeof(digest), buffer);
@@ -920,7 +920,7 @@ void __cdecl CJabberProto::LoadHttpAvatars(void* param)
wcsncpy_s(ai.filename, tszFileName, _TRUNCATE);
FILE* out = _wfopen(tszFileName, L"wb");
if (out != nullptr) {
- fwrite(res->pData, res->dataLength, 1, out);
+ fwrite(res->body, res->body.GetLength(), 1, out);
fclose(out);
setString(ai.hContact, "AvatarHash", buffer);
ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
diff --git a/protocols/MinecraftDynmap/src/communication.cpp b/protocols/MinecraftDynmap/src/communication.cpp
index 47e6ec4480..e9e035404d 100644
--- a/protocols/MinecraftDynmap/src/communication.cpp
+++ b/protocols/MinecraftDynmap/src/communication.cpp
@@ -21,18 +21,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-http::response MinecraftDynmapProto::sendRequest(const int request_type, std::string *post_data, std::string *get_data)
+MHttpResponse* MinecraftDynmapProto::sendRequest(const int request_type, std::string *post_data, std::string *get_data)
{
- http::response resp;
-
// Prepare the request
- NETLIBHTTPREQUEST nlhr = { sizeof(NETLIBHTTPREQUEST) };
+ MHttpRequest nlhr;
// FIXME: get server
// Set request URL
std::string url = m_server + chooseAction(request_type, get_data);
- nlhr.szUrl = (char*)url.c_str();
+ nlhr.m_szUrl = url.c_str();
// Set timeout (bigger for channel request)
nlhr.timeout = 1000 * ((request_type == MINECRAFTDYNMAP_REQUEST_EVENTS) ? 65 : 20);
@@ -40,15 +38,18 @@ http::response MinecraftDynmapProto::sendRequest(const int request_type, std::st
// Set request type (GET/POST) and eventually also POST data
if (post_data != nullptr) {
nlhr.requestType = REQUEST_POST;
- nlhr.pData = (char*)(*post_data).c_str();
- nlhr.dataLength = (int)post_data->length();
- }
- else {
- nlhr.requestType = REQUEST_GET;
+ nlhr.SetData(post_data->c_str(), post_data->length());
}
+ else nlhr.requestType = REQUEST_GET;
// Set headers - it depends on requestType so it must be after setting that
- nlhr.headers = get_request_headers(nlhr.requestType, &nlhr.headersCount);
+ if (request_type == REQUEST_POST)
+ nlhr.AddHeader("Content-Type", "application/json; charset=utf-8");
+
+ nlhr.AddHeader("Cookie", m_cookie.c_str());
+ nlhr.AddHeader("User-Agent", g_strUserAgent.c_str());
+ nlhr.AddHeader("Accept", "*/*");
+ nlhr.AddHeader("Accept-Language", "en,en-US;q=0.9");
// Set flags
nlhr.flags = NLHRF_HTTP11;
@@ -78,12 +79,10 @@ http::response MinecraftDynmapProto::sendRequest(const int request_type, std::st
break;
}
- debugLogA("@@@@@ Sending request to '%s'", nlhr.szUrl);
+ debugLogA("@@@@@ Sending request to '%s'", nlhr.m_szUrl.c_str());
// Send the request
- NLHR_PTR pnlhr(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
-
- mir_free(nlhr.headers);
+ auto *pnlhr = Netlib_HttpTransaction(m_hNetlibUser, &nlhr);
// Remember the persistent connection handle (or not)
switch (request_type) {
@@ -100,22 +99,7 @@ http::response MinecraftDynmapProto::sendRequest(const int request_type, std::st
break;
}
- // Check and copy response data
- if (pnlhr != nullptr)
- {
- debugLogA("@@@@@ Got response with code %d", pnlhr->resultCode);
- store_headers(&resp, pnlhr->headers, pnlhr->headersCount);
- resp.code = pnlhr->resultCode;
- resp.data = pnlhr->pData ? pnlhr->pData : "";
-
- // debugLogA("&&&&& Got response: %s", resp.data.c_str());
- } else {
- debugLogA("!!!!! No response from server (time-out)");
- resp.code = HTTP_CODE_FAKE_DISCONNECTED;
- // Better to have something set explicitely as this value is compaired in all communication requests
- }
-
- return resp;
+ return pnlhr;
}
//////////////////////////////////////////////////////////////////////////////
@@ -138,56 +122,17 @@ std::string MinecraftDynmapProto::chooseAction(int request_type, std::string *ge
}
}
-
-NETLIBHTTPHEADER* MinecraftDynmapProto::get_request_headers(int request_type, int* headers_count)
-{
- if (request_type == REQUEST_POST)
- *headers_count = 5;
- else
- *headers_count = 4;
-
- NETLIBHTTPHEADER *headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER)*(*headers_count));
-
- if (request_type == REQUEST_POST) {
- headers[4].szName = "Content-Type";
- headers[4].szValue = "application/json; charset=utf-8";
- }
-
- headers[3].szName = "Cookie";
- headers[3].szValue = (char *)m_cookie.c_str();
- headers[2].szName = "User-Agent";
- headers[2].szValue = (char *)g_strUserAgent.c_str();
- headers[1].szName = "Accept";
- headers[1].szValue = "*/*";
- headers[0].szName = "Accept-Language";
- headers[0].szValue = "en,en-US;q=0.9";
-
- return headers;
-}
-
-void MinecraftDynmapProto::store_headers(http::response* resp, NETLIBHTTPHEADER* headers, int headersCount)
-{
- for (size_t i = 0; i < (size_t)headersCount; i++) {
- std::string header_name = headers[i].szName;
- std::string header_value = headers[i].szValue;
-
- resp->headers[header_name] = header_value;
- }
-}
-
//////////////////////////////////////////////////////////////////////////////
bool MinecraftDynmapProto::doSignOn()
{
handleEntry(__FUNCTION__);
- http::response resp = sendRequest(MINECRAFTDYNMAP_REQUEST_CONFIGURATION);
-
- if (resp.code != HTTP_CODE_OK) {
+ NLHR_PTR resp(sendRequest(MINECRAFTDYNMAP_REQUEST_CONFIGURATION));
+ if (!resp || resp->resultCode != HTTP_CODE_OK)
return handleError(__FUNCTION__, "Can't load configuration", true);
- }
- JSONNode root = JSONNode::parse(resp.data.c_str());
+ JSONNode root = JSONNode::parse(resp->body);
if (!root)
return false;
@@ -212,16 +157,14 @@ bool MinecraftDynmapProto::doSignOn()
m_updateRate = rate_.as_int();
m_cookie.clear();
- if (resp.headers.find("Set-Cookie") != resp.headers.end()) {
- // Load Session identifier
- std::string cookies = resp.headers["Set-Cookie"];
+ if (auto *pszCookie = resp->FindHeader("Set-Cookie")) {
+ m_cookie = pszCookie;
+ // Load Session identifier
const char *findStr = "JSESSIONID=";
- std::string::size_type start = cookies.find(findStr);
-
- if (start != std::string::npos) {
- m_cookie = cookies.substr(start, cookies.find(";") - start);
- }
+ std::string::size_type start = m_cookie.find(findStr);
+ if (start != std::string::npos)
+ m_cookie = m_cookie.substr(start, m_cookie.find(";") - start);
}
if (m_cookie.empty()) {
@@ -236,12 +179,11 @@ bool MinecraftDynmapProto::doEvents()
handleEntry(__FUNCTION__);
// Get update
- http::response resp = sendRequest(MINECRAFTDYNMAP_REQUEST_EVENTS);
-
- if (resp.code != HTTP_CODE_OK)
+ NLHR_PTR resp(sendRequest(MINECRAFTDYNMAP_REQUEST_EVENTS));
+ if (!resp || resp->resultCode != HTTP_CODE_OK)
return handleError(__FUNCTION__, "Response is not code 200");
- JSONNode root = JSONNode::parse(resp.data.c_str());
+ JSONNode root = JSONNode::parse(resp->body);
if (!root)
return handleError(__FUNCTION__, "Invalid JSON response");
@@ -290,10 +232,9 @@ bool MinecraftDynmapProto::doSendMessage(const std::string &message_text)
json.push_back(JSONNode("message", message_text.c_str()));
std::string data = json.write();
- http::response resp = sendRequest(MINECRAFTDYNMAP_REQUEST_MESSAGE, &data);
-
- if (resp.code == HTTP_CODE_OK) {
- JSONNode root = JSONNode::parse(resp.data.c_str());
+ NLHR_PTR resp(sendRequest(MINECRAFTDYNMAP_REQUEST_MESSAGE, &data));
+ if (resp && resp->resultCode == HTTP_CODE_OK) {
+ JSONNode root = JSONNode::parse(resp->body);
if (root) {
const JSONNode &error_ = root["error"];
if (error_) {
@@ -315,15 +256,14 @@ std::string MinecraftDynmapProto::doGetPage(const int request_type)
{
handleEntry(__FUNCTION__);
- http::response resp = sendRequest(request_type);
-
- if (resp.code == HTTP_CODE_OK) {
+ NLHR_PTR resp(sendRequest(request_type));
+ if (resp && resp->resultCode == HTTP_CODE_OK) {
handleSuccess(__FUNCTION__);
- } else {
- handleError(__FUNCTION__);
+ return resp->body.c_str();
}
- return resp.data;
+ handleError(__FUNCTION__);
+ return "";
}
void MinecraftDynmapProto::SignOnWorker(void*)
diff --git a/protocols/MinecraftDynmap/src/proto.h b/protocols/MinecraftDynmap/src/proto.h
index fb8046d79b..9cebc8c128 100644
--- a/protocols/MinecraftDynmap/src/proto.h
+++ b/protocols/MinecraftDynmap/src/proto.h
@@ -86,8 +86,6 @@ public:
HANDLE chatHandle_;
// Data storage
- void store_headers(http::response *resp, NETLIBHTTPHEADER *headers, int headers_count);
-
std::string get_server(bool not_last = false);
std::string get_language();
@@ -104,9 +102,8 @@ public:
void __inline reset_error() { error_count_ = 0; }
// HTTP communication
- http::response sendRequest(const int request_type, std::string *post_data = nullptr, std::string *get_data = nullptr);
+ MHttpResponse* sendRequest(const int request_type, std::string *post_data = nullptr, std::string *get_data = nullptr);
std::string chooseAction(int, std::string *get_data = nullptr);
- NETLIBHTTPHEADER *get_request_headers(int request_type, int *headers_count);
// Requests and processing
bool doSignOn();
diff --git a/protocols/MinecraftDynmap/src/utils.h b/protocols/MinecraftDynmap/src/utils.h
index c42fb86d9e..135faf0d11 100644
--- a/protocols/MinecraftDynmap/src/utils.h
+++ b/protocols/MinecraftDynmap/src/utils.h
@@ -30,17 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HTTP_CODE_FAKE_DISCONNECTED 0
#define HTTP_CODE_FAKE_ERROR 1
-namespace http
-{
- struct response
- {
- response() : code(0) {}
- int code;
- std::map< std::string, std::string > headers;
- std::string data;
- };
-}
-
class ScopedLock
{
public:
diff --git a/protocols/NewsAggregator/Src/Utils.cpp b/protocols/NewsAggregator/Src/Utils.cpp
index 328c63bc8e..c5f1df5b95 100644
--- a/protocols/NewsAggregator/Src/Utils.cpp
+++ b/protocols/NewsAggregator/Src/Utils.cpp
@@ -47,48 +47,35 @@ void NetlibUnInit()
void GetNewsData(wchar_t *tszUrl, char **szData, MCONTACT hContact, CFeedEditor *pEditDlg)
{
Netlib_LogfW(hNetlibUser, L"Getting feed data %s.", tszUrl);
- NETLIBHTTPREQUEST nlhr = { 0 };
+ MHttpRequest nlhr;
// initialize the netlib request
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
if (wcsstr(tszUrl, L"https://") != nullptr)
nlhr.flags |= NLHRF_SSL;
- char *szUrl = mir_u2a(tszUrl);
- nlhr.szUrl = szUrl;
+ nlhr.m_szUrl = _T2A(tszUrl);
nlhr.nlc = hNetlibHttp;
// change the header so the plugin is pretended to be IE 6 + WinXP
- NETLIBHTTPHEADER headers[5];
- nlhr.headersCount = 4;
- nlhr.headers = headers;
- nlhr.headers[0].szName = "User-Agent";
- nlhr.headers[0].szValue = NETLIB_USER_AGENT;
- nlhr.headers[1].szName = "Cache-Control";
- nlhr.headers[1].szValue = "no-cache";
- nlhr.headers[2].szName = "Pragma";
- nlhr.headers[2].szValue = "no-cache";
- nlhr.headers[3].szName = "Connection";
- nlhr.headers[3].szValue = "close";
- char auth[256];
- if (g_plugin.getByte(hContact, "UseAuth", 0) || (pEditDlg && pEditDlg->m_useauth.IsChecked()) /*IsDlgButtonChecked(hwndDlg, IDC_USEAUTH)*/) {
- nlhr.headersCount++;
- nlhr.headers[4].szName = "Authorization";
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
+ nlhr.AddHeader("Connection", "close");
+ if (g_plugin.getByte(hContact, "UseAuth", 0) || (pEditDlg && pEditDlg->m_useauth.IsChecked())) {
+ char auth[256];
CreateAuthString(auth, hContact, pEditDlg);
- nlhr.headers[4].szValue = auth;
+ nlhr.AddHeader("Authorization", auth);
}
// download the page
NLHR_PTR nlhrReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (nlhrReply) {
// if the recieved code is 200 OK
- if (nlhrReply->resultCode == 200 && nlhrReply->dataLength > 0) {
+ if (nlhrReply->resultCode == 200 && !nlhrReply->body.IsEmpty()) {
Netlib_LogfW(hNetlibUser, L"Code 200: Succeeded getting feed data %s.", tszUrl);
- // allocate memory and save the retrieved data
- *szData = (char *)mir_alloc((size_t)nlhrReply->dataLength + 2);
- memcpy(*szData, nlhrReply->pData, (size_t)nlhrReply->dataLength);
- (*szData)[nlhrReply->dataLength] = 0;
+ *szData = nlhrReply->body.Detach();
}
else if (nlhrReply->resultCode == 401) {
Netlib_LogfW(hNetlibUser, L"Code 401: feed %s needs auth data.", tszUrl);
@@ -99,8 +86,6 @@ void GetNewsData(wchar_t *tszUrl, char **szData, MCONTACT hContact, CFeedEditor
else Netlib_LogfW(hNetlibUser, L"Code %d: Failed getting feed data %s.", nlhrReply->resultCode, tszUrl);
}
else Netlib_LogfW(hNetlibUser, L"Failed getting feed data %s, no response.", tszUrl);
-
- mir_free(szUrl);
}
time_t DateToUnixTime(const char *stamp, bool FeedType)
@@ -220,81 +205,42 @@ time_t DateToUnixTime(const char *stamp, bool FeedType)
bool DownloadFile(LPCTSTR tszURL, LPCTSTR tszLocal)
{
- NETLIBHTTPREQUEST nlhr = { 0 };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11;
- char *szUrl = mir_u2a(tszURL);
- nlhr.szUrl = szUrl;
- NETLIBHTTPHEADER headers[4];
- nlhr.headersCount = 4;
- nlhr.headers = headers;
- nlhr.headers[0].szName = "User-Agent";
- nlhr.headers[0].szValue = NETLIB_USER_AGENT;
- nlhr.headers[1].szName = "Connection";
- nlhr.headers[1].szValue = "close";
- nlhr.headers[2].szName = "Cache-Control";
- nlhr.headers[2].szValue = "no-cache";
- nlhr.headers[3].szName = "Pragma";
- nlhr.headers[3].szValue = "no-cache";
-
- bool ret = false;
+ nlhr.m_szUrl = _T2A(tszURL);
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Connection", "close");
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
+
NLHR_PTR pReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
if (pReply) {
- if ((200 == pReply->resultCode) && (pReply->dataLength > 0)) {
- char *date = nullptr, *size = nullptr;
- for (int i = 0; i < pReply->headersCount; i++) {
- if (!mir_strcmpi(pReply->headers[i].szName, "Last-Modified")) {
- date = pReply->headers[i].szValue;
- continue;
- }
- else if (!mir_strcmpi(pReply->headers[i].szName, "Content-Length")) {
- size = pReply->headers[i].szValue;
- continue;
- }
- }
+ if (200 == pReply->resultCode && !pReply->body.IsEmpty()) {
+ const char *date = pReply->FindHeader("Last-Modified");
+ const char *size = pReply->FindHeader("Content-Length");
if (date != nullptr && size != nullptr) {
- wchar_t *tsize = mir_a2u(size);
struct _stat buf;
-
int fh = _wopen(tszLocal, _O_RDONLY);
if (fh != -1) {
_fstat(fh, &buf);
+ _close(fh);
+
time_t modtime = DateToUnixTime(date, 0);
time_t filemodtime = mktime(localtime(&buf.st_atime));
- if (modtime > filemodtime && buf.st_size != _wtoi(tsize)) {
- DWORD dwBytes;
- HANDLE hFile = CreateFile(tszLocal, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- WriteFile(hFile, pReply->pData, (uint32_t)pReply->dataLength, &dwBytes, nullptr);
- ret = true;
- if (hFile)
- CloseHandle(hFile);
- }
- _close(fh);
+ if (modtime <= filemodtime || buf.st_size == atoi(size))
+ return false;
}
- else {
- DWORD dwBytes;
- HANDLE hFile = CreateFile(tszLocal, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- WriteFile(hFile, pReply->pData, (uint32_t)pReply->dataLength, &dwBytes, nullptr);
- ret = true;
- if (hFile)
- CloseHandle(hFile);
- }
- mir_free(tsize);
- }
- else {
- DWORD dwBytes;
- HANDLE hFile = CreateFile(tszLocal, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- WriteFile(hFile, pReply->pData, (uint32_t)pReply->dataLength, &dwBytes, nullptr);
- ret = true;
- if (hFile)
- CloseHandle(hFile);
}
+
+ DWORD dwBytes;
+ HANDLE hFile = CreateFile(tszLocal, GENERIC_READ | GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+ WriteFile(hFile, pReply->body, pReply->body.GetLength(), &dwBytes, nullptr);
+ if (hFile)
+ CloseHandle(hFile);
}
}
-
- mir_free(szUrl);
-
- return ret;
+ return true;
}
typedef HRESULT(MarkupCallback)(IHTMLDocument3 *, BSTR &message);
diff --git a/protocols/Non-IM Contact/src/http.cpp b/protocols/Non-IM Contact/src/http.cpp
index 70804521b4..5aba5bbd8d 100644
--- a/protocols/Non-IM Contact/src/http.cpp
+++ b/protocols/Non-IM Contact/src/http.cpp
@@ -35,16 +35,13 @@ HNETLIBUSER hNetlibUser;
int InternetDownloadFile(char *szUrl)
{
// initialize the netlib request
- NETLIBHTTPREQUEST nlhr = {};
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT;
- nlhr.szUrl = szUrl;
+ nlhr.m_szUrl = szUrl;
// change the header so the plugin is pretended to be IE 6 + WinXP
- nlhr.headersCount++;
- nlhr.headers = (NETLIBHTTPHEADER*)malloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount);
- nlhr.headers[nlhr.headersCount - 1].szName = "User-Agent";
- nlhr.headers[nlhr.headersCount - 1].szValue = NETLIB_USER_AGENT;
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
// download the page
NLHR_PTR nlhrReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
@@ -57,14 +54,14 @@ int InternetDownloadFile(char *szUrl)
// if the recieved code is 200 OK
else if (nlhrReply->resultCode == 200) {
// allocate memory and save the retrieved data
- szData = (char *)malloc(mir_strlen(nlhrReply->pData) + 2);
- mir_strncpy(szData, nlhrReply->pData, mir_strlen(nlhrReply->pData));
+ szData = (char *)malloc(nlhrReply->body.GetLength() + 2);
+ mir_strncpy(szData, nlhrReply->body, nlhrReply->body.GetLength());
}
// if the recieved code is 302 Moved, Found, etc
else if (nlhrReply->resultCode == 302) { // page moved
// get the url for the new location and save it to szInfo
// look for the reply header "Location"
- if (auto *pszHdr = Netlib_GetHeader(nlhrReply, "Location")) {
+ if (auto *pszHdr = nlhrReply->FindHeader("Location")) {
szData = (char *)malloc(512);
// add "Moved/Location:" in front of the new URL for identification
mir_snprintf(szData, 512, "Moved/Location: %s\n", pszHdr);
diff --git a/protocols/SkypeWeb/src/request_queue.cpp b/protocols/SkypeWeb/src/request_queue.cpp
index d6240e7cee..9dd5ecd71e 100644
--- a/protocols/SkypeWeb/src/request_queue.cpp
+++ b/protocols/SkypeWeb/src/request_queue.cpp
@@ -73,7 +73,7 @@ void CSkypeProto::PushRequest(AsyncHttpRequest *request)
/////////////////////////////////////////////////////////////////////////////////////////
-NETLIBHTTPREQUEST* CSkypeProto::DoSend(AsyncHttpRequest *pReq)
+MHttpResponse* CSkypeProto::DoSend(AsyncHttpRequest *pReq)
{
if (pReq->m_host != HOST_OTHER)
pReq->m_szUrl.Insert(0, ((pReq->flags & NLHRF_SSL) ? "https://" : "http://"));
@@ -88,17 +88,12 @@ NETLIBHTTPREQUEST* CSkypeProto::DoSend(AsyncHttpRequest *pReq)
case REQUEST_PUT:
case REQUEST_POST:
- if (Netlib_GetHeader(pReq, "Content-Type") == nullptr) {
+ if (!pReq->FindHeader("Content-Type")) {
if (pReq->m_szParam[0] == '[' || pReq->m_szParam[0] == '{')
pReq->AddHeader("Content-Type", "application/json; charset=UTF-8");
else
pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
}
- __fallthrough;
-
- default:
- pReq->pData = pReq->m_szParam.Detach();
- pReq->dataLength = (int)mir_strlen(pReq->pData);
}
}
@@ -126,8 +121,8 @@ NETLIBHTTPREQUEST* CSkypeProto::DoSend(AsyncHttpRequest *pReq)
break;
}
- pReq->szUrl = pReq->m_szUrl.GetBuffer();
- debugLogA("Send request to %s", pReq->szUrl);
+ pReq->m_szUrl = pReq->m_szUrl.GetBuffer();
+ debugLogA("Send request to %s", pReq->m_szUrl.c_str());
return Netlib_HttpTransaction(m_hNetlibUser, pReq);
}
diff --git a/protocols/SkypeWeb/src/requests/avatars.h b/protocols/SkypeWeb/src/requests/avatars.h
index cdf5ac7b6e..aeffbf8ab0 100644
--- a/protocols/SkypeWeb/src/requests/avatars.h
+++ b/protocols/SkypeWeb/src/requests/avatars.h
@@ -30,21 +30,15 @@ struct GetAvatarRequest : public AsyncHttpRequest
struct SetAvatarRequest : public AsyncHttpRequest
{
- SetAvatarRequest(const uint8_t *data, size_t dataSize, const char *szMime, CSkypeProto *ppro) :
+ SetAvatarRequest(const uint8_t *data, int dataSize, const char *szMime, CSkypeProto *ppro) :
AsyncHttpRequest(REQUEST_PUT, HOST_API, 0, &CSkypeProto::OnSentAvatar)
{
m_szUrl.AppendFormat("/users/%s/profile/avatar", ppro->m_szSkypename.MakeLower().c_str());
AddHeader("Content-Type", szMime);
- pData = (char *)mir_alloc(dataSize);
- memcpy(pData, data, dataSize);
- dataLength = (int)dataSize;
- }
-
- ~SetAvatarRequest()
- {
- mir_free(pData);
+ m_szParam.Truncate(dataSize);
+ memcpy(m_szParam.GetBuffer(), data, dataSize);
}
};
diff --git a/protocols/SkypeWeb/src/requests/files.h b/protocols/SkypeWeb/src/requests/files.h
index 72c47b4788..d47b3637f3 100644
--- a/protocols/SkypeWeb/src/requests/files.h
+++ b/protocols/SkypeWeb/src/requests/files.h
@@ -28,7 +28,7 @@ struct ASMObjectCreateRequest : public AsyncHttpRequest
struct ASMObjectUploadRequest : public AsyncHttpRequest
{
- ASMObjectUploadRequest(CSkypeProto *ppro, const char *szObject, const uint8_t *data, const size_t size, CFileUploadParam *fup) :
+ ASMObjectUploadRequest(CSkypeProto *ppro, const char *szObject, const uint8_t *data, int size, CFileUploadParam *fup) :
AsyncHttpRequest(REQUEST_PUT, HOST_OTHER, 0, &CSkypeProto::OnASMObjectUploaded)
{
m_szUrl.AppendFormat("https://api.asm.skype.com/v1/objects/%s/content/original", szObject);
@@ -37,13 +37,7 @@ struct ASMObjectUploadRequest : public AsyncHttpRequest
AddHeader("Authorization", CMStringA(FORMAT, "skype_token %s", ppro->m_szApiToken.get()));
AddHeader("Content-Type", "application/octet-stream");
- pData = (char*)mir_alloc(size);
- memcpy(pData, data, size);
- dataLength = (int)size;
- }
-
- ~ASMObjectUploadRequest()
- {
- mir_free(pData);
+ m_szParam.Truncate(size);
+ memcpy(m_szParam.GetBuffer(), data, size);
}
};
diff --git a/protocols/SkypeWeb/src/skype_avatars.cpp b/protocols/SkypeWeb/src/skype_avatars.cpp
index 94d097c852..50c1207803 100644
--- a/protocols/SkypeWeb/src/skype_avatars.cpp
+++ b/protocols/SkypeWeb/src/skype_avatars.cpp
@@ -52,9 +52,9 @@ void CSkypeProto::ReloadAvatarInfo(MCONTACT hContact)
SvcGetAvatarInfo(0, (LPARAM)&ai);
}
-void CSkypeProto::OnReceiveAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnReceiveAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
- if (response == nullptr || response->pData == nullptr)
+ if (response == nullptr || response->body.IsEmpty())
return;
MCONTACT hContact = (DWORD_PTR)pRequest->pUserInfo;
@@ -62,7 +62,7 @@ void CSkypeProto::OnReceiveAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest
return;
PROTO_AVATAR_INFORMATION ai = { 0 };
- ai.format = ProtoGetBufferFormat(response->pData);
+ ai.format = ProtoGetBufferFormat(response->body);
setByte(hContact, "AvatarType", ai.format);
GetAvatarFileName(hContact, ai.filename, _countof(ai.filename));
@@ -72,13 +72,13 @@ void CSkypeProto::OnReceiveAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest
return;
}
- fwrite(response->pData, 1, response->dataLength, out);
+ fwrite(response->body, 1, response->body.GetLength(), out);
fclose(out);
setByte(hContact, "NeedNewAvatar", 0);
ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai, 0);
}
-void CSkypeProto::OnSentAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnSentAvatar(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply root(response);
if (root.error())
@@ -175,7 +175,7 @@ INT_PTR CSkypeProto::SvcSetMyAvatar(WPARAM, LPARAM lParam)
if (data != NULL && fread(data, sizeof(uint8_t), length, hFile) == length) {
const char *szMime = FreeImage_GetFIFMimeType(FreeImage_GetFIFFromFilenameU(path));
- PushRequest(new SetAvatarRequest(data, length, szMime, this));
+ PushRequest(new SetAvatarRequest(data, (int)length, szMime, this));
fclose(hFile);
return 0;
}
diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp
index 2d1fc6c3b8..243257353e 100644
--- a/protocols/SkypeWeb/src/skype_chatrooms.cpp
+++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp
@@ -51,7 +51,7 @@ SESSION_INFO* CSkypeProto::StartChatRoom(const wchar_t *tid, const wchar_t *tnam
return si;
}
-void CSkypeProto::OnLoadChats(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnLoadChats(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
@@ -380,7 +380,7 @@ void CSkypeProto::AddMessageToChat(SESSION_INFO *si, const wchar_t *from, const
Chat_Event(&gce);
}
-void CSkypeProto::OnGetChatInfo(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp
index c249c6e281..f5f83e6fa9 100644
--- a/protocols/SkypeWeb/src/skype_contacts.cpp
+++ b/protocols/SkypeWeb/src/skype_contacts.cpp
@@ -100,7 +100,7 @@ MCONTACT CSkypeProto::AddContact(const char *skypeId, const char *nick, bool isT
return hContact;
}
-void CSkypeProto::LoadContactsAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
@@ -142,7 +142,7 @@ void CSkypeProto::LoadContactsAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest
//[{"skypeId":"echo123", "authorized" : true, "blocked" : false, ...},...]
// other properties is exists but empty
-void CSkypeProto::LoadContactList(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::LoadContactList(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
@@ -255,7 +255,7 @@ INT_PTR CSkypeProto::BlockContact(WPARAM hContact, LPARAM)
return 0;
}
-void CSkypeProto::OnBlockContact(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnBlockContact(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
MCONTACT hContact = (DWORD_PTR)pRequest->pUserInfo;
if (response != nullptr)
@@ -268,7 +268,7 @@ INT_PTR CSkypeProto::UnblockContact(WPARAM hContact, LPARAM)
return 0;
}
-void CSkypeProto::OnUnblockContact(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnUnblockContact(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
if (response == nullptr)
return;
diff --git a/protocols/SkypeWeb/src/skype_files.cpp b/protocols/SkypeWeb/src/skype_files.cpp
index 358a337e90..9eaef8b665 100644
--- a/protocols/SkypeWeb/src/skype_files.cpp
+++ b/protocols/SkypeWeb/src/skype_files.cpp
@@ -28,10 +28,10 @@ void CSkypeProto::SendFileThread(void *p)
PushRequest(new ASMObjectCreateRequest(this, fup));
}
-void CSkypeProto::OnASMObjectCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnASMObjectCreated(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
auto *fup = (CFileUploadParam*)pRequest->pUserInfo;
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
LBL_Error:
FILETRANSFER_FAILED(fup);
return;
@@ -42,7 +42,7 @@ LBL_Error:
goto LBL_Error;
}
- JSONNode node = JSONNode::parse((char*)response->pData);
+ JSONNode node = JSONNode::parse(response->body);
std::string strObjectId = node["id"].as_string();
if (strObjectId.empty()) {
debugLogA("Invalid server response (empty object id)");
@@ -74,7 +74,7 @@ LBL_Error:
fclose(pFile);
}
-void CSkypeProto::OnASMObjectUploaded(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
auto *fup = (CFileUploadParam*)pRequest->pUserInfo;
if (response == nullptr) {
diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp
index b10897b0d3..7497d8f7a1 100644
--- a/protocols/SkypeWeb/src/skype_history_sync.cpp
+++ b/protocols/SkypeWeb/src/skype_history_sync.cpp
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* HISTORY SYNC */
-void CSkypeProto::OnGetServerHistory(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
JsonReply reply(response);
if (reply.error())
@@ -140,7 +140,7 @@ INT_PTR CSkypeProto::GetContactHistory(WPARAM hContact, LPARAM)
return 0;
}
-void CSkypeProto::OnSyncHistory(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnSyncHistory(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp
index 76977ab6cd..f9f2ecab57 100644
--- a/protocols/SkypeWeb/src/skype_login.cpp
+++ b/protocols/SkypeWeb/src/skype_login.cpp
@@ -66,18 +66,18 @@ void CSkypeProto::Login()
PushRequest(new OAuthRequest());
}
-void CSkypeProto::OnLoginOAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnLoginOAuth(MHttpResponse *response, AsyncHttpRequest*)
{
if (!IsStatusConnecting(m_iStatus))
return;
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
}
- JSONNode json = JSONNode::parse(response->pData);
+ JSONNode json = JSONNode::parse(response->body);
if (!json) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
@@ -148,7 +148,7 @@ void CSkypeProto::OnLoginSuccess()
PushRequest(new CreateEndpointRequest(this));
}
-void CSkypeProto::OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest*)
{
if (IsStatusConnecting(m_iStatus))
m_iStatus++;
@@ -167,7 +167,7 @@ void CSkypeProto::OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpReques
case 301:
case 302: // redirect to the closest data center
- if (auto *hdr = Netlib_GetHeader(response, "Location")) {
+ if (auto *hdr = response->FindHeader("Location")) {
CMStringA szUrl(hdr+8);
int iEnd = szUrl.Find('/');
g_plugin.szDefaultServer = (iEnd != -1) ? szUrl.Left(iEnd) : szUrl;
@@ -176,7 +176,7 @@ void CSkypeProto::OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpReques
return;
case 401: // unauthorized
- if (auto *szStatus = Netlib_GetHeader(response, "StatusText"))
+ if (auto *szStatus = response->FindHeader("StatusText"))
if (strstr(szStatus, "SkypeTokenExpired"))
delSetting("TokenSecret");
delSetting("TokenExpiresIn");
@@ -191,7 +191,7 @@ void CSkypeProto::OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpReques
}
// Succeeded, decode the answer
- if (auto *hdr = Netlib_GetHeader(response, "Set-RegistrationToken")) {
+ if (auto *hdr = response->FindHeader("Set-RegistrationToken")) {
CMStringA szValue = hdr;
int iStart = 0;
while (true) {
@@ -215,13 +215,13 @@ void CSkypeProto::OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpReques
PushRequest(new CreateSubscriptionsRequest());
}
-void CSkypeProto::OnEndpointDeleted(NETLIBHTTPREQUEST *, AsyncHttpRequest *)
+void CSkypeProto::OnEndpointDeleted(MHttpResponse *, AsyncHttpRequest *)
{
m_szId = nullptr;
m_szToken = nullptr;
}
-void CSkypeProto::OnSubscriptionsCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnSubscriptionsCreated(MHttpResponse *response, AsyncHttpRequest*)
{
if (response == nullptr) {
debugLogA(__FUNCTION__ ": failed to create subscription");
@@ -249,9 +249,9 @@ void CSkypeProto::SendPresence()
PushRequest(new SendCapabilitiesRequest(epname, this));
}
-void CSkypeProto::OnCapabilitiesSended(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest*)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
@@ -277,23 +277,23 @@ void CSkypeProto::OnCapabilitiesSended(NETLIBHTTPREQUEST *response, AsyncHttpReq
if (bAutoHistorySync)
PushRequest(new SyncHistoryFirstRequest(100));
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root)
setString("SelfEndpointName", UrlToSkypeId(root["selfLink"].as_string().c_str()));
PushRequest(new GetProfileRequest(this, 0));
}
-void CSkypeProto::OnStatusChanged(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnStatusChanged(MHttpResponse *response, AsyncHttpRequest*)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
debugLogA(__FUNCTION__ ": failed to change status");
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
}
- JSONNode json = JSONNode::parse(response->pData);
+ JSONNode json = JSONNode::parse(response->body);
if (!json) {
debugLogA(__FUNCTION__ ": failed to change status");
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp
index 16d9b2cb03..6504224c21 100644
--- a/protocols/SkypeWeb/src/skype_messages.cpp
+++ b/protocols/SkypeWeb/src/skype_messages.cpp
@@ -45,7 +45,7 @@ int CSkypeProto::SendMsg(MCONTACT hContact, MEVENT, const char *szMessage)
return param->hMessage;
}
-void CSkypeProto::OnMessageSent(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
auto *param = (SendMessageParam*)pRequest->pUserInfo;
MCONTACT hContact = param->hContact;
@@ -56,8 +56,8 @@ void CSkypeProto::OnMessageSent(NETLIBHTTPREQUEST *response, AsyncHttpRequest *p
if (response->resultCode != 201) {
std::string strError = Translate("Unknown error!");
- if (response->pData != nullptr) {
- JSONNode jRoot = JSONNode::parse(response->pData);
+ if (!response->body.IsEmpty()) {
+ JSONNode jRoot = JSONNode::parse(response->body);
const JSONNode &jErr = jRoot["errorCode"];
if (jErr)
strError = jErr.as_string();
diff --git a/protocols/SkypeWeb/src/skype_oauth.cpp b/protocols/SkypeWeb/src/skype_oauth.cpp
index 0a1f8908d3..d767496efa 100644
--- a/protocols/SkypeWeb/src/skype_oauth.cpp
+++ b/protocols/SkypeWeb/src/skype_oauth.cpp
@@ -28,9 +28,9 @@ static std::string sub(const std::string &str, const char *start, const char *en
return (i2 == -1) ? "" : str.substr(i1, i2 - i1);
}
-void CSkypeProto::OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnOAuthStart(MHttpResponse *response, AsyncHttpRequest*)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
@@ -38,7 +38,7 @@ void CSkypeProto::OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
std::regex regex;
std::smatch match;
- std::string content = response->pData;
+ std::string content = response->body.c_str();
regex = "<input.+?type=\"hidden\".+?name=\"PPFT\".+?id=\"i0327\".+?value=\"(.+?)\".*?/>";
@@ -52,11 +52,11 @@ void CSkypeProto::OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
std::map<std::string, std::string> scookies;
regex = "^(.+?)=(.*?);";
- for (int i = 0; i < response->headersCount; i++) {
- if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ for (auto &it : *response) {
+ if (mir_strcmpi(it->szName, "Set-Cookie"))
continue;
- content = response->headers[i].szValue;
+ content = it->szValue;
if (std::regex_search(content, match, regex))
scookies[match[1]] = match[2];
}
@@ -83,18 +83,18 @@ bool CSkypeProto::CheckOauth(const char *szResponse)
return true;
}
-void CSkypeProto::OnOAuthConfirm(NETLIBHTTPREQUEST *response, AsyncHttpRequest *)
+void CSkypeProto::OnOAuthConfirm(MHttpResponse *response, AsyncHttpRequest *)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
}
- if (CheckOauth(response->pData))
+ if (CheckOauth(response->body))
return;
- std::string content = response->pData;
+ std::string content = response->body.c_str();
std::string PPFT = sub(content, "sFT:'", "'");
std::string opid = sub(content, "opid=", "&");
if (PPFT.empty() || opid.empty()) {
@@ -107,11 +107,11 @@ void CSkypeProto::OnOAuthConfirm(NETLIBHTTPREQUEST *response, AsyncHttpRequest *
std::smatch match;
CMStringA mscookies;
- for (int i = 0; i < response->headersCount; i++) {
- if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ for (auto &it : *response) {
+ if (mir_strcmpi(it->szName, "Set-Cookie"))
continue;
- content = response->headers[i].szValue;
+ content = it->szValue;
if (std::regex_search(content, match, regex))
mscookies.Append(match[1].str().c_str());
}
@@ -119,23 +119,23 @@ void CSkypeProto::OnOAuthConfirm(NETLIBHTTPREQUEST *response, AsyncHttpRequest *
PushRequest(new OAuthRequest(mscookies.c_str(), PPFT.c_str(), opid.c_str()));
}
-void CSkypeProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnOAuthAuthorize(MHttpResponse *response, AsyncHttpRequest*)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
}
- if (!CheckOauth(response->pData)) {
+ if (!CheckOauth(response->body)) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
}
}
-void CSkypeProto::OnOAuthEnd(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnOAuthEnd(MHttpResponse *response, AsyncHttpRequest*)
{
- if (response == nullptr || response->pData == nullptr) {
+ if (response == nullptr || response->body.IsEmpty()) {
ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
SetStatus(ID_STATUS_OFFLINE);
return;
@@ -143,7 +143,7 @@ void CSkypeProto::OnOAuthEnd(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
std::regex regex;
std::smatch match;
- std::string content = response->pData;
+ std::string content = response->body;
regex = "<input.+?type=\"hidden\".+?name=\"skypetoken\".+?value=\"(.+?)\".*?/>";
if (!std::regex_search(content, match, regex)) {
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp
index 0000de3b20..b850cffb23 100644
--- a/protocols/SkypeWeb/src/skype_polling.cpp
+++ b/protocols/SkypeWeb/src/skype_polling.cpp
@@ -39,14 +39,14 @@ void CSkypeProto::PollingThread(void *)
if (response->resultCode == 200) {
nErrors = 0;
- if (response->pData)
- ParsePollData(response->pData);
+ if (!response->body.IsEmpty())
+ ParsePollData(response->body);
}
else {
nErrors++;
- if (response->pData) {
- JSONNode root = JSONNode::parse(response->pData);
+ if (!response->body.IsEmpty()) {
+ JSONNode root = JSONNode::parse(response->body);
const JSONNode &error = root["errorCode"];
if (error && error.as_int() == 729)
break;
diff --git a/protocols/SkypeWeb/src/skype_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp
index f8fbaa2fbe..16fda7b0c8 100644
--- a/protocols/SkypeWeb/src/skype_profile.cpp
+++ b/protocols/SkypeWeb/src/skype_profile.cpp
@@ -397,7 +397,7 @@ void CSkypeProto::UpdateProfileAvatar(const JSONNode &root, MCONTACT hContact)
}
//{"firstname":"Echo \/ Sound Test Service", "lastname" : null, "birthday" : null, "gender" : null, "country" : null, "city" : null, "language" : null, "homepage" : null, "about" : null, "province" : null, "jobtitle" : null, "emails" : [], "phoneMobile" : null, "phoneHome" : null, "phoneOffice" : null, "mood" : null, "richMood" : null, "avatarUrl" : null, "username" : "echo123"}
-void CSkypeProto::LoadProfile(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::LoadProfile(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
MCONTACT hContact = (DWORD_PTR)pRequest->pUserInfo;
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index 59ad914aaa..536744f36f 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -125,7 +125,7 @@ int CSkypeProto::SetAwayMsg(int, const wchar_t *msg)
/////////////////////////////////////////////////////////////////////////////////////////
-void CSkypeProto::OnReceiveAwayMsg(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+void CSkypeProto::OnReceiveAwayMsg(MHttpResponse *response, AsyncHttpRequest *pRequest)
{
JsonReply reply(response);
if (reply.error())
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index 5686aad69c..113e22b228 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -120,48 +120,48 @@ public:
return getMStringA(hContact, SKYPE_SETTINGS_ID);
}
- void OnReceiveAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnSentAvatar(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnSearch(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnReceiveAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnSentAvatar(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnSearch(MHttpResponse *response, AsyncHttpRequest *pRequest);
// login
- void OnLoginOAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnSubscriptionsCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnCapabilitiesSended(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnReceiveStatus(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnStatusChanged(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnLoginOAuth(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnSubscriptionsCreated(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnCapabilitiesSended(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnReceiveStatus(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnStatusChanged(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnEndpointCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnEndpointDeleted(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnEndpointCreated(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnEndpointDeleted(MHttpResponse *response, AsyncHttpRequest *pRequest);
// oauth
- void OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnOAuthConfirm(NETLIBHTTPREQUEST* response, AsyncHttpRequest* pRequest);
- void OnOAuthAuthorize(NETLIBHTTPREQUEST* response, AsyncHttpRequest* pRequest);
- void OnOAuthEnd(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnOAuthStart(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnOAuthConfirm(MHttpResponse* response, AsyncHttpRequest* pRequest);
+ void OnOAuthAuthorize(MHttpResponse* response, AsyncHttpRequest* pRequest);
+ void OnOAuthEnd(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnASMObjectCreated(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnASMObjectUploaded(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnASMObjectCreated(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void LoadContactsAuth(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void LoadContactList(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void LoadContactsAuth(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void LoadContactList(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnBlockContact(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnUnblockContact(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnBlockContact(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnUnblockContact(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnMessageSent(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnGetServerHistory(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnSyncHistory(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnSyncHistory(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnLoadChats(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnGetChatInfo(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
- void OnReceiveAwayMsg(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void OnLoadChats(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnReceiveAwayMsg(MHttpResponse *response, AsyncHttpRequest *pRequest);
void CheckConvert(void);
bool CheckOauth(const char *szResponse);
- void LoadProfile(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest);
+ void LoadProfile(MHttpResponse *response, AsyncHttpRequest *pRequest);
static INT_PTR __cdecl GlobalParseSkypeUriService(WPARAM, LPARAM lParam);
@@ -206,7 +206,7 @@ private:
void StartQueue();
void StopQueue();
- NETLIBHTTPREQUEST* DoSend(AsyncHttpRequest *request);
+ MHttpResponse* DoSend(AsyncHttpRequest *request);
void Execute(AsyncHttpRequest *request);
void PushRequest(AsyncHttpRequest *request);
diff --git a/protocols/SkypeWeb/src/skype_search.cpp b/protocols/SkypeWeb/src/skype_search.cpp
index 51a4952021..8dc34dc62c 100644
--- a/protocols/SkypeWeb/src/skype_search.cpp
+++ b/protocols/SkypeWeb/src/skype_search.cpp
@@ -30,7 +30,7 @@ void CSkypeProto::SearchBasicThread(void *id)
PushRequest(new GetSearchRequest(T2Utf((wchar_t *)id)));
}
-void CSkypeProto::OnSearch(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnSearch(MHttpResponse *response, AsyncHttpRequest*)
{
debugLogA(__FUNCTION__);
diff --git a/protocols/SkypeWeb/src/skype_trouter.cpp b/protocols/SkypeWeb/src/skype_trouter.cpp
index 65e38d4d41..567e449da1 100644
--- a/protocols/SkypeWeb/src/skype_trouter.cpp
+++ b/protocols/SkypeWeb/src/skype_trouter.cpp
@@ -26,7 +26,7 @@ void CSkypeProto::ProcessTimer()
SendPresence();
}
-void CSkypeProto::OnReceiveStatus(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+void CSkypeProto::OnReceiveStatus(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index acd02c6892..e2a751568c 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -653,7 +653,7 @@ INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam)
/////////////////////////////////////////////////////////////////////////////////////////
-JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
+JsonReply::JsonReply(MHttpResponse *pReply)
{
if (pReply == nullptr) {
m_errorCode = 500;
@@ -664,7 +664,7 @@ JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
if (m_errorCode != 200)
return;
- m_root = json_parse(pReply->pData);
+ m_root = json_parse(pReply->body);
if (m_root == nullptr) {
m_errorCode = 500;
return;
diff --git a/protocols/SkypeWeb/src/skype_utils.h b/protocols/SkypeWeb/src/skype_utils.h
index e8a1f05836..4162a8ec35 100644
--- a/protocols/SkypeWeb/src/skype_utils.h
+++ b/protocols/SkypeWeb/src/skype_utils.h
@@ -59,7 +59,7 @@ class JsonReply
int m_errorCode = 0;
public:
- JsonReply(NETLIBHTTPREQUEST *response);
+ JsonReply(MHttpResponse *response);
~JsonReply();
__forceinline JSONNode &data() const { return *m_root; }
diff --git a/protocols/Steam/src/http_request.h b/protocols/Steam/src/http_request.h
index 4c7b83509d..843ed94cda 100644
--- a/protocols/Steam/src/http_request.h
+++ b/protocols/Steam/src/http_request.h
@@ -5,10 +5,10 @@
class HttpResponse
{
- NETLIBHTTPREQUEST *m_response;
+ MHttpResponse *m_response;
public:
- HttpResponse(NETLIBHTTPREQUEST *response) :
+ HttpResponse(MHttpResponse *response) :
m_response(response)
{
}
@@ -20,12 +20,12 @@ public:
bool operator!() const
{
- return !m_response || !m_response->pData;
+ return !m_response || m_response->body.IsEmpty();
}
operator bool() const
{
- return m_response && m_response->pData;
+ return m_response && !m_response->body.IsEmpty();
}
bool IsSuccess() const
@@ -37,16 +37,14 @@ public:
char* data() const
{
- return (m_response) ? m_response->pData : nullptr;
+ return (m_response) ? m_response->body.GetBuffer() : nullptr;
}
unsigned length() const
{
- return (m_response) ? m_response->dataLength : 0;
+ return (m_response) ? m_response->body.GetLength() : 0;
}
- LIST<NETLIBHTTPHEADER> Headers() const;
-
int GetStatusCode() const
{
if (m_response)
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 234ae44e88..ed7978e890 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -45,7 +45,7 @@ struct HttpRequest : public MTHttpRequest<CSteamProto>
{
HttpRequest(int iRequestType, const char *pszUrl);
- NETLIBHTTPREQUEST* Get();
+ MHttpRequest* Get();
};
struct ProtoRequest
diff --git a/protocols/Steam/src/steam_request.cpp b/protocols/Steam/src/steam_request.cpp
index b91283198a..918e01ca16 100644
--- a/protocols/Steam/src/steam_request.cpp
+++ b/protocols/Steam/src/steam_request.cpp
@@ -2,7 +2,7 @@
bool CSteamProto::SendRequest(HttpRequest *request)
{
- NETLIBHTTPREQUEST *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
+ auto *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
HttpResponse response(pResp);
delete request;
return response.IsSuccess();
@@ -10,7 +10,7 @@ bool CSteamProto::SendRequest(HttpRequest *request)
bool CSteamProto::SendRequest(HttpRequest *request, HttpCallback callback, void *param)
{
- NETLIBHTTPREQUEST *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
+ auto *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
HttpResponse response(pResp);
if (callback)
(this->*callback)(response, param);
@@ -20,7 +20,7 @@ bool CSteamProto::SendRequest(HttpRequest *request, HttpCallback callback, void
bool CSteamProto::SendRequest(HttpRequest *request, JsonCallback callback, void *param)
{
- NETLIBHTTPREQUEST *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
+ auto *pResp = Netlib_HttpTransaction(m_hNetlibUser, request->Get());
HttpResponse response(pResp);
if (callback) {
JSONNode root = JSONNode::parse(response.data());
@@ -42,26 +42,11 @@ HttpRequest::HttpRequest(int iRequestType, const char *szUrl)
m_szUrl = szUrl;
}
-NETLIBHTTPREQUEST* HttpRequest::Get()
+MHttpRequest* HttpRequest::Get()
{
if (m_szUrl[0]== '/') {
m_szUrl.Insert(0, STEAM_API_URL);
AddHeader("User-Agent", STEAM_USER_AGENT);
}
- szUrl = m_szUrl.GetBuffer();
return this;
}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// HttpResponse
-
-LIST<NETLIBHTTPHEADER> HttpResponse::Headers() const
-{
- LIST<NETLIBHTTPHEADER> ret(10);
-
- if (m_response)
- for (int i = 0; i < m_response->headersCount; i++)
- ret.insert(&m_response->headers[i]);
-
- return ret;
-}
diff --git a/protocols/Tox/src/http_request.h b/protocols/Tox/src/http_request.h
index bba9f0591c..1e140b2ef0 100644
--- a/protocols/Tox/src/http_request.h
+++ b/protocols/Tox/src/http_request.h
@@ -17,22 +17,12 @@ public:
}
};
-class HttpRequest : protected NETLIBHTTPREQUEST
+class HttpRequest : public MHttpRequest
{
-private:
- CMStringA m_szUrl;
-
void Init(int type)
{
requestType = type;
flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
- szUrl = nullptr;
- headers = nullptr;
- headersCount = 0;
- pData = nullptr;
- dataLength = 0;
- resultCode = 0;
- szResultDescr = nullptr;
nlc = nullptr;
timeout = 0;
}
@@ -60,22 +50,6 @@ public:
~HttpRequest()
{
- for (int i = 0; i < headersCount; i++)
- {
- mir_free(headers[i].szName);
- mir_free(headers[i].szValue);
- }
- mir_free(headers);
- if (pData)
- mir_free(pData);
- }
-
- void 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 AddUrlParameter(const char *urlFormat, ...)
@@ -87,20 +61,9 @@ public:
va_end(urlArgs);
}
- void SetData(const char *data, size_t size)
- {
- if (pData != nullptr)
- mir_free(pData);
-
- dataLength = (int)size;
- pData = (char*)mir_alloc(size);
- memcpy(pData, data, size);
- }
-
- NETLIBHTTPREQUEST* Send(HNETLIBUSER hNetlibConnection)
+ MHttpResponse* Send(HNETLIBUSER hNetlibConnection)
{
m_szUrl.Replace('\\', '/');
- szUrl = m_szUrl.GetBuffer();
return Netlib_HttpTransaction(hNetlibConnection, this);
}
};
diff --git a/protocols/Tox/src/tox_bootstrap.cpp b/protocols/Tox/src/tox_bootstrap.cpp
index 663e46a8ab..6e8a5d774e 100644
--- a/protocols/Tox/src/tox_bootstrap.cpp
+++ b/protocols/Tox/src/tox_bootstrap.cpp
@@ -121,12 +121,12 @@ void CToxProto::UpdateNodes()
debugLogA(__FUNCTION__": updating nodes");
HttpRequest request(REQUEST_GET, "https://nodes.tox.chat/json");
NLHR_PTR response(request.Send(m_hNetlibUser));
- if (!response || response->resultCode != HTTP_CODE_OK || !response->pData) {
+ if (!response || response->resultCode != HTTP_CODE_OK || response->body.IsEmpty()) {
debugLogA(__FUNCTION__": failed to dowload tox.json");
return;
}
- JSONNode root = JSONNode::parse(response->pData);
+ JSONNode root = JSONNode::parse(response->body);
if (root.empty()) {
debugLogA(__FUNCTION__": failed to dowload tox.json");
return;
@@ -142,7 +142,7 @@ void CToxProto::UpdateNodes()
return;
}
- if (fwrite(response->pData, sizeof(char), response->dataLength, hFile) != (size_t)response->dataLength)
+ if (fwrite(response->body, sizeof(char), response->body.GetLength(), hFile) != (size_t)response->body.GetLength())
debugLogA(__FUNCTION__": failed to write tox.json");
fclose(hFile);
diff --git a/protocols/Twitter/src/http.cpp b/protocols/Twitter/src/http.cpp
index 888afdfa84..71aa265954 100644
--- a/protocols/Twitter/src/http.cpp
+++ b/protocols/Twitter/src/http.cpp
@@ -39,9 +39,6 @@ void CTwitterProto::Execute(AsyncHttpRequest *pReq)
}
else pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
pReq->AddHeader("Cache-Control", "no-cache");
-
- pReq->dataLength = (int)pReq->m_szParam.GetLength();
- pReq->pData = pReq->m_szParam.Detach();
}
else {
if (pReq->requestType == REQUEST_PATCH)
@@ -60,7 +57,6 @@ void CTwitterProto::Execute(AsyncHttpRequest *pReq)
// auth = OAuthWebRequestSubmit(pReq->m_szUrl, "POST", (bIsJson) ? "" : pReq->pData);
// pReq->AddHeader("Authorization", auth);
- pReq->szUrl = pReq->m_szUrl.GetBuffer();
pReq->flags = NLHRF_HTTP11 | NLHRF_PERSISTENT | NLHRF_REDIRECT;
pReq->nlc = m_hConnHttp;
diff --git a/protocols/Twitter/src/oauth.cpp b/protocols/Twitter/src/oauth.cpp
index 9ef2c9bf7c..6e919d3b47 100644
--- a/protocols/Twitter/src/oauth.cpp
+++ b/protocols/Twitter/src/oauth.cpp
@@ -163,7 +163,7 @@ CMStringA CTwitterProto::OAuthCreateSignature(const CMStringA &signatureBase, co
/////////////////////////////////////////////////////////////////////////////////////////
-void CTwitterProto::Oauth2RequestToken(NETLIBHTTPREQUEST *pResp, AsyncHttpRequest *)
+void CTwitterProto::Oauth2RequestToken(MHttpResponse *pResp, AsyncHttpRequest *)
{
if (pResp->resultCode != 200) {
OnLoggedFail();
@@ -196,7 +196,7 @@ void CTwitterProto::RequestOauthToken(const char *szPin)
/////////////////////////////////////////////////////////////////////////////////////////
-void CTwitterProto::Oauth2RequestAuth(NETLIBHTTPREQUEST *pResp, AsyncHttpRequest *)
+void CTwitterProto::Oauth2RequestAuth(MHttpResponse *pResp, AsyncHttpRequest *)
{
if (pResp->resultCode != 200) {
OnLoggedFail();
diff --git a/protocols/Twitter/src/proto.h b/protocols/Twitter/src/proto.h
index e3e5650b4d..fd09b49147 100644
--- a/protocols/Twitter/src/proto.h
+++ b/protocols/Twitter/src/proto.h
@@ -119,8 +119,8 @@ class CTwitterProto : public PROTO<CTwitterProto>
void RequestOauthToken(const char *szPin = nullptr);
void ResetOauthKeys();
- void Oauth2RequestAuth(NETLIBHTTPREQUEST *, AsyncHttpRequest *);
- void Oauth2RequestToken(NETLIBHTTPREQUEST *, AsyncHttpRequest *);
+ void Oauth2RequestAuth(MHttpResponse *, AsyncHttpRequest *);
+ void Oauth2RequestToken(MHttpResponse *, AsyncHttpRequest *);
CMStringA OAuthWebRequestSubmit(const CMStringA &url, const char *httpMethod, const char *postData);
diff --git a/protocols/Twitter/src/utility.cpp b/protocols/Twitter/src/utility.cpp
index d9031b51ce..737278bf0a 100644
--- a/protocols/Twitter/src/utility.cpp
+++ b/protocols/Twitter/src/utility.cpp
@@ -71,10 +71,10 @@ void CTwitterProto::ShowPopup(const char *text, int Error)
bool save_url(HNETLIBUSER hNetlib, const CMStringA &url, const CMStringW &filename)
{
- NETLIBHTTPREQUEST req = { sizeof(req) };
+ MHttpRequest req;
req.requestType = REQUEST_GET;
req.flags = NLHRF_HTTP11 | NLHRF_REDIRECT;
- req.szUrl = const_cast<char*>(url.c_str());
+ req.m_szUrl = const_cast<char*>(url.c_str());
NLHR_PTR resp(Netlib_HttpTransaction(hNetlib, &req));
if (!resp)
@@ -89,7 +89,7 @@ bool save_url(HNETLIBUSER hNetlib, const CMStringA &url, const CMStringW &filena
// Write to file
if (FILE *f = _wfopen(filename, L"wb")) {
- fwrite(resp->pData, 1, resp->dataLength, f);
+ fwrite(resp->body, 1, resp->body.GetLength(), f);
fclose(f);
}
else return false;
diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp
index 4378651b6f..01e6046a43 100644
--- a/protocols/VKontakte/src/misc.cpp
+++ b/protocols/VKontakte/src/misc.cpp
@@ -315,14 +315,14 @@ bool CVkProto::IsGroupUser(MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
-JSONNode& CVkProto::CheckJsonResponse(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST *reply, JSONNode &root)
+JSONNode& CVkProto::CheckJsonResponse(AsyncHttpRequest *pReq, MHttpResponse *reply, JSONNode &root)
{
debugLogA("CVkProto::CheckJsonResponse");
- if (!reply || !reply->pData)
+ if (!reply || reply->body.IsEmpty())
return nullNode;
- root = JSONNode::parse(reply->pData);
+ root = JSONNode::parse(reply->body);
if (!CheckJsonResult(pReq, root))
return nullNode;
@@ -442,7 +442,7 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
return (iErrorCode == 0);
}
-void CVkProto::OnReceiveSmth(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveSmth(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
JSONNode jnRoot;
const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot);
@@ -575,14 +575,15 @@ CMStringW CVkProto::RunRenameNick(LPCWSTR pwszOldName)
/////////////////////////////////////////////////////////////////////////////////////////
-void CVkProto::GrabCookies(NETLIBHTTPREQUEST *nhr, CMStringA szDefDomain)
+void CVkProto::GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain)
{
debugLogA("CVkProto::GrabCookies");
- for (int i = 0; i < nhr->headersCount; i++) {
- if (_stricmp(nhr->headers[i].szName, "Set-cookie"))
+
+ for (auto &hdr : *nhr) {
+ if (_stricmp(hdr->szName, "Set-cookie"))
continue;
- CMStringA szValue = nhr->headers[i].szValue, szCookieName, szCookieVal, szDomain;
+ CMStringA szValue = hdr->szValue, szCookieName, szCookieVal, szDomain;
int iStart = 0;
while (true) {
bool bFirstToken = (iStart == 0);
@@ -1468,16 +1469,16 @@ CMStringW CVkProto::GetAttachmentDescr(const JSONNode &jnAttachments, BBCSupport
if (GetFileAttributesW(wszFileName) == INVALID_FILE_ATTRIBUTES) {
T2Utf szUrl(wszUrl);
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.flags = NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
req.requestType = REQUEST_GET;
- req.szUrl = szUrl;
+ req.m_szUrl = szUrl.get();
- NETLIBHTTPREQUEST* pReply = Netlib_HttpTransaction(m_hNetlibUser, &req);
- if (pReply != nullptr && pReply->resultCode == 200 && pReply->pData && pReply->dataLength) {
+ MHttpResponse *pReply = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ if (pReply != nullptr && pReply->resultCode == 200 && !pReply->body.IsEmpty()) {
bSuccess = true;
FILE* out = _wfopen(wszFileName, L"wb");
- fwrite(pReply->pData, 1, pReply->dataLength, out);
+ fwrite(pReply->body, 1, pReply->body.GetLength(), out);
fclose(out);
}
}
diff --git a/protocols/VKontakte/src/vk_avatars.cpp b/protocols/VKontakte/src/vk_avatars.cpp
index 29288a2a3a..53c33f8250 100644
--- a/protocols/VKontakte/src/vk_avatars.cpp
+++ b/protocols/VKontakte/src/vk_avatars.cpp
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-void CVkProto::OnReceiveAvatar(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveAvatar(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
if (reply->resultCode != 200 || !pReq->pUserInfo)
return;
@@ -25,7 +25,7 @@ void CVkProto::OnReceiveAvatar(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
PROTO_AVATAR_INFORMATION ai = { 0 };
CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo;
GetAvatarFileName(param->hContact, ai.filename, _countof(ai.filename));
- ai.format = ProtoGetBufferFormat(reply->pData);
+ ai.format = ProtoGetBufferFormat(reply->body);
FILE *out = _wfopen(ai.filename, L"wb");
if (out == nullptr) {
@@ -35,7 +35,7 @@ void CVkProto::OnReceiveAvatar(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
return;
}
- fwrite(reply->pData, 1, reply->dataLength, out);
+ fwrite(reply->body, 1, reply->body.GetLength(), out);
fclose(out);
setByte(param->hContact, "NeedNewAvatar", 0);
ProtoBroadcastAck(param->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
diff --git a/protocols/VKontakte/src/vk_captcha.cpp b/protocols/VKontakte/src/vk_captcha.cpp
index e82d1a3400..06e1d451e0 100644
--- a/protocols/VKontakte/src/vk_captcha.cpp
+++ b/protocols/VKontakte/src/vk_captcha.cpp
@@ -33,12 +33,12 @@ bool CVkProto::RunCaptchaForm(LPCSTR szUrl, CMStringA &result)
Utils_OpenUrl(szCaptchaAssistant);
}
else {
- NETLIBHTTPREQUEST req = { sizeof(req) };
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = (LPSTR)szUrl;
+ req.m_szUrl = (LPSTR)szUrl;
req.flags = VK_NODUMPHEADERS;
- NETLIBHTTPREQUEST *reply = Netlib_HttpTransaction(m_hNetlibUser, &req);
+ auto *reply = Netlib_HttpTransaction(m_hNetlibUser, &req);
if (reply == nullptr)
return false;
@@ -47,7 +47,7 @@ bool CVkProto::RunCaptchaForm(LPCSTR szUrl, CMStringA &result)
return false;
}
- param.bmp = Image_LoadFromMem(reply->pData, reply->dataLength, FIF_UNKNOWN);
+ param.bmp = Image_LoadFromMem(reply->body, reply->body.GetLength(), FIF_UNKNOWN);
BITMAP bmp = { 0 };
GetObject(param.bmp, sizeof(bmp), &bmp);
diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp
index 1fa6d8b774..0264ffad89 100644
--- a/protocols/VKontakte/src/vk_chats.cpp
+++ b/protocols/VKontakte/src/vk_chats.cpp
@@ -195,7 +195,7 @@ void CVkProto::RetrieveChatInfo(CVkChatInfo *cc)
)->pUserInfo = cc;
}
-void CVkProto::OnReceiveChatInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveChatInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveChatInfo %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -644,7 +644,7 @@ int CVkProto::OnChatEvent(WPARAM, LPARAM lParam)
return 1;
}
-void CVkProto::OnSendChatMsg(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnSendChatMsg(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnSendChatMsg %d", reply->resultCode);
int iResult = ACKRESULT_FAILED;
@@ -784,7 +784,7 @@ void CVkProto::KickFromChat(VKUserID_t iChatId, VKUserID_t iUserId, const JSONNo
LeaveChat(iChatId);
}
-void CVkProto::OnChatLeave(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnChatLeave(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnChatLeave %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -795,7 +795,7 @@ void CVkProto::OnChatLeave(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
}
-void CVkProto::OnChatDestroy(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnChatDestroy(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnChatDestroy %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -1031,7 +1031,7 @@ void CVkProto::CreateNewChat(LPCSTR uids, LPCWSTR pwszTitle)
<< CHAR_PARAM("user_ids", uids));
}
-void CVkProto::OnCreateNewChat(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnCreateNewChat(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnCreateNewChat %d", reply->resultCode);
if (reply->resultCode != 200)
diff --git a/protocols/VKontakte/src/vk_feed.cpp b/protocols/VKontakte/src/vk_feed.cpp
index c5e6701ef1..53f5755057 100644
--- a/protocols/VKontakte/src/vk_feed.cpp
+++ b/protocols/VKontakte/src/vk_feed.cpp
@@ -642,7 +642,7 @@ static int sttCompareVKNotificationItems(const CVKNewsItem *p1, const CVKNewsIte
return compareType ? compareDate : (compareId ? (int)compareDate : 0);
}
-void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveUnreadNews(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveUnreadNews %d", reply->resultCode);
db_unset(0, m_szModuleName, "LastNewsReqTime");
@@ -747,7 +747,7 @@ void CVkProto::NotificationMarkAsViewed()
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/notifications.markAsViewed.json", true, &CVkProto::OnReceiveSmth));
}
-void CVkProto::OnReceiveUnreadNotifications(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveUnreadNotifications(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveUnreadNotifications %d", reply->resultCode);
db_unset(0, m_szModuleName, "LastNotificationsReqTime");
diff --git a/protocols/VKontakte/src/vk_files.cpp b/protocols/VKontakte/src/vk_files.cpp
index 5c83372d51..34bdfd5504 100644
--- a/protocols/VKontakte/src/vk_files.cpp
+++ b/protocols/VKontakte/src/vk_files.cpp
@@ -127,7 +127,7 @@ void CVkProto::SendFileFiled(CVkFileUploadParam *fup, int ErrorCode)
}
-void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReciveUploadServer(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
@@ -201,9 +201,9 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
// Body size
long dataLength = iFileLen + DataBegin.GetLength() + DataEnd.GetLength();
// Body {
- char *pData = (char *)mir_alloc(dataLength);
+ pUploadReq->m_szParam.Truncate(dataLength);
+ char *pData = pUploadReq->m_szParam.GetBuffer();
memcpy(pData, (void *)DataBegin.GetBuffer(), DataBegin.GetLength());
- pUploadReq->pData = pData;
pData += DataBegin.GetLength();
long lBytes = (long)fread(pData, 1, iFileLen, pFile);
@@ -211,7 +211,6 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
if (lBytes != iFileLen) {
SendFileFiled(fup, VKERR_ERR_READ_FILE);
- mir_free(pUploadReq->pData);
delete pUploadReq;
return;
}
@@ -220,12 +219,11 @@ void CVkProto::OnReciveUploadServer(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *
memcpy(pData, (void *)DataEnd.GetBuffer(), DataEnd.GetLength());
// } Body
- pUploadReq->dataLength = (int)dataLength;
pUploadReq->pUserInfo = pReq->pUserInfo;
Push(pUploadReq);
}
-void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReciveUpload(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
@@ -303,7 +301,7 @@ void CVkProto::OnReciveUpload(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
Push(pUploadReq);
}
-void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReciveUploadFile(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
CVkFileUploadParam *fup = (CVkFileUploadParam *)pReq->pUserInfo;
if (!IsOnline()) {
diff --git a/protocols/VKontakte/src/vk_history.cpp b/protocols/VKontakte/src/vk_history.cpp
index 4e967f319e..64ea57b002 100644
--- a/protocols/VKontakte/src/vk_history.cpp
+++ b/protocols/VKontakte/src/vk_history.cpp
@@ -166,7 +166,7 @@ void CVkProto::GetHistoryDlg(MCONTACT hContact, VKMessageID_t iLastMsg)
}
}
-void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveHistoryMessages(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveHistoryMessages %d", reply->resultCode);
if (reply->resultCode != 200 || !pReq->pUserInfo) {
diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp
index 3549a77a8b..3030df3b9f 100644
--- a/protocols/VKontakte/src/vk_messages.cpp
+++ b/protocols/VKontakte/src/vk_messages.cpp
@@ -186,7 +186,7 @@ int CVkProto::SendMsg(MCONTACT hContact, MEVENT hReplyEvent, const char *szMsg)
return uMsgId;
}
-void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnSendMessage(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
int iResult = ACKRESULT_FAILED;
if (pReq->pUserInfo == nullptr) {
@@ -299,7 +299,7 @@ void CVkProto::RetrieveUnreadMessages()
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/execute.RetrieveUnreadConversations", true, &CVkProto::OnReceiveDlgs, AsyncHttpRequest::rpHigh));
}
-void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveMessages(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveMessages %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -487,7 +487,7 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe
}
}
-void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveDlgs(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveDlgs %d", reply->resultCode);
if (reply->resultCode != 200)
diff --git a/protocols/VKontakte/src/vk_pollserver.cpp b/protocols/VKontakte/src/vk_pollserver.cpp
index 1597b439ca..3030816b1c 100644
--- a/protocols/VKontakte/src/vk_pollserver.cpp
+++ b/protocols/VKontakte/src/vk_pollserver.cpp
@@ -28,7 +28,7 @@ void CVkProto::RetrievePollingInfo()
);
}
-void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceivePollingInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceivePollingInfo %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -253,9 +253,9 @@ int CVkProto::PollServer()
CMStringA szReqUrl(FORMAT, "https://%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s&mode=%d&version=%d", m_szPollingServer, m_szPollingKey, m_szPollingTs, m_szAccessToken, 106, 2);
// see mode parametr description on https://vk.com/dev/using_longpoll (Russian version)
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = szReqUrl.GetBuffer();
+ req.m_szUrl = szReqUrl.GetBuffer();
req.flags = VK_NODUMPHEADERS | NLHRF_PERSISTENT | NLHRF_HTTP11 | NLHRF_SSL;
req.timeout = 30000;
req.nlc = m_hPollingConn;
@@ -290,7 +290,7 @@ int CVkProto::PollServer()
int retVal = 0;
if (reply->resultCode == 200) {
- JSONNode jnRoot = JSONNode::parse(reply->pData);
+ JSONNode jnRoot = JSONNode::parse(reply->body);
const JSONNode &jnFailed = jnRoot["failed"];
if (jnFailed && jnFailed.as_int() > 1) {
RetrievePollingInfo();
diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp
index 372e8690a8..285ee996ae 100644
--- a/protocols/VKontakte/src/vk_proto.cpp
+++ b/protocols/VKontakte/src/vk_proto.cpp
@@ -651,7 +651,7 @@ int CVkProto::AuthRequest(MCONTACT hContact, const wchar_t *message)
return 0;
}
-void CVkProto::OnReceiveAuthRequest(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveAuthRequest(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveAuthRequest %d", reply->resultCode);
CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h
index bc07b1dbc2..4d19cb7d29 100644
--- a/protocols/VKontakte/src/vk_proto.h
+++ b/protocols/VKontakte/src/vk_proto.h
@@ -82,8 +82,8 @@ struct CVkProto : public PROTO<CVkProto>
//==== Events ========================================================================
int __cdecl OnOptionsInit(WPARAM, LPARAM);
- void OnOAuthAuthorize(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveAvatar(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnOAuthAuthorize(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveAvatar(MHttpResponse*, AsyncHttpRequest*);
//==== Services ======================================================================
@@ -284,15 +284,15 @@ private:
//==== Search ========================================================================
void FreeProtoShearchStruct(PROTOSEARCHBYNAME *pParam);
- void OnSearch(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnSearchByMail(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnSearch(MHttpResponse*, AsyncHttpRequest*);
+ void OnSearchByMail(MHttpResponse*, AsyncHttpRequest*);
//==== Files Upload ==================================================================
void SendFileFiled(CVkFileUploadParam *fup, int ErrorCode);
- void OnReciveUploadServer(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReciveUpload(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReciveUploadFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReciveUploadServer(MHttpResponse*, AsyncHttpRequest*);
+ void OnReciveUpload(MHttpResponse*, AsyncHttpRequest*);
+ void OnReciveUploadFile(MHttpResponse*, AsyncHttpRequest*);
//==== Feed ==========================================================================
@@ -308,11 +308,11 @@ private:
CMStringW GetVkFeedback(const JSONNode &jnFeedback, VKObjType vkFeedbackType, OBJLIST<CVkUserInfo> &vkUsers, CVkUserInfo *vkUser);
CVKNewsItem* GetVkParent(const JSONNode &jnParent, VKObjType vkParentType, LPCWSTR pwszReplyText = nullptr, LPCWSTR pwszReplyLink = nullptr);
void RetrieveUnreadNews(time_t tLastNewsTime);
- void OnReceiveUnreadNews(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveUnreadNews(MHttpResponse*, AsyncHttpRequest*);
void RetrieveUnreadNotifications(time_t tLastNotificationsTime);
bool FilterNotification(CVKNewsItem *vkNotificationItem, bool& bIsCommented);
void NotificationMarkAsViewed();
- void OnReceiveUnreadNotifications(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveUnreadNotifications(MHttpResponse*, AsyncHttpRequest*);
void RetrieveUnreadEvents();
void NewsClearHistory();
INT_PTR __cdecl SvcLoadVKNews(WPARAM, LPARAM);
@@ -323,50 +323,50 @@ private:
void RetrieveUsersInfo(bool bFlag = false, bool bRepeat = false);
void RetrieveStatusMsg(const CMStringW &StatusMsg);
void RetrieveStatusMusic(const CMStringW &StatusMsg);
- void OnReceiveStatus(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveStatusMsg(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveStatus(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveStatusMsg(MHttpResponse*, AsyncHttpRequest*);
MCONTACT SetContactInfo(const JSONNode &jnItem, bool bFlag = false, VKContactType vkContactType = VKContactType::vkContactNormal);
void TrackVisitor();
void RetrieveMyInfo(void);
- void OnReceiveMyInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveMyInfo(MHttpResponse*, AsyncHttpRequest*);
void RetrieveUserInfo(VKUserID_t iUserId);
void RetrieveGroupInfo(VKUserID_t iGroupID);
void RetrieveGroupInfo(CMStringA & groupIDs);
- void OnReceiveUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveGroupInfo(NETLIBHTTPREQUEST * reply, AsyncHttpRequest * pReq);
+ void OnReceiveUserInfo(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveGroupInfo(MHttpResponse * reply, AsyncHttpRequest * pReq);
void RetrieveFriends(bool bCleanNonFriendContacts = false);
- void OnReceiveFriends(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveFriends(MHttpResponse*, AsyncHttpRequest*);
void MarkMessagesRead(const MCONTACT hContact);
void RetrieveMessagesByIds(const CMStringA &szMids);
void RetrieveUnreadMessages();
- void OnReceiveMessages(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveDlgs(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnSendMessage(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveMessages(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveDlgs(MHttpResponse*, AsyncHttpRequest*);
+ void OnSendMessage(MHttpResponse*, AsyncHttpRequest*);
void WallPost(MCONTACT hContact, wchar_t *pwszMsg, wchar_t *pwszUrl, bool bFriendsOnly);
void GetServerHistoryLastNDay(MCONTACT hContact, int iNDay);
void GetServerHistory(MCONTACT hContact, int iOffset, int iCount, time_t tTime, VKMessageID_t iLastMsgId, bool bOnce = false);
- void OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq);
+ void OnReceiveHistoryMessages(MHttpResponse *reply, AsyncHttpRequest *pReq);
void GetHistoryDlg(MCONTACT hContact, VKMessageID_t iLastMsg);
void RetrievePollingInfo();
- void OnReceivePollingInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceivePollingInfo(MHttpResponse*, AsyncHttpRequest*);
void __cdecl PollingThread(void*);
int PollServer();
void PollUpdates(const JSONNode&);
- void OnReceiveAuthRequest(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnReceiveDeleteFriend(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveAuthRequest(MHttpResponse*, AsyncHttpRequest*);
+ void OnReceiveDeleteFriend(MHttpResponse*, AsyncHttpRequest*);
//==== Misc ==========================================================================
void SetAllContactStatuses(int iStatus);
MCONTACT FindUser(VKUserID_t iUserId, bool bCreate = false);
MCONTACT FindChat(VKUserID_t iUserId);
- JSONNode& CheckJsonResponse(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST *reply, JSONNode &root);
+ JSONNode& CheckJsonResponse(AsyncHttpRequest *pReq, MHttpResponse *reply, JSONNode &root);
bool CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &Node);
- void OnReceiveSmth(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveSmth(MHttpResponse*, AsyncHttpRequest*);
bool AutoFillForm(char*, CMStringA&, CMStringA&);
CMStringW RunConfirmationCode(LPCWSTR pwszTitle);
CMStringW RunRenameNick(LPCWSTR pwszOldName);
- void GrabCookies(NETLIBHTTPREQUEST *nhr, CMStringA szDefDomain = "");
+ void GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain = "");
void ApplyCookies(AsyncHttpRequest*);
bool IsAuthContactLater(MCONTACT hContact);
bool AddAuthContactLater(MCONTACT hContact);
@@ -417,16 +417,16 @@ private:
void StopChatContactTyping(VKUserID_t iChatId, VKUserID_t iUserId);
- void OnCreateNewChat(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnCreateNewChat(MHttpResponse*, AsyncHttpRequest*);
CVkChatInfo* AppendConversationChat(VKUserID_t iChatId, const JSONNode& jnItem);
void SetChatTitle(CVkChatInfo *cc, LPCWSTR wszTopic);
void AppendChatConversationMessage(VKUserID_t iChatId, const JSONNode& jnMsg, const JSONNode& jnFUsers, bool bIsHistory);
void AppendChatMessage(CVkChatInfo* vkChatInfo, VKMessageID_t iMessageId, VKUserID_t iUserId, time_t tMsgTime, LPCWSTR pwszBody, bool bIsHistory, bool bIsAction = false);
void RetrieveChatInfo(CVkChatInfo*);
- void OnReceiveChatInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnSendChatMsg(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
- void OnChatLeave(NETLIBHTTPREQUEST*, AsyncHttpRequest *);
- void OnChatDestroy(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveChatInfo(MHttpResponse*, AsyncHttpRequest*);
+ void OnSendChatMsg(MHttpResponse*, AsyncHttpRequest*);
+ void OnChatLeave(MHttpResponse*, AsyncHttpRequest *);
+ void OnChatDestroy(MHttpResponse*, AsyncHttpRequest*);
int __cdecl OnChatEvent(WPARAM, LPARAM);
int __cdecl OnGcMenuHook(WPARAM, LPARAM);
void KickFromChat(VKUserID_t iChatId, VKUserID_t iUserId, const JSONNode &jnMsg, const JSONNode &jnFUsers);
diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp
index 94e85b826d..e42bd1db42 100644
--- a/protocols/VKontakte/src/vk_queue.cpp
+++ b/protocols/VKontakte/src/vk_queue.cpp
@@ -38,15 +38,11 @@ bool CVkProto::ExecuteRequest(AsyncHttpRequest *pReq)
do {
pReq->bNeedsRestart = false;
pReq->m_iErrorCode = 0;
- pReq->szUrl = pReq->m_szUrl.GetBuffer();
+ pReq->m_szUrl = pReq->m_szUrl.GetBuffer();
if (!pReq->m_szParam.IsEmpty()) {
if (pReq->requestType == REQUEST_GET) {
str.Format("%s?%s", pReq->m_szUrl.c_str(), pReq->m_szParam.c_str());
- pReq->szUrl = str.GetBuffer();
- }
- else {
- pReq->pData = mir_strdup(pReq->m_szParam);
- pReq->dataLength = pReq->m_szParam.GetLength();
+ pReq->m_szUrl = str.GetBuffer();
}
}
@@ -64,7 +60,7 @@ bool CVkProto::ExecuteRequest(AsyncHttpRequest *pReq)
tLocalWorkThreadTimer = m_tWorkThreadTimer = time(0);
}
- debugLogA("CVkProto::ExecuteRequest \n====\n%s\n====\n", pReq->szUrl);
+ 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);
diff --git a/protocols/VKontakte/src/vk_search.cpp b/protocols/VKontakte/src/vk_search.cpp
index f5da64438c..399e58945d 100644
--- a/protocols/VKontakte/src/vk_search.cpp
+++ b/protocols/VKontakte/src/vk_search.cpp
@@ -69,7 +69,7 @@ void CVkProto::FreeProtoShearchStruct(PROTOSEARCHBYNAME *pParam)
delete pParam;
}
-void CVkProto::OnSearch(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnSearch(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
PROTOSEARCHBYNAME *pParam = (PROTOSEARCHBYNAME *)pReq->pUserInfo;
debugLogA("CVkProto::OnSearch %d", reply->resultCode);
@@ -124,7 +124,7 @@ void CVkProto::OnSearch(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
FreeProtoShearchStruct(pParam);
}
-void CVkProto::OnSearchByMail(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnSearchByMail(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnSearch %d", reply->resultCode);
if (reply->resultCode != 200) {
diff --git a/protocols/VKontakte/src/vk_status.cpp b/protocols/VKontakte/src/vk_status.cpp
index 4fb2405aa2..10e55835b9 100644
--- a/protocols/VKontakte/src/vk_status.cpp
+++ b/protocols/VKontakte/src/vk_status.cpp
@@ -124,7 +124,7 @@ INT_PTR __cdecl CVkProto::SvcSetStatusMsg(WPARAM, LPARAM)
return 0;
}
-void CVkProto::OnReceiveStatusMsg(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveStatusMsg(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveStatusMsg %d", reply->resultCode);
if (reply->resultCode != 200)
@@ -153,7 +153,7 @@ void CVkProto::OnReceiveStatusMsg(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR
setWString("OldStatusMsg", pwszOldStatusMsg);
}
-void CVkProto::OnReceiveStatus(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveStatus(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveStatus %d", reply->resultCode);
if (reply->resultCode != 200)
diff --git a/protocols/VKontakte/src/vk_struct.cpp b/protocols/VKontakte/src/vk_struct.cpp
index 2b5eb9e121..153aac408d 100644
--- a/protocols/VKontakte/src/vk_struct.cpp
+++ b/protocols/VKontakte/src/vk_struct.cpp
@@ -68,9 +68,9 @@ AsyncHttpRequest::AsyncHttpRequest(CVkProto *ppro, int iRequestType, LPCSTR _url
m_priority = rpPriority;
}
-void AsyncHttpRequest::Redirect(NETLIBHTTPREQUEST *nhr)
+void AsyncHttpRequest::Redirect(MHttpResponse *nhr)
{
- if (auto *pszHdr = Netlib_GetHeader(nhr, "Location"))
+ if (auto *pszHdr = nhr->FindHeader("Location"))
m_szUrl = pszHdr;
}
diff --git a/protocols/VKontakte/src/vk_struct.h b/protocols/VKontakte/src/vk_struct.h
index f25072f89f..73683a652a 100644
--- a/protocols/VKontakte/src/vk_struct.h
+++ b/protocols/VKontakte/src/vk_struct.h
@@ -25,7 +25,7 @@ struct AsyncHttpRequest : public MTHttpRequest<CVkProto>
AsyncHttpRequest();
AsyncHttpRequest(CVkProto*, int iRequestType, LPCSTR szUrl, bool bSecure, MTHttpRequestHandler pFunc, RequestPriority rpPriority = rpMedium);
- void Redirect(NETLIBHTTPREQUEST*);
+ void Redirect(MHttpResponse*);
int m_iRetry;
int m_iErrorCode;
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index 393a215079..6f7d0b7791 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -200,7 +200,7 @@ void CVkProto::OnLoggedOut()
/////////////////////////////////////////////////////////////////////////////////////////
-void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest*)
+void CVkProto::OnOAuthAuthorize(MHttpResponse *reply, AsyncHttpRequest*)
{
debugLogA("CVkProto::OnOAuthAuthorize %d", reply->resultCode);
GrabCookies(reply, szVKCookieDomain);
@@ -225,7 +225,7 @@ void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest*)
}
if (reply->resultCode == 302) { // manual redirect
- LPCSTR pszLocation = Netlib_GetHeader(reply, "Location");
+ LPCSTR pszLocation = reply->FindHeader("Location");
if (pszLocation) {
if (!_strnicmp(pszLocation, szBlankUrl, sizeof(szBlankUrl) - 1)) {
m_szAccessToken = nullptr;
@@ -283,12 +283,12 @@ void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest*)
return;
}
- if (reply->resultCode != 200 || !reply->pData || (!(strstr(reply->pData, "method=\"post\"") || strstr(reply->pData, "method=\"POST\"")) && !strstr(reply->pData, "meta http-equiv=\"refresh\""))) { // something went wrong
+ if (reply->resultCode != 200 || reply->body.IsEmpty() || (!(strstr(reply->body, "method=\"post\"") || strstr(reply->body, "method=\"POST\"")) && !strstr(reply->body, "meta http-equiv=\"refresh\""))) { // something went wrong
ConnectionFailed(LOGINERR_NOSERVER);
return;
}
- LPCSTR pBlankUrl = strstr(reply->pData, szBlankUrl);
+ LPCSTR pBlankUrl = strstr(reply->body, szBlankUrl);
if (pBlankUrl) {
debugLogA("CVkProto::OnOAuthAuthorize blank ulr found");
m_szAccessToken = nullptr;
@@ -311,10 +311,10 @@ void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest*)
return;
}
- char* pMsgWarning = strstr(reply->pData, "service_msg_warning");
+ auto *pMsgWarning = strstr(reply->body, "service_msg_warning");
if (pMsgWarning) {
- char *p1 = strchr(pMsgWarning, '>');
- char *p2 = strchr(pMsgWarning, '<');
+ auto *p1 = strchr(pMsgWarning, '>');
+ auto *p2 = strchr(pMsgWarning, '<');
if (p1 && p2 && (p1 + 1 < p2)) {
CMStringA szMsg(p1 + 1, (int)(p2 - p1 - 1));
MsgPopup(ptrW(mir_utf8decodeW(szMsg)), TranslateT("Service message"), true);
@@ -325,7 +325,7 @@ void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest*)
}
CMStringA szAction, szBody;
- bool bSuccess = AutoFillForm(reply->pData, szAction, szBody);
+ bool bSuccess = AutoFillForm(reply->body.GetBuffer(), szAction, szBody);
if (!bSuccess || szAction.IsEmpty() || szBody.IsEmpty()) {
if (m_bPrevError) {
ConnectionFailed(LOGINERR_NOSERVER);
@@ -381,7 +381,7 @@ void CVkProto::RetrieveMyInfo()
Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/users.get.json", true, &CVkProto::OnReceiveMyInfo, AsyncHttpRequest::rpHigh));
}
-void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveMyInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveMyInfo %d", reply->resultCode);
if (reply->resultCode != 200) {
@@ -723,7 +723,7 @@ void CVkProto::RetrieveUsersInfo(bool bFreeOffline, bool bRepeat)
}
-void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveUserInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode);
@@ -801,7 +801,7 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe
}
}
-void CVkProto::OnReceiveGroupInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveGroupInfo(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode);
@@ -887,7 +887,7 @@ void CVkProto::RetrieveFriends(bool bCleanNonFriendContacts)
<< CHAR_PARAM("fields", szFieldsName))->pUserInfo = new CVkSendMsgParam(0, bCleanNonFriendContacts ? 1 : 0);
}
-void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveFriends(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveFriends %d", reply->resultCode);
if (reply->resultCode != 200 || !IsOnline())
@@ -983,7 +983,7 @@ INT_PTR __cdecl CVkProto::SvcDeleteFriend(WPARAM hContact, LPARAM flag)
return 0;
}
-void CVkProto::OnReceiveDeleteFriend(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+void CVkProto::OnReceiveDeleteFriend(MHttpResponse *reply, AsyncHttpRequest *pReq)
{
debugLogA("CVkProto::OnReceiveDeleteFriend %d", reply->resultCode);
CVkSendMsgParam *param = (CVkSendMsgParam*)pReq->pUserInfo;
diff --git a/protocols/Weather/src/weather_http.cpp b/protocols/Weather/src/weather_http.cpp
index a306315011..99c262ec6a 100644
--- a/protocols/Weather/src/weather_http.cpp
+++ b/protocols/Weather/src/weather_http.cpp
@@ -39,28 +39,17 @@ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **s
if (userAgent == nullptr || userAgent[0] == 0)
userAgent = NETLIB_USER_AGENT;
- NETLIBHTTPHEADER headers[5];
- headers[0].szName = "User-Agent";
- headers[0].szValue = userAgent;
- headers[1].szName = "Cache-Control";
- headers[1].szValue = "no-cache";
- headers[2].szName = "Pragma";
- headers[2].szValue = "no-cache";
- headers[3].szName = "Connection";
- headers[3].szValue = "close";
- headers[4].szName = "Cookie";
- headers[4].szValue = cookie;
-
// initialize the netlib request
- NETLIBHTTPREQUEST nlhr = { sizeof(nlhr) };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
- nlhr.szUrl = szUrl;
- nlhr.headers = headers;
- nlhr.headersCount = _countof(headers);
-
- if (cookie == nullptr || cookie[0] == 0)
- --nlhr.headersCount;
+ nlhr.m_szUrl = szUrl;
+ nlhr.AddHeader("User-Agent", userAgent);
+ nlhr.AddHeader("Cache-Control", "no-cache");
+ nlhr.AddHeader("Pragma", "no-cache");
+ nlhr.AddHeader("Connection", "close");
+ if (mir_strlen(cookie) > 0)
+ nlhr.AddHeader("Cookie", cookie);
// download the page
NLHR_PTR nlhrReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
@@ -75,17 +64,17 @@ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **s
// if the recieved code is 200 OK
int result;
if (nlhrReply->resultCode == 200) {
- if (nlhrReply->dataLength) {
+ if (!nlhrReply->body.IsEmpty()) {
bool bIsUtf = false;
result = 0;
// allocate memory and save the retrieved data
- auto *pszHdr = Netlib_GetHeader(nlhrReply, "Content-Type");
+ auto *pszHdr = nlhrReply->FindHeader("Content-Type");
// look for Content-Type=utf-8 in header
if (pszHdr && strstr(_strlwr(pszHdr), "utf-8"))
bIsUtf = true;
else {
- char *end = nlhrReply->pData;
+ char *end = nlhrReply->body.GetBuffer();
while (end) {
// look for
// <meta http-equiv="Content-Type" content="utf-8" />
@@ -112,9 +101,9 @@ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **s
wchar_t *retVal = nullptr;
if (bIsUtf)
- retVal = mir_utf8decodeW(nlhrReply->pData);
+ retVal = mir_utf8decodeW(nlhrReply->body);
if (retVal == nullptr)
- retVal = mir_a2u(nlhrReply->pData);
+ retVal = mir_a2u(nlhrReply->body);
*szData = retVal;
}
else result = DATA_EMPTY;
diff --git a/protocols/WebView/src/webview_getdata.cpp b/protocols/WebView/src/webview_getdata.cpp
index ae29e134ef..babfe3cca8 100644
--- a/protocols/WebView/src/webview_getdata.cpp
+++ b/protocols/WebView/src/webview_getdata.cpp
@@ -104,20 +104,12 @@ void GetData(void *param)
if (mir_strlen(url) < 3)
WErrorPopup(hContact, TranslateT("URL not supplied"));
- NETLIBHTTPREQUEST nlhr = { sizeof(nlhr) };
+ MHttpRequest nlhr;
nlhr.requestType = REQUEST_GET;
nlhr.flags = NLHRF_DUMPASTEXT;
- nlhr.szUrl = url;
- nlhr.headersCount = 2;
-
- NETLIBHTTPHEADER headers[2];
- headers[0].szName = "User-Agent";
- headers[0].szValue = NETLIB_USER_AGENT;
-
- headers[1].szName = "Content-Length";
- headers[1].szValue = nullptr;
-
- nlhr.headers = headers;
+ nlhr.m_szUrl = url;
+ nlhr.AddHeader("User-Agent", NETLIB_USER_AGENT);
+ nlhr.AddHeader("Content-Length", nullptr);
if ( g_plugin.getByte(NO_PROTECT_KEY, 0)) // disable
AlreadyDownloading = 0;
@@ -144,10 +136,10 @@ void GetData(void *param)
WErrorPopup(hContact, statusText);
db_set_ws(hContact, "CList", "StatusMsg", statusText);
}
- if (nlhrReply->dataLength) {
+ if (nlhrReply->body.GetLength()) {
trunccount = 0;
- downloadsize = (ULONG)mir_strlen(nlhrReply->pData);
- strncpy_s(truncated2, nlhrReply->pData, _TRUNCATE);
+ downloadsize = nlhrReply->body.GetLength();
+ strncpy_s(truncated2, nlhrReply->body, _TRUNCATE);
AlreadyDownloading = 1;
} // END DATELENGTH
} // END REPLY
diff --git a/protocols/WhatsApp/src/avatars.cpp b/protocols/WhatsApp/src/avatars.cpp
index 9bb7e926aa..077414e8e0 100644
--- a/protocols/WhatsApp/src/avatars.cpp
+++ b/protocols/WhatsApp/src/avatars.cpp
@@ -130,10 +130,10 @@ void WhatsAppProto::ServerFetchAvatar(const char *jid)
bool CMPlugin::SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai)
{
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.flags = NLHRF_NODUMP | NLHRF_PERSISTENT | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
req.requestType = REQUEST_GET;
- req.szUrl = (char*)pszUrl;
+ req.m_szUrl = pszUrl;
req.nlc = hAvatarConn;
NLHR_PTR pReply(Netlib_HttpTransaction(hAvatarUser, &req));
@@ -146,14 +146,14 @@ bool CMPlugin::SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai)
hAvatarConn = pReply->nlc;
bool bSuccess = false;
- if (pReply->resultCode == 200 && pReply->pData && pReply->dataLength) {
- if (auto *pszHdr = Netlib_GetHeader(pReply, "Content-Type"))
+ if (pReply->resultCode == 200 && !pReply->body.IsEmpty()) {
+ if (auto *pszHdr = pReply->FindHeader("Content-Type"))
ai.format = ProtoGetAvatarFormatByMimeType(pszHdr);
if (ai.format != PA_FORMAT_UNKNOWN) {
FILE *fout = _wfopen(ai.filename, L"wb");
if (fout) {
- fwrite(pReply->pData, 1, pReply->dataLength, fout);
+ fwrite(pReply->body, 1, pReply->body.GetLength(), fout);
fclose(fout);
bSuccess = true;
}
diff --git a/protocols/WhatsApp/src/server.cpp b/protocols/WhatsApp/src/server.cpp
index 857666b2e4..e653ac95ba 100644
--- a/protocols/WhatsApp/src/server.cpp
+++ b/protocols/WhatsApp/src/server.cpp
@@ -24,13 +24,10 @@ void WhatsAppProto::ServerThread(void *)
void WhatsAppProto::ServerThreadWorker()
{
// connect websocket
- NETLIBHTTPHEADER hdrs[] =
- {
- { "Origin", "https://web.whatsapp.com" },
- { 0, 0 }
- };
+ MHttpHeaders hdrs;
+ hdrs.AddHeader("Origin", "https://web.whatsapp.com");
- NLHR_PTR pReply(WebSocket_Connect(m_hNetlibUser, "web.whatsapp.com/ws/chat", hdrs));
+ NLHR_PTR pReply(WebSocket_Connect(m_hNetlibUser, "web.whatsapp.com/ws/chat", &hdrs));
if (pReply == nullptr) {
debugLogA("Server connection failed, exiting");
return;
diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp
index 3d3650c043..8e9a19b936 100644
--- a/protocols/WhatsApp/src/utils.cpp
+++ b/protocols/WhatsApp/src/utils.cpp
@@ -260,7 +260,7 @@ MBinBuffer decodeBufStr(const std::string &buf)
uint32_t decodeBigEndian(const uint8_t *buf, size_t len)
{
uint32_t ret = 0;
- for (int i = 0; i < len; i++) {
+ for (size_t i = 0; i < len; i++) {
ret <<= 8;
ret += buf[i];
}
@@ -271,7 +271,7 @@ uint32_t decodeBigEndian(const uint8_t *buf, size_t len)
std::string encodeBigEndian(uint32_t num, size_t len)
{
std::string res;
- for (int i = 0; i < len; i++) {
+ for (size_t i = 0; i < len; i++) {
char c = num & 0xFF;
res = c + res;
num >>= 8;
@@ -519,20 +519,17 @@ WAMediaKeys::WAMediaKeys(const uint8_t *pKey, size_t keyLen, const char *pszMedi
MBinBuffer WhatsAppProto::DownloadEncryptedFile(const char *url, const ProtobufCBinaryData &mediaKeys, const char *pszMediaType)
{
- NETLIBHTTPHEADER headers[1] = {{"Origin", "https://web.whatsapp.com"}};
-
- NETLIBHTTPREQUEST req = {};
+ MHttpRequest req;
req.requestType = REQUEST_GET;
- req.szUrl = (char*)url;
- req.headersCount = _countof(headers);
- req.headers = headers;
+ req.m_szUrl = url;
+ req.AddHeader("Origin", "https://web.whatsapp.com");
MBinBuffer ret;
auto *pResp = Netlib_HttpTransaction(m_hNetlibUser, &req);
if (pResp) {
if (pResp->resultCode == 200) {
WAMediaKeys out(mediaKeys.data, mediaKeys.len, pszMediaType);
- ret = aesDecrypt(EVP_aes_256_cbc(), out.cipherKey, out.iv, pResp->pData, pResp->dataLength);
+ ret = aesDecrypt(EVP_aes_256_cbc(), out.cipherKey, out.iv, pResp->body, pResp->body.GetLength());
}
}
diff --git a/src/mir_app/mir_app.vcxproj b/src/mir_app/mir_app.vcxproj
index 4cecba6fe2..ed4ea3b3e1 100644
--- a/src/mir_app/mir_app.vcxproj
+++ b/src/mir_app/mir_app.vcxproj
@@ -117,7 +117,9 @@
<ClCompile Include="src\meta_options.cpp" />
<ClCompile Include="src\meta_services.cpp" />
<ClCompile Include="src\meta_utils.cpp" />
+ <ClCompile Include="src\MHttpHeaders.cpp" />
<ClCompile Include="src\MHttpRequest.cpp" />
+ <ClCompile Include="src\MHttpResponse.cpp" />
<ClCompile Include="src\miranda.cpp" />
<ClCompile Include="src\modules.cpp" />
<ClCompile Include="src\movetogroup.cpp" />
diff --git a/src/mir_app/mir_app.vcxproj.filters b/src/mir_app/mir_app.vcxproj.filters
index b1c74d0b08..35a50fb760 100644
--- a/src/mir_app/mir_app.vcxproj.filters
+++ b/src/mir_app/mir_app.vcxproj.filters
@@ -428,6 +428,12 @@
<ClCompile Include="src\srmm_main.cpp">
<Filter>Source Files\SRMM</Filter>
</ClCompile>
+ <ClCompile Include="src\MHttpResponse.cpp">
+ <Filter>Source Files\Netlib</Filter>
+ </ClCompile>
+ <ClCompile Include="src\MHttpHeaders.cpp">
+ <Filter>Source Files\Netlib</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\filter.h">
diff --git a/src/mir_app/src/MHttpHeaders.cpp b/src/mir_app/src/MHttpHeaders.cpp
new file mode 100644
index 0000000000..7681f2aa1b
--- /dev/null
+++ b/src/mir_app/src/MHttpHeaders.cpp
@@ -0,0 +1,82 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 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"
+
+static int CompareHeaders(const MHttpHeader *p1, const MHttpHeader *p2)
+{
+ return strcmp(p1->szName, p2->szName);
+}
+
+MHttpHeaders::MHttpHeaders() :
+ OBJLIST<MHttpHeader>(10, CompareHeaders)
+{
+}
+
+MHttpHeaders::~MHttpHeaders()
+{
+}
+
+void MHttpHeaders::AddHeader(const char *pszName, const char *pszValue)
+{
+ MHttpHeader tmp(pszName, 0);
+ if (auto *p = find(&tmp))
+ p->szValue = mir_strdup(pszValue);
+ else
+ insert(new MHttpHeader(pszName, pszValue));
+}
+
+void MHttpHeaders::DeleteHeader(const char *pszName)
+{
+ MHttpHeader tmp(pszName, 0);
+ int idx = getIndex(&tmp);
+ if (idx != -1)
+ remove(idx);
+}
+
+char* MHttpHeaders::FindHeader(const char *pszName) const
+{
+ MHttpHeader tmp(pszName, 0);
+ if (auto *p = find(&tmp))
+ return p->szValue;
+ return nullptr;
+}
+
+CMStringA MHttpHeaders::GetCookies() const
+{
+ CMStringA ret;
+
+ for (auto &it : *this) {
+ if (mir_strcmpi(it->szName, "Set-Cookie"))
+ continue;
+
+ if (!ret.IsEmpty())
+ ret.Append("; ");
+
+ if (const char *p = strchr(it->szValue, ';'))
+ ret.Append(it->szValue, p - it->szValue.get());
+ else
+ ret.Append(it->szValue);
+ }
+ return ret;
+}
diff --git a/src/mir_app/src/MHttpRequest.cpp b/src/mir_app/src/MHttpRequest.cpp
index 5c165a5130..e6445549b2 100644
--- a/src/mir_app/src/MHttpRequest.cpp
+++ b/src/mir_app/src/MHttpRequest.cpp
@@ -25,33 +25,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
MHttpRequest::MHttpRequest()
{
- 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)
+void MHttpRequest::SetData(const void *pData, size_t cbLen)
{
- 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++;
+ m_szParam.Truncate((int)cbLen);
+ memcpy(m_szParam.GetBuffer(), pData, cbLen);
}
+
/////////////////////////////////////////////////////////////////////////////////////////
MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest *pReq, const INT_PARAM &param)
diff --git a/src/mir_app/src/MHttpResponse.cpp b/src/mir_app/src/MHttpResponse.cpp
new file mode 100644
index 0000000000..1ac1e35c74
--- /dev/null
+++ b/src/mir_app/src/MHttpResponse.cpp
@@ -0,0 +1,60 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 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"
+
+MHttpResponse::MHttpResponse()
+{
+}
+
+MHttpResponse::~MHttpResponse()
+{
+ mir_free(szUrl);
+ mir_free(szResultDescr);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MHttpResponse helpers for Pascal
+// declared only in m_netlib.inc
+
+EXTERN_C MIR_APP_DLL(int) Netlib_HttpResult(MHttpResponse *nlhr)
+{
+ return (nlhr) ? nlhr->resultCode : 500;
+}
+
+EXTERN_C MIR_APP_DLL(char *) Netlib_HttpBuffer(MHttpResponse *nlhr, int &cbLen)
+{
+ if (!nlhr)
+ return nullptr;
+
+ cbLen = nlhr->body.GetLength();
+ return nlhr->body.Detach();
+}
+
+EXTERN_C MIR_APP_DLL(char *) Netlib_HttpCookies(MHttpResponse *nlhr)
+{
+ if (!nlhr)
+ return nullptr;
+
+ return nlhr->GetCookies().Detach();
+}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index bb3a1dec8e..7565cfe960 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -234,7 +234,6 @@ Font_RegisterW @326
Options_AddPage @327
Options_Open @328
Options_OpenPage @329
-Netlib_GetHeader @330
Srmm_ModifyButton @331
Srmm_AddButton @332
Srmm_GetButtonState @333
@@ -584,15 +583,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
db_mc_addToMeta @716
db_mc_convertToMeta @717
db_mc_enable @718
@@ -919,10 +915,50 @@ _CallContactService@20 @1048 NONAME
??0MDatabaseExport@@QAE@XZ @1049 NONAME
??1MDatabaseExport@@UAE@XZ @1050 NONAME
??_7MDatabaseExport@@6B@ @1051 NONAME
-??4NETLIBHTTPREQUEST@@QAEAAU0@$$QAU0@@Z @1052 NONAME
-??4NETLIBHTTPREQUEST@@QAEAAU0@ABU0@@Z @1053 NONAME
-??ANETLIBHTTPREQUEST@@QAEPBDPBD@Z @1054 NONAME
-?GetCookies@NETLIBHTTPREQUEST@@QBE?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@XZ @1055 NONAME
-Netlib_HttpBuffer @1056
-Netlib_HttpCookies @1057
-Netlib_HttpResult @1058
+??0?$LIST@UMHttpHeader@@@@QAE@ABU0@@Z @1052 NONAME
+??0?$LIST@UMHttpHeader@@@@QAE@HH@Z @1053 NONAME
+??0?$LIST@UMHttpHeader@@@@QAE@HP6AHPBUMHttpHeader@@0@Z@Z @1054 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QAE@ABU0@@Z @1055 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QAE@HH@Z @1056 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QAE@HP6AHPBUMHttpHeader@@0@Z@Z @1057 NONAME
+??0MHttpHeaders@@QAE@ABU0@@Z @1058 NONAME
+??0MHttpHeaders@@QAE@XZ @1059 NONAME
+??0MHttpResponse@@QAE@XZ @1060 NONAME
+??1?$LIST@UMHttpHeader@@@@QAE@XZ @1061 NONAME
+??1?$OBJLIST@UMHttpHeader@@@@QAE@XZ @1062 NONAME
+??1MHttpHeaders@@QAE@XZ @1063 NONAME
+??1MHttpResponse@@QAE@XZ @1064 NONAME
+??4?$LIST@UMHttpHeader@@@@QAEAAU0@ABU0@@Z @1065 NONAME
+??4?$OBJLIST@UMHttpHeader@@@@QAEAAU0@ABU0@@Z @1066 NONAME
+??4MHttpHeaders@@QAEAAU0@ABU0@@Z @1067 NONAME
+??A?$LIST@UMHttpHeader@@@@QBEPAUMHttpHeader@@H@Z @1068 NONAME
+??A?$OBJLIST@UMHttpHeader@@@@QBEAAUMHttpHeader@@H@Z @1069 NONAME
+??AMHttpHeaders@@QAEPBDPBD@Z @1070 NONAME
+?AddHeader@MHttpHeaders@@QAEXPBD0@Z @1071 NONAME
+?FindHeader@MHttpHeaders@@QBEPADPBD@Z @1072 NONAME
+?GetCookies@MHttpHeaders@@QBE?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@XZ @1073 NONAME
+?begin@?$LIST@UMHttpHeader@@@@QBEPAPAUMHttpHeader@@XZ @1074 NONAME
+?destroy@?$LIST@UMHttpHeader@@@@QAEXXZ @1075 NONAME
+?destroy@?$OBJLIST@UMHttpHeader@@@@QAEXXZ @1076 NONAME
+?end@?$LIST@UMHttpHeader@@@@QBEPAPAUMHttpHeader@@XZ @1077 NONAME
+?find@?$LIST@UMHttpHeader@@@@QBEPAUMHttpHeader@@PAU2@@Z @1078 NONAME
+?getArray@?$LIST@UMHttpHeader@@@@QBEPAPAUMHttpHeader@@XZ @1079 NONAME
+?getCount@?$LIST@UMHttpHeader@@@@QBEHXZ @1080 NONAME
+?getIndex@?$LIST@UMHttpHeader@@@@QBEHPAUMHttpHeader@@@Z @1081 NONAME
+?indexOf@?$LIST@UMHttpHeader@@@@QBEHPAPAUMHttpHeader@@@Z @1082 NONAME
+?indexOf@?$LIST@UMHttpHeader@@@@QBEHPAUMHttpHeader@@@Z @1083 NONAME
+?insert@?$LIST@UMHttpHeader@@@@QAEHPAUMHttpHeader@@@Z @1084 NONAME
+?insert@?$LIST@UMHttpHeader@@@@QAEHPAUMHttpHeader@@H@Z @1085 NONAME
+?put@?$LIST@UMHttpHeader@@@@QAEXHPAUMHttpHeader@@@Z @1086 NONAME
+?remove@?$LIST@UMHttpHeader@@@@QAEHH@Z @1087 NONAME
+?remove@?$LIST@UMHttpHeader@@@@QAEHPAUMHttpHeader@@@Z @1088 NONAME
+?remove@?$OBJLIST@UMHttpHeader@@@@QAEHH@Z @1089 NONAME
+?remove@?$OBJLIST@UMHttpHeader@@@@QAEHPAUMHttpHeader@@@Z @1090 NONAME
+?removeItem@?$LIST@UMHttpHeader@@@@QAEPAUMHttpHeader@@PAPAU2@@Z @1091 NONAME
+?removeItem@?$OBJLIST@UMHttpHeader@@@@QAEXPAPAUMHttpHeader@@@Z @1092 NONAME
+?rev_iter@?$LIST@UMHttpHeader@@@@QBE?AVreverse_iterator@1@XZ @1093 NONAME
+_Netlib_HttpBuffer@8 @1094 NONAME
+_Netlib_HttpCookies@4 @1095 NONAME
+_Netlib_HttpResult@4 @1096 NONAME
+?SetData@MHttpRequest@@QAEXPBXI@Z @1097 NONAME
+?DeleteHeader@MHttpHeaders@@QAEXPBD@Z @1098 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 26f860b889..f1161f7878 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -234,7 +234,6 @@ Font_RegisterW @326
Options_AddPage @327
Options_Open @328
Options_OpenPage @329
-Netlib_GetHeader @330
Srmm_ModifyButton @331
Srmm_AddButton @332
Srmm_GetButtonState @333
@@ -584,15 +583,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
db_mc_addToMeta @716
db_mc_convertToMeta @717
db_mc_enable @718
@@ -919,10 +915,50 @@ CallContactService @1042 NONAME
??0MDatabaseExport@@QEAA@XZ @1043 NONAME
??1MDatabaseExport@@UEAA@XZ @1044 NONAME
??_7MDatabaseExport@@6B@ @1045 NONAME
-??4NETLIBHTTPREQUEST@@QEAAAEAU0@$$QEAU0@@Z @1046 NONAME
-??4NETLIBHTTPREQUEST@@QEAAAEAU0@AEBU0@@Z @1047 NONAME
-??ANETLIBHTTPREQUEST@@QEAAPEBDPEBD@Z @1048 NONAME
-?GetCookies@NETLIBHTTPREQUEST@@QEBA?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@XZ @1049 NONAME
-Netlib_HttpBuffer @1050
-Netlib_HttpCookies @1051
-Netlib_HttpResult @1052
+??0?$LIST@UMHttpHeader@@@@QEAA@AEBU0@@Z @1046 NONAME
+??0?$LIST@UMHttpHeader@@@@QEAA@HP6AHPEBUMHttpHeader@@0@Z@Z @1047 NONAME
+??0?$LIST@UMHttpHeader@@@@QEAA@H_J@Z @1048 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QEAA@AEBU0@@Z @1049 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QEAA@HP6AHPEBUMHttpHeader@@0@Z@Z @1050 NONAME
+??0?$OBJLIST@UMHttpHeader@@@@QEAA@H_J@Z @1051 NONAME
+??0MHttpHeaders@@QEAA@AEBU0@@Z @1052 NONAME
+??0MHttpHeaders@@QEAA@XZ @1053 NONAME
+??0MHttpResponse@@QEAA@XZ @1054 NONAME
+??1?$LIST@UMHttpHeader@@@@QEAA@XZ @1055 NONAME
+??1?$OBJLIST@UMHttpHeader@@@@QEAA@XZ @1056 NONAME
+??1MHttpHeaders@@QEAA@XZ @1057 NONAME
+??1MHttpResponse@@QEAA@XZ @1058 NONAME
+??4?$LIST@UMHttpHeader@@@@QEAAAEAU0@AEBU0@@Z @1059 NONAME
+??4?$OBJLIST@UMHttpHeader@@@@QEAAAEAU0@AEBU0@@Z @1060 NONAME
+??4MHttpHeaders@@QEAAAEAU0@AEBU0@@Z @1061 NONAME
+??A?$LIST@UMHttpHeader@@@@QEBAPEAUMHttpHeader@@H@Z @1062 NONAME
+??A?$OBJLIST@UMHttpHeader@@@@QEBAAEAUMHttpHeader@@H@Z @1063 NONAME
+??AMHttpHeaders@@QEAAPEBDPEBD@Z @1064 NONAME
+?AddHeader@MHttpHeaders@@QEAAXPEBD0@Z @1065 NONAME
+?FindHeader@MHttpHeaders@@QEBAPEADPEBD@Z @1066 NONAME
+?GetCookies@MHttpHeaders@@QEBA?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@XZ @1067 NONAME
+?begin@?$LIST@UMHttpHeader@@@@QEBAPEAPEAUMHttpHeader@@XZ @1068 NONAME
+?destroy@?$LIST@UMHttpHeader@@@@QEAAXXZ @1069 NONAME
+?destroy@?$OBJLIST@UMHttpHeader@@@@QEAAXXZ @1070 NONAME
+?end@?$LIST@UMHttpHeader@@@@QEBAPEAPEAUMHttpHeader@@XZ @1071 NONAME
+?find@?$LIST@UMHttpHeader@@@@QEBAPEAUMHttpHeader@@PEAU2@@Z @1072 NONAME
+?getArray@?$LIST@UMHttpHeader@@@@QEBAPEAPEAUMHttpHeader@@XZ @1073 NONAME
+?getCount@?$LIST@UMHttpHeader@@@@QEBAHXZ @1074 NONAME
+?getIndex@?$LIST@UMHttpHeader@@@@QEBAHPEAUMHttpHeader@@@Z @1075 NONAME
+?indexOf@?$LIST@UMHttpHeader@@@@QEBAHPEAPEAUMHttpHeader@@@Z @1076 NONAME
+?indexOf@?$LIST@UMHttpHeader@@@@QEBAHPEAUMHttpHeader@@@Z @1077 NONAME
+?insert@?$LIST@UMHttpHeader@@@@QEAAHPEAUMHttpHeader@@@Z @1078 NONAME
+?insert@?$LIST@UMHttpHeader@@@@QEAAHPEAUMHttpHeader@@H@Z @1079 NONAME
+?put@?$LIST@UMHttpHeader@@@@QEAAXHPEAUMHttpHeader@@@Z @1080 NONAME
+?remove@?$LIST@UMHttpHeader@@@@QEAAHH@Z @1081 NONAME
+?remove@?$LIST@UMHttpHeader@@@@QEAAHPEAUMHttpHeader@@@Z @1082 NONAME
+?remove@?$OBJLIST@UMHttpHeader@@@@QEAAHH@Z @1083 NONAME
+?remove@?$OBJLIST@UMHttpHeader@@@@QEAAHPEAUMHttpHeader@@@Z @1084 NONAME
+?removeItem@?$LIST@UMHttpHeader@@@@QEAAPEAUMHttpHeader@@PEAPEAU2@@Z @1085 NONAME
+?removeItem@?$OBJLIST@UMHttpHeader@@@@QEAAXPEAPEAUMHttpHeader@@@Z @1086 NONAME
+?rev_iter@?$LIST@UMHttpHeader@@@@QEBA?AVreverse_iterator@1@XZ @1087 NONAME
+Netlib_HttpBuffer @1088 NONAME
+Netlib_HttpCookies @1089 NONAME
+Netlib_HttpResult @1090 NONAME
+?SetData@MHttpRequest@@QEAAXPEBX_K@Z @1091 NONAME
+?DeleteHeader@MHttpHeaders@@QEAAXPEBD@Z @1092 NONAME
diff --git a/src/mir_app/src/netlib.h b/src/mir_app/src/netlib.h
index 1ce7394cfb..fc11fb8546 100644
--- a/src/mir_app/src/netlib.h
+++ b/src/mir_app/src/netlib.h
@@ -71,6 +71,56 @@ struct NetlibUrl
int flags = 0, port = 0;
};
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct MChunkHandler
+{
+ virtual int getTotal() const = 0;
+ virtual void updateChunk(const void *pData, size_t cbLen) = 0;
+ virtual void apply(MHttpResponse *nlhr) = 0;
+};
+
+class MMemoryChunkStorage : public MChunkHandler
+{
+ MBinBuffer buf;
+
+ int getTotal() const override
+ {
+ return (int)buf.length();
+ }
+
+ void updateChunk(const void *pData, size_t cbLen) override
+ {
+ buf.append(pData, cbLen);
+ }
+
+ void apply(MHttpResponse *nlhr) override
+ {
+ unsigned dataLen = (unsigned)buf.length();
+ nlhr->body.Truncate(dataLen+1);
+ memcpy(nlhr->body.GetBuffer(), buf.data(), dataLen);
+ nlhr->body.SetAt(dataLen, 0);
+ }
+
+public:
+ MMemoryChunkStorage() {}
+};
+
+class MFileChunkStorage : public MChunkHandler
+{
+ CMStringW filePath;
+
+ void updateChunk(const void *pData, size_t cbLen) override;
+ void apply(MHttpResponse *nlhr) override;
+
+public:
+ MFileChunkStorage(const wchar_t *pwszFileName) :
+ filePath(pwszFileName)
+ {}
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
struct NetlibConnection : public MZeroedObject
{
NetlibConnection();
@@ -86,6 +136,7 @@ struct NetlibConnection : public MZeroedObject
NetlibUrl url;
int timeout;
+ MChunkHandler *pChunkHandler;
char *szNewUrl;
mir_cs csHttpSequenceNums;
@@ -164,9 +215,9 @@ bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn);
// netlibhttp.cpp
void NetlibHttpSetLastErrorUsingHttpResult(int result);
-int Netlib_SendHttpRequest(HNETLIBCONN hConnection, NETLIBHTTPREQUEST *pRec);
+int Netlib_SendHttpRequest(HNETLIBCONN hConnection, MHttpRequest *pRec, MChunkHandler *pHandler);
-NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection *nlc, uint32_t hflags, uint32_t dflags, bool isConnect = false);
+MHttpResponse* NetlibHttpRecv(NetlibConnection *nlc, uint32_t hflags, uint32_t dflags, bool isConnect = false);
// netliblog.cpp
void NetlibLogShowOptions(void);
diff --git a/src/mir_app/src/netlib_autoproxy.cpp b/src/mir_app/src/netlib_autoproxy.cpp
index c725166c5c..5e4e7deff0 100644
--- a/src/mir_app/src/netlib_autoproxy.cpp
+++ b/src/mir_app/src/netlib_autoproxy.cpp
@@ -52,20 +52,16 @@ static void GetFile(char *szUrl, AUTO_PROXY_SCRIPT_BUFFER &buf)
nlu.toLog = 1;
// initialize the netlib request
- NETLIBHTTPREQUEST nlhr = {};
- nlhr.requestType = REQUEST_GET;
+ MHttpRequest nlhr;
nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_REDIRECT;
- nlhr.szUrl = szUrl;
+ nlhr.m_szUrl = szUrl;
// download the page
NLHR_PTR nlhrReply(Netlib_HttpTransaction(&nlu, &nlhr));
if (nlhrReply) {
if (nlhrReply->resultCode == 200) {
- buf.lpszScriptBuffer = nlhrReply->pData;
- buf.dwScriptBufferSize = nlhrReply->dataLength + 1;
-
- nlhrReply->dataLength = 0;
- nlhrReply->pData = nullptr;
+ buf.dwScriptBufferSize = nlhrReply->body.GetLength() + 1;
+ buf.lpszScriptBuffer = nlhrReply->body.Detach();
}
}
}
diff --git a/src/mir_app/src/netlib_http.cpp b/src/mir_app/src/netlib_http.cpp
index 9e8e6759cb..a5bd0aaf92 100644
--- a/src/mir_app/src/netlib_http.cpp
+++ b/src/mir_app/src/netlib_http.cpp
@@ -82,61 +82,17 @@ ProxyAuthList proxyAuthList;
/////////////////////////////////////////////////////////////////////////////////////////
// Module exports
-MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST *nlhr)
+MIR_APP_DLL(bool) Netlib_FreeHttpRequest(MHttpResponse *nlhr)
{
- if (nlhr == nullptr || nlhr->requestType != REQUEST_RESPONSE) {
+ if (nlhr == nullptr) {
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
- if (nlhr->headers) {
- for (int i = 0; i < nlhr->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhr->headers[i];
- mir_free(p.szName);
- mir_free(p.szValue);
- }
- mir_free(nlhr->headers);
- }
- mir_free(nlhr->pData);
- mir_free(nlhr->szResultDescr);
- mir_free(nlhr->szUrl);
- mir_free(nlhr);
+ delete nlhr;
return true;
}
-MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *nlhr, const char *hdr)
-{
- if (nlhr == nullptr || hdr == nullptr)
- return nullptr;
-
- for (int i = 0; i < nlhr->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhr->headers[i];
- if (_stricmp(p.szName, hdr) == 0)
- return p.szValue;
- }
-
- return nullptr;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CMStringA NETLIBHTTPREQUEST::GetCookies() const
-{
- CMStringA ret;
-
- for (int i = 0; i < headersCount; i++) {
- if (!mir_strcmpi(headers[i].szName, "Set-Cookie")) {
- char *p = strchr(headers[i].szValue, ';');
- if (p) *p = 0;
- if (!ret.IsEmpty())
- ret.Append("; ");
-
- ret.Append(headers[i].szValue);
- }
- }
- return ret;
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
static int RecvWithTimeoutTime(NetlibConnection *nlc, int dwTimeoutTime, char *buf, int len, int flags)
@@ -165,22 +121,22 @@ static int RecvWithTimeoutTime(NetlibConnection *nlc, int dwTimeoutTime, char *b
return Netlib_Recv(nlc, buf, len, flags);
}
-static char* NetlibHttpFindAuthHeader(NETLIBHTTPREQUEST *nlhrReply, const char *hdr, const char *szProvider)
+static char* NetlibHttpFindAuthHeader(MHttpResponse *nlhrReply, const char *hdr, const char *szProvider)
{
char *szBasicHdr = nullptr;
char *szNegoHdr = nullptr;
char *szNtlmHdr = nullptr;
- for (int i=0; i < nlhrReply->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhrReply->headers[i];
- if (_stricmp(p.szName, hdr) == 0) {
- if (_strnicmp(p.szValue, "Negotiate", 9) == 0)
- szNegoHdr = p.szValue;
- else if (_strnicmp(p.szValue, "NTLM", 4) == 0)
- szNtlmHdr = p.szValue;
- else if (_strnicmp(p.szValue, "Basic", 5) == 0)
- szBasicHdr = p.szValue;
- }
+ for (auto &it : *nlhrReply) {
+ if (_stricmp(it->szName, hdr))
+ continue;
+
+ if (!_strnicmp(it->szValue, "Negotiate", 9))
+ szNegoHdr = it->szValue;
+ else if (!_strnicmp(it->szValue, "NTLM", 4))
+ szNtlmHdr = it->szValue;
+ else if (!_strnicmp(it->szValue, "Basic", 5))
+ szBasicHdr = it->szValue;
}
if (szNegoHdr && (!szProvider || !_stricmp(szProvider, "Negotiate"))) return szNegoHdr;
@@ -210,12 +166,12 @@ static void NetlibConnFromUrl(const char *szUrl, bool secur, NetlibUrl &url)
url.flags = (secur ? NLOCF_SSL : 0);
}
-static NetlibConnection* NetlibHttpProcessUrl(NETLIBHTTPREQUEST *nlhr, NetlibUser *nlu, NetlibConnection *nlc, const char *szUrl = nullptr)
+static NetlibConnection* NetlibHttpProcessUrl(MHttpRequest *nlhr, NetlibUser *nlu, NetlibConnection *nlc, const char *szUrl = nullptr)
{
NetlibUrl url;
if (szUrl == nullptr)
- NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, url);
+ NetlibConnFromUrl(nlhr->m_szUrl, (nlhr->flags & NLHRF_SSL) != 0, url);
else
NetlibConnFromUrl(szUrl, false, url);
@@ -385,12 +341,12 @@ static int HttpPeekFirstResponseLine(NetlibConnection *nlc, uint32_t dwTimeoutTi
return 1;
}
-static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest, NETLIBHTTPREQUEST *nlhr, int sendContentLengthHeader)
+static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest, MHttpRequest *nlhr, int sendContentLengthHeader)
{
bool sendData = (nlhr->requestType == REQUEST_POST || nlhr->requestType == REQUEST_PUT || nlhr->requestType == REQUEST_PATCH);
if (sendContentLengthHeader && sendData)
- httpRequest.AppendFormat("Content-Length: %d\r\n\r\n", nlhr->dataLength);
+ httpRequest.AppendFormat("Content-Length: %d\r\n\r\n", nlhr->m_szParam.GetLength());
else
httpRequest.AppendFormat("\r\n");
@@ -400,13 +356,13 @@ static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest,
(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
int bytesSent = Netlib_Send(nlc, httpRequest, httpRequest.GetLength(), hflags);
- if (bytesSent != SOCKET_ERROR && sendData && nlhr->dataLength) {
+ if (bytesSent != SOCKET_ERROR && sendData && nlhr->m_szParam.GetLength()) {
uint32_t sflags = MSG_NOTITLE | (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) |
(nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ?
MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
- int sendResult = Netlib_Send(nlc, nlhr->pData, nlhr->dataLength, sflags);
+ int sendResult = Netlib_Send(nlc, nlhr->m_szParam, nlhr->m_szParam.GetLength(), sflags);
bytesSent = sendResult != SOCKET_ERROR ? bytesSent + sendResult : SOCKET_ERROR;
}
@@ -417,7 +373,7 @@ static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest,
/////////////////////////////////////////////////////////////////////////////////////////
// Receives HTTP headers
//
-// Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Returns a pointer to a MHttpRequest structure on success, NULL on failure.
// Call Netlib_FreeHttpRequest() to free this.
// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
// nlhr->pData = NULL and nlhr->dataLength = 0 always. The requested data should
@@ -433,21 +389,18 @@ static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest,
#define NHRV_BUF_SIZE 8192
-static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int flags)
+static MHttpResponse* Netlib_RecvHttpHeaders(NetlibConnection *nlc, int flags)
{
- NetlibConnection *nlc = (NetlibConnection *)hConnection;
if (!NetlibEnterNestedCS(nlc, NLNCS_RECV))
return nullptr;
uint32_t dwRequestTimeoutTime = GetTickCount() + HTTPRECVDATATIMEOUT;
- NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST *)mir_calloc(sizeof(NETLIBHTTPREQUEST));
+ std::unique_ptr<MHttpResponse> nlhr(new MHttpResponse());
nlhr->nlc = nlc; // Needed to id connection in the protocol HTTP gateway wrapper functions
- nlhr->requestType = REQUEST_RESPONSE;
int firstLineLength = 0;
if (!HttpPeekFirstResponseLine(nlc, dwRequestTimeoutTime, flags | MSG_PEEK, &nlhr->resultCode, &nlhr->szResultDescr, &firstLineLength)) {
NetlibLeaveNestedCS(&nlc->ncsRecv);
- Netlib_FreeHttpRequest(nlhr);
return nullptr;
}
@@ -455,7 +408,6 @@ static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int fl
int bytesPeeked = Netlib_Recv(nlc, buffer, min(firstLineLength, NHRV_BUF_SIZE), flags | MSG_DUMPASTEXT);
if (bytesPeeked != firstLineLength) {
NetlibLeaveNestedCS(&nlc->ncsRecv);
- Netlib_FreeHttpRequest(nlhr);
if (bytesPeeked != SOCKET_ERROR)
SetLastError(ERROR_HANDLE_EOF);
return nullptr;
@@ -492,14 +444,10 @@ static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int fl
if (bytesPeeked <= 0) {
NetlibLeaveNestedCS(&nlc->ncsRecv);
- Netlib_FreeHttpRequest(nlhr);
return nullptr;
}
// Receive headers
- nlhr->headersCount = headersCount;
- nlhr->headers = (NETLIBHTTPHEADER *)mir_calloc(sizeof(NETLIBHTTPHEADER) * headersCount);
-
headersCount = 0;
for (char *pbuffer = (char *)buf.data();; headersCount++) {
char *peol = strchr(pbuffer, '\n');
@@ -509,14 +457,12 @@ static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int fl
char *pColon = strchr(pbuffer, ':');
if (pColon == nullptr) {
- Netlib_FreeHttpRequest(nlhr); nlhr = nullptr;
SetLastError(ERROR_INVALID_DATA);
- break;
+ return nullptr;
}
*pColon = 0;
- nlhr->headers[headersCount].szName = mir_strdup(rtrim(pbuffer));
- nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon + 1));
+ nlhr->AddHeader(rtrim(pbuffer), lrtrimp(pColon + 1));
pbuffer = peol + 1;
}
@@ -525,7 +471,7 @@ static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int fl
nlc->foreBuf.appendBefore(buf.data(), buf.length());
NetlibLeaveNestedCS(&nlc->ncsRecv);
- return nlhr;
+ return nlhr.release();
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -539,9 +485,9 @@ static NETLIBHTTPREQUEST* Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int fl
// nlhr.resultCode and nlhr.szResultDescr are ignored by this function.
// Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND
-int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
+int Netlib_SendHttpRequest(HNETLIBCONN nlc, MHttpRequest *nlhr, MChunkHandler *pHandler)
{
- NETLIBHTTPREQUEST *nlhrReply = nullptr;
+ MHttpResponse *nlhrReply = nullptr;
HttpSecurityContext httpSecurity;
char *szHost = nullptr, *szNewUrl = nullptr;
@@ -549,7 +495,7 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
int bytesSent = 0;
bool lastFirstLineFail = false;
- if (nlhr == nullptr || nlhr->szUrl == nullptr || nlhr->szUrl[0] == '\0') {
+ if (nlhr == nullptr || nlhr->m_szUrl.IsEmpty()) {
SetLastError(ERROR_INVALID_PARAMETER);
return SOCKET_ERROR;
}
@@ -579,9 +525,11 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
if (!NetlibEnterNestedCS(nlc, NLNCS_SEND))
return SOCKET_ERROR;
- const char *pszFullUrl = nlhr->szUrl;
+ const char *pszFullUrl = nlhr->m_szUrl;
const char *pszUrl = nullptr;
+ nlc->pChunkHandler = pHandler;
+
unsigned complete = false;
int count = 11;
while (--count) {
@@ -650,15 +598,14 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
// HTTP headers
bool doneHostHeader = false, doneContentLengthHeader = false, doneProxyAuthHeader = false, doneAuthHeader = false, doneConnection = false;
- for (int i = 0; i < nlhr->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhr->headers[i];
- if (!mir_strcmpi(p.szName, "Host")) doneHostHeader = true;
- else if (!mir_strcmpi(p.szName, "Content-Length")) doneContentLengthHeader = true;
- else if (!mir_strcmpi(p.szName, "Proxy-Authorization")) doneProxyAuthHeader = true;
- else if (!mir_strcmpi(p.szName, "Authorization")) doneAuthHeader = true;
- else if (!mir_strcmpi(p.szName, "Connection")) doneConnection = true;
- if (p.szValue == nullptr) continue;
- httpRequest.AppendFormat("%s: %s\r\n", p.szName, p.szValue);
+ for (auto &it : *nlhr) {
+ if (!mir_strcmpi(it->szName, "Host")) doneHostHeader = true;
+ else if (!mir_strcmpi(it->szName, "Content-Length")) doneContentLengthHeader = true;
+ else if (!mir_strcmpi(it->szName, "Proxy-Authorization")) doneProxyAuthHeader = true;
+ else if (!mir_strcmpi(it->szName, "Authorization")) doneAuthHeader = true;
+ else if (!mir_strcmpi(it->szName, "Connection")) doneConnection = true;
+ if (it->szValue == nullptr) continue;
+ httpRequest.AppendFormat("%s: %s\r\n", it->szName, it->szValue);
}
if (szHost && !doneHostHeader)
httpRequest.AppendFormat("%s: %s\r\n", "Host", szHost);
@@ -683,9 +630,10 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
if (doneContentLengthHeader && nlhr->requestType != REQUEST_HEAD)
break;
+ int resultCode;
uint32_t fflags = MSG_PEEK | MSG_NODUMP | ((nlhr->flags & NLHRF_NOPROXY) ? MSG_RAW : 0);
uint32_t dwTimeOutTime = hdrTimeout < 0 ? -1 : GetTickCount() + hdrTimeout;
- if (!HttpPeekFirstResponseLine(nlc, dwTimeOutTime, fflags, &nlhr->resultCode, nullptr, nullptr)) {
+ if (!HttpPeekFirstResponseLine(nlc, dwTimeOutTime, fflags, &resultCode, nullptr, nullptr)) {
uint32_t err = GetLastError();
Netlib_Logf(nlu, "%s %d: %s Failed (%u %u)", __FILE__, __LINE__, "HttpPeekFirstResponseLine", err, count);
@@ -704,7 +652,6 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
continue;
}
- int resultCode = nlhr->resultCode;
lastFirstLineFail = false;
uint32_t hflags = (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPHEADERS | NLHRF_NODUMPSEND) ?
@@ -726,7 +673,7 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);
if (nlhrReply) {
- auto *tmpUrl = Netlib_GetHeader(nlhrReply, "Location");
+ auto *tmpUrl = nlhrReply->FindHeader("Location");
if (tmpUrl) {
size_t rlen = 0;
if (tmpUrl[0] == '/') {
@@ -838,14 +785,14 @@ int Netlib_SendHttpRequest(HNETLIBCONN nlc, NETLIBHTTPREQUEST *nlhr)
replaceStr(pszAuthHdr, nullptr);
if (nlhrReply) {
- Netlib_FreeHttpRequest(nlhrReply);
+ delete nlhrReply;
nlhrReply = nullptr;
}
}
if (count == 0) bytesSent = SOCKET_ERROR;
- if (nlhrReply)
- Netlib_FreeHttpRequest(nlhrReply);
+
+ delete nlhrReply;
//clean up
mir_free(pszProxyAuthHdr);
@@ -960,90 +907,70 @@ static int NetlibHttpRecvChunkHeader(NetlibConnection *nlc, bool first, uint32_t
}
}
-NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection *nlc, uint32_t hflags, uint32_t dflags, bool isConnect)
+MHttpResponse* NetlibHttpRecv(NetlibConnection *nlc, uint32_t hflags, uint32_t dflags, bool isConnect)
{
- int dataLen = -1, i, chunkhdr = 0;
+ int dataLen = -1;
bool chunked = false;
int cenc = 0, cenctype = 0, close = 0;
next:
- NETLIBHTTPREQUEST *nlhrReply = Netlib_RecvHttpHeaders(nlc, hflags);
+ std::unique_ptr<MHttpResponse> nlhrReply(Netlib_RecvHttpHeaders(nlc, hflags));
if (nlhrReply == nullptr)
return nullptr;
- if (nlhrReply->resultCode == 100) {
- Netlib_FreeHttpRequest(nlhrReply);
+ if (nlhrReply->resultCode == 100)
goto next;
- }
if (nlhrReply->resultCode == 204)
dataLen = 0;
- for (i = 0; i < nlhrReply->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhrReply->headers[i];
- if (!mir_strcmpi(p.szName, "Content-Length"))
- dataLen = atoi(p.szValue);
+ for (auto &it : *nlhrReply) {
+ if (!mir_strcmpi(it->szName, "Content-Length"))
+ dataLen = atoi(it->szValue);
- if (!mir_strcmpi(p.szName, "Content-Encoding")) {
- cenc = i;
- if (strstr(p.szValue, "gzip"))
+ if (!mir_strcmpi(it->szName, "Content-Encoding")) {
+ cenc = nlhrReply->indexOf(&it);
+ if (strstr(it->szValue, "gzip"))
cenctype = 1;
- else if (strstr(p.szValue, "deflate"))
+ else if (strstr(it->szValue, "deflate"))
cenctype = 2;
}
- if (!mir_strcmpi(p.szName, "Connection"))
- close = !mir_strcmpi(p.szValue, "close");
+ if (!mir_strcmpi(it->szName, "Connection"))
+ close = mir_strcmpi(it->szValue, "close") == 0;
- if (!mir_strcmpi(p.szName, "Transfer-Encoding") && !mir_strcmpi(p.szValue, "chunked")) {
+ if (!mir_strcmpi(it->szName, "Transfer-Encoding") && !mir_strcmpi(it->szValue, "chunked")) {
chunked = true;
- chunkhdr = i;
dataLen = -1;
}
}
if (nlhrReply->resultCode >= 200 && (dataLen > 0 || (!isConnect && dataLen < 0))) {
int recvResult, chunksz = -1;
- int dataBufferAlloced;
if (chunked) {
chunksz = NetlibHttpRecvChunkHeader(nlc, true, dflags | (cenctype ? MSG_NODUMP : 0));
- if (chunksz == SOCKET_ERROR) {
- Netlib_FreeHttpRequest(nlhrReply);
+ if (chunksz == SOCKET_ERROR)
return nullptr;
- }
+
dataLen = chunksz;
}
- dataBufferAlloced = dataLen < 0 ? 2048 : dataLen + 1;
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
+ ptrA tmpBuf((char *)mir_alloc(65536));
while (chunksz != 0) {
while (true) {
recvResult = RecvWithTimeoutTime(nlc, GetTickCount() + HTTPRECVDATATIMEOUT,
- nlhrReply->pData + nlhrReply->dataLength,
- dataBufferAlloced - nlhrReply->dataLength - 1,
- dflags | (cenctype ? MSG_NODUMP : 0));
+ tmpBuf, (chunked) ? chunksz : 65536, dflags | (cenctype ? MSG_NODUMP : 0));
if (recvResult == 0) break;
- if (recvResult == SOCKET_ERROR) {
- Netlib_FreeHttpRequest(nlhrReply);
+ if (recvResult == SOCKET_ERROR)
return nullptr;
- }
- nlhrReply->dataLength += recvResult;
- if (dataLen >= 0) {
- if (nlhrReply->dataLength >= dataLen)
+ nlc->pChunkHandler->updateChunk(tmpBuf, recvResult);
+ if (dataLen >= 0)
+ if (nlc->pChunkHandler->getTotal() >= dataLen)
break;
- }
- else if ((dataBufferAlloced - nlhrReply->dataLength) < 256) {
- dataBufferAlloced += 2048;
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
- if (nlhrReply->pData == nullptr) {
- SetLastError(ERROR_OUTOFMEMORY);
- Netlib_FreeHttpRequest(nlhrReply);
- return nullptr;
- }
- }
+
Sleep(10);
}
@@ -1051,60 +978,46 @@ next:
break;
chunksz = NetlibHttpRecvChunkHeader(nlc, false, dflags | MSG_NODUMP);
- if (chunksz == SOCKET_ERROR) {
- Netlib_FreeHttpRequest(nlhrReply);
+ if (chunksz == SOCKET_ERROR)
return nullptr;
- }
- dataLen += chunksz;
- dataBufferAlloced += chunksz;
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
+ dataLen += chunksz;
}
-
- nlhrReply->pData[nlhrReply->dataLength] = '\0';
}
- if (chunked) {
- nlhrReply->headers[chunkhdr].szName = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szName, 16);
- mir_strcpy(nlhrReply->headers[chunkhdr].szName, "Content-Length");
+ nlc->pChunkHandler->apply(nlhrReply.get());
- nlhrReply->headers[chunkhdr].szValue = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szValue, 16);
- mir_snprintf(nlhrReply->headers[chunkhdr].szValue, 16, "%u", nlhrReply->dataLength);
- }
+ if (chunked)
+ nlhrReply->AddHeader("Content-Length", CMStringA(FORMAT, "%u", dataLen));
- if (cenctype) {
- int bufsz = nlhrReply->dataLength;
+ if (cenctype && !nlhrReply->body.IsEmpty()) {
+ int bufsz = nlhrReply->body.GetLength();
char* szData = nullptr;
switch (cenctype) {
case 1:
- szData = gzip_decode(nlhrReply->pData, &bufsz, 0x10 | MAX_WBITS);
+ szData = gzip_decode(nlhrReply->body.GetBuffer(), &bufsz, 0x10 | MAX_WBITS);
break;
case 2:
- szData = gzip_decode(nlhrReply->pData, &bufsz, -MAX_WBITS);
+ szData = gzip_decode(nlhrReply->body.GetBuffer(), &bufsz, -MAX_WBITS);
if (bufsz < 0) {
- bufsz = nlhrReply->dataLength;
- szData = gzip_decode(nlhrReply->pData, &bufsz, MAX_WBITS);
+ bufsz = nlhrReply->body.GetLength();;
+ szData = gzip_decode(nlhrReply->body.GetBuffer(), &bufsz, MAX_WBITS);
}
break;
}
if (bufsz > 0) {
Netlib_Dump(nlc, (uint8_t*)szData, bufsz, false, dflags | MSG_NOTITLE);
- mir_free(nlhrReply->pData);
- nlhrReply->pData = szData;
- nlhrReply->dataLength = bufsz;
+ nlhrReply->body.Truncate(bufsz);
+ memcpy(nlhrReply->body.GetBuffer(), szData, bufsz);
+ nlhrReply->body.SetAt(bufsz, 0);
- mir_free(nlhrReply->headers[cenc].szName);
- mir_free(nlhrReply->headers[cenc].szValue);
- memmove(&nlhrReply->headers[cenc], &nlhrReply->headers[cenc+1], (--nlhrReply->headersCount-cenc)*sizeof(nlhrReply->headers[0]));
- }
- else if (bufsz == 0) {
- mir_free(nlhrReply->pData);
- nlhrReply->pData = nullptr;
- nlhrReply->dataLength = 0;
+ nlhrReply->remove(cenc);
}
+ else if (bufsz == 0)
+ nlhrReply->body.Empty();
}
if (close &&
@@ -1112,15 +1025,15 @@ next:
(!isConnect || nlhrReply->resultCode != 200))
NetlibDoCloseSocket(nlc);
- return nlhrReply;
+ return nlhrReply.release();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Module entry point
-MIR_APP_DLL(NETLIBHTTPREQUEST *) Netlib_HttpTransaction(HNETLIBUSER nlu, NETLIBHTTPREQUEST *nlhr)
+MIR_APP_DLL(MHttpResponse *) Netlib_HttpTransaction(HNETLIBUSER nlu, MHttpRequest *nlhr)
{
- if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) || !nlhr || !nlhr->szUrl || nlhr->szUrl[0] == 0) {
+ if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) || !nlhr || nlhr->m_szUrl.IsEmpty()) {
SetLastError(ERROR_INVALID_PARAMETER);
return nullptr;
}
@@ -1128,27 +1041,14 @@ MIR_APP_DLL(NETLIBHTTPREQUEST *) Netlib_HttpTransaction(HNETLIBUSER nlu, NETLIBH
if (nlhr->nlc != nullptr && GetNetlibHandleType(nlhr->nlc) != NLH_CONNECTION)
nlhr->nlc = nullptr;
- NetlibConnection *nlc = NetlibHttpProcessUrl(nlhr, nlu, (NetlibConnection *)nlhr->nlc);
+ NetlibConnection *nlc = NetlibHttpProcessUrl(nlhr, nlu, nlhr->nlc);
if (nlc == nullptr)
return nullptr;
- NETLIBHTTPREQUEST nlhrSend = *nlhr;
- nlhrSend.flags |= NLHRF_SMARTREMOVEHOST;
-
- bool doneUserAgentHeader = Netlib_GetHeader(nlhr, "User-Agent") != nullptr;
- bool doneAcceptEncoding = Netlib_GetHeader(nlhr, "Accept-Encoding") != nullptr;
- if (!doneUserAgentHeader || !doneAcceptEncoding) {
- nlhrSend.headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER) * (nlhrSend.headersCount + 2));
- memcpy(nlhrSend.headers, nlhr->headers, sizeof(NETLIBHTTPHEADER) * nlhr->headersCount);
- }
+ nlhr->flags |= NLHRF_SMARTREMOVEHOST;
- char szUserAgent[64];
- if (!doneUserAgentHeader) {
- nlhrSend.headers[nlhrSend.headersCount].szName = "User-Agent";
- nlhrSend.headers[nlhrSend.headersCount].szValue = szUserAgent;
- ++nlhrSend.headersCount;
-
- char szMirandaVer[64];
+ if (!nlhr->FindHeader("User-Agent")) {
+ char szUserAgent[64], szMirandaVer[64];
strncpy_s(szMirandaVer, MIRANDA_VERSION_STRING, _TRUNCATE);
#if defined(_WIN64)
strncat_s(szMirandaVer, " x64", _TRUNCATE);
@@ -1160,20 +1060,18 @@ MIR_APP_DLL(NETLIBHTTPREQUEST *) Netlib_HttpTransaction(HNETLIBUSER nlu, NETLIBH
mir_snprintf(szUserAgent, "Miranda/%s (%s)", szMirandaVer, pspace);
}
else mir_snprintf(szUserAgent, "Miranda/%s", szMirandaVer);
+
+ nlhr->AddHeader("User-Agent", szUserAgent);
}
- if (!doneAcceptEncoding) {
- nlhrSend.headers[nlhrSend.headersCount].szName = "Accept-Encoding";
- nlhrSend.headers[nlhrSend.headersCount].szValue = "deflate, gzip";
- ++nlhrSend.headersCount;
- }
- if (Netlib_SendHttpRequest(nlc, &nlhrSend) == SOCKET_ERROR) {
- if (!doneUserAgentHeader || !doneAcceptEncoding) mir_free(nlhrSend.headers);
- nlhr->resultCode = nlhrSend.resultCode;
+
+ if (!nlhr->FindHeader("Accept-Encoding"))
+ nlhr->AddHeader("Accept-Encoding", "deflate, gzip");
+
+ MMemoryChunkStorage storage;
+ if (Netlib_SendHttpRequest(nlc, nlhr, &storage) == SOCKET_ERROR) {
Netlib_CloseHandle(nlc);
return nullptr;
}
- if (!doneUserAgentHeader || !doneAcceptEncoding)
- mir_free(nlhrSend.headers);
uint32_t dflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) |
(nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
@@ -1183,7 +1081,7 @@ MIR_APP_DLL(NETLIBHTTPREQUEST *) Netlib_HttpTransaction(HNETLIBUSER nlu, NETLIBH
(nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
- NETLIBHTTPREQUEST *nlhrReply;
+ MHttpResponse *nlhrReply;
if (nlhr->requestType == REQUEST_HEAD)
nlhrReply = Netlib_RecvHttpHeaders(nlc, 0);
else
@@ -1203,25 +1101,3 @@ MIR_APP_DLL(NETLIBHTTPREQUEST *) Netlib_HttpTransaction(HNETLIBUSER nlu, NETLIBH
return nlhrReply;
}
-
-EXTERN_C MIR_APP_DLL(int) Netlib_HttpResult(NETLIBHTTPREQUEST *nlhr)
-{
- return (nlhr) ? nlhr->resultCode : 500;
-}
-
-EXTERN_C MIR_APP_DLL(char *) Netlib_HttpBuffer(NETLIBHTTPREQUEST *nlhr, int &cbLen)
-{
- if (!nlhr)
- return nullptr;
-
- cbLen = nlhr->dataLength;
- return nlhr->pData;
-}
-
-EXTERN_C MIR_APP_DLL(char *) Netlib_HttpCookies(NETLIBHTTPREQUEST *nlhr)
-{
- if (!nlhr)
- return nullptr;
-
- return nlhr->GetCookies().Detach();
-}
diff --git a/src/mir_app/src/netlib_openconn.cpp b/src/mir_app/src/netlib_openconn.cpp
index adbde4d07e..210c94cb71 100644
--- a/src/mir_app/src/netlib_openconn.cpp
+++ b/src/mir_app/src/netlib_openconn.cpp
@@ -308,15 +308,16 @@ static bool NetlibInitHttpsConnection(NetlibConnection *nlc)
szUrl.Format("%s:%u", inet_ntoa(*(PIN_ADDR)&ip), url.port);
}
- NETLIBHTTPREQUEST nlhrSend = {};
+ MMemoryChunkStorage storage;
+ MHttpRequest nlhrSend;
nlhrSend.requestType = REQUEST_CONNECT;
nlhrSend.flags = NLHRF_DUMPPROXY | NLHRF_HTTP11 | NLHRF_NOPROXY | NLHRF_REDIRECT;
- nlhrSend.szUrl = szUrl.GetBuffer();
+ nlhrSend.m_szUrl = szUrl;
- if (Netlib_SendHttpRequest(nlc, &nlhrSend) == SOCKET_ERROR)
+ if (Netlib_SendHttpRequest(nlc, &nlhrSend, &storage) == SOCKET_ERROR)
return false;
- NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW, true);
+ auto *nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW, true);
if (nlhrReply == nullptr)
return false;
diff --git a/src/mir_app/src/netlib_websocket.cpp b/src/mir_app/src/netlib_websocket.cpp
index cd3aaaef4e..a0f7465f0e 100644
--- a/src/mir_app/src/netlib_websocket.cpp
+++ b/src/mir_app/src/netlib_websocket.cpp
@@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../../libs/zlib/src/zlib.h"
-MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER nlu, const char *szHost, NETLIBHTTPHEADER *pHeaders)
+MIR_APP_DLL(MHttpResponse*) WebSocket_Connect(HNETLIBUSER nlu, const char *szHost, const MHttpHeaders *pHeaders)
{
CMStringA tmpHost(szHost);
@@ -37,7 +37,7 @@ MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER nlu, const char *s
auto *nlr = new MHttpRequest;
nlr->flags = NLHRF_PERSISTENT | NLHRF_HTTP11 | NLHRF_SSL;
- nlr->szUrl = tmpHost.GetBuffer();
+ nlr->m_szUrl = tmpHost.GetBuffer();
nlr->AddHeader("Accept", "*/*");
nlr->AddHeader("Upgrade", "websocket");
nlr->AddHeader("Pragma", "no-cache");
@@ -50,12 +50,9 @@ MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER nlu, const char *s
nlr->AddHeader("Sec-WebSocket-Version", "13");
nlr->AddHeader("Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits");
- if (pHeaders) {
- while (pHeaders->szName != nullptr) {
- nlr->AddHeader(pHeaders->szName, pHeaders->szValue);
- pHeaders++;
- }
- }
+ if (pHeaders)
+ for (auto &it: *pHeaders)
+ nlr->AddHeader(it->szName, it->szValue);
auto *pReply = Netlib_HttpTransaction(nlu, nlr);
delete nlr;