summaryrefslogtreecommitdiff
path: root/protocols/MSN/src/msn_avatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/MSN/src/msn_avatar.cpp')
-rw-r--r--protocols/MSN/src/msn_avatar.cpp80
1 files changed, 79 insertions, 1 deletions
diff --git a/protocols/MSN/src/msn_avatar.cpp b/protocols/MSN/src/msn_avatar.cpp
index b1ed8b1690..bd27529c1f 100644
--- a/protocols/MSN/src/msn_avatar.cpp
+++ b/protocols/MSN/src/msn_avatar.cpp
@@ -22,11 +22,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void CMsnProto::AvatarQueue_Init()
{
::InitializeCriticalSection(&csAvatarQueue);
+ hevAvatarQueue = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ ForkThread(&CMsnProto::MSN_AvatarsThread, 0);
}
void CMsnProto::AvatarQueue_Uninit()
{
::DeleteCriticalSection(&csAvatarQueue);
+ ::CloseHandle(hevAvatarQueue);
}
void CMsnProto::pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl)
@@ -37,9 +41,83 @@ void CMsnProto::pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl)
mir_cslock lck(csAvatarQueue);
for (int i=0; i < lsAvatarQueue.getCount(); i++)
- if (lsAvatarQueue[i].hContact == hContact)
+ if (lsAvatarQueue[i]->hContact == hContact)
return;
lsAvatarQueue.insert(new AvatarQueueEntry(hContact, pszUrl));
+ SetEvent(hevAvatarQueue);
+ }
+}
+
+bool CMsnProto::loadHttpAvatar(AvatarQueueEntry *p)
+{
+ NETLIBHTTPHEADER nlbhHeaders[1];
+ nlbhHeaders[0].szName = "User-Agent";
+ nlbhHeaders[0].szValue = (char*)MSN_USER_AGENT;
+
+ NETLIBHTTPREQUEST nlhr = { sizeof(nlhr) };
+ nlhr.requestType = REQUEST_GET;
+ nlhr.flags = NLHRF_HTTP11 | NLHRF_REDIRECT;;
+ nlhr.szUrl = p->pszUrl;
+ nlhr.headers = (NETLIBHTTPHEADER*)&nlbhHeaders;
+ nlhr.headersCount = 1;
+
+ NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr);
+ if (nlhrReply == NULL)
+ return false;
+
+ if (nlhrReply->resultCode != 200 || nlhrReply->dataLength == 0) {
+LBL_Error:
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
+ return false;
+ }
+
+ const TCHAR *szExt;
+ int fmt = MSN_GetImageFormat(nlhrReply->pData, &szExt);
+ if (fmt == PA_FORMAT_UNKNOWN)
+ goto LBL_Error;
+
+ PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) };
+ AI.format = fmt;
+ AI.hContact = p->hContact;
+ MSN_GetAvatarFileName(AI.hContact, AI.filename, SIZEOF(AI.filename), szExt);
+ _tremove(AI.filename);
+
+ int fileId = _topen(AI.filename, _O_CREAT | _O_TRUNC | _O_WRONLY | O_BINARY, _S_IREAD | _S_IWRITE);
+ if (fileId == -1)
+ goto LBL_Error;
+
+ _write(fileId, nlhrReply->pData, (unsigned)nlhrReply->dataLength);
+ _close(fileId);
+
+ SendBroadcast(p->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &AI, 0);
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
+ return true;
+}
+
+void __cdecl CMsnProto::MSN_AvatarsThread(void*)
+{
+ while(true) {
+ if (WaitForSingleObject(hevAvatarQueue, INFINITE) != WAIT_OBJECT_0)
+ break;
+
+ if ( Miranda_Terminated())
+ break;
+
+ AvatarQueueEntry *p = NULL;
+ {
+ mir_cslock lck(csAvatarQueue);
+ if (lsAvatarQueue.getCount() > 0) {
+ p = lsAvatarQueue[0];
+ lsAvatarQueue.remove(0);
+ }
+ }
+
+ if (p == NULL)
+ continue;
+
+ if ( !loadHttpAvatar(p))
+ SendBroadcast(p->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, 0, 0);
+ delete p;
}
}