From 3b55a62fdcb1f8222de3c2c8fbed530792c419a0 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 12 Oct 2012 14:53:57 +0000 Subject: GTalkExt, ICQ, IRC, Jabber: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/IcqOscarJ/src/icq_http.cpp | 212 +++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 protocols/IcqOscarJ/src/icq_http.cpp (limited to 'protocols/IcqOscarJ/src/icq_http.cpp') diff --git a/protocols/IcqOscarJ/src/icq_http.cpp b/protocols/IcqOscarJ/src/icq_http.cpp new file mode 100644 index 0000000000..3e50db43ed --- /dev/null +++ b/protocols/IcqOscarJ/src/icq_http.cpp @@ -0,0 +1,212 @@ +// ---------------------------------------------------------------------------80 +// ICQ plugin for Miranda Instant Messenger +// ________________________________________ +// +// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede +// Copyright © 2001,2002 Jon Keating, Richard Hughes +// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater +// Copyright © 2004,2005,2006 Joe Kucera +// +// 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. +// +// ----------------------------------------------------------------------------- +// DESCRIPTION: +// +// HTTP Gateway Handling routines +// +// ----------------------------------------------------------------------------- +#include "icqoscar.h" + +int icq_httpGatewayInit(HANDLE hConn, NETLIBOPENCONNECTION *nloc, NETLIBHTTPREQUEST *nlhr) +{ + // initial response from ICQ http gateway + WORD wLen, wVersion, wType; + WORD wIpLen; + DWORD dwSid1, dwSid2, dwSid3, dwSid4; + BYTE *buf; + char szSid[33], szHttpServer[256], szHttpGetUrl[300], szHttpPostUrl[300]; + NETLIBHTTPPROXYINFO nlhpi = {0}; + + if (nlhr->dataLength < 31) + { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + + buf = (PBYTE)nlhr->pData; + unpackWord(&buf, &wLen); + unpackWord(&buf, &wVersion); /* always 0x0443 */ + unpackWord(&buf, &wType); /* hello reply */ + buf += 6; /* dunno */ + unpackDWord(&buf, &dwSid1); + unpackDWord(&buf, &dwSid2); + unpackDWord(&buf, &dwSid3); + unpackDWord(&buf, &dwSid4); + null_snprintf(szSid, 33, "%08x%08x%08x%08x", dwSid1, dwSid2, dwSid3, dwSid4); + unpackWord(&buf, &wIpLen); + + if(nlhr->dataLength < 30 + wIpLen || wIpLen == 0 || wIpLen > sizeof(szHttpServer) - 1) + { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + + SetGatewayIndex(hConn, 1); // new master connection begins here + + memcpy(szHttpServer, buf, wIpLen); + szHttpServer[wIpLen] = '\0'; + + nlhpi.cbSize = sizeof(nlhpi); + nlhpi.flags = NLHPIF_USEPOSTSEQUENCE; + nlhpi.szHttpGetUrl = szHttpGetUrl; + nlhpi.szHttpPostUrl = szHttpPostUrl; + nlhpi.firstPostSequence = 1; + null_snprintf(szHttpGetUrl, 300, "http://%s/monitor?sid=%s", szHttpServer, szSid); + null_snprintf(szHttpPostUrl, 300, "http://%s/data?sid=%s&seq=", szHttpServer, szSid); + + return CallService(MS_NETLIB_SETHTTPPROXYINFO, (WPARAM)hConn, (LPARAM)&nlhpi); +} + + + +int icq_httpGatewayBegin(HANDLE hConn, NETLIBOPENCONNECTION* nloc) +{ // open our "virual data connection" + icq_packet packet; + size_t serverNameLen; + + serverNameLen = strlennull(nloc->szHost); + + packet.wLen = (WORD)(serverNameLen + 4); + write_httphdr(&packet, HTTP_PACKETTYPE_LOGIN, GetGatewayIndex(hConn)); + packWord(&packet, (WORD)serverNameLen); + packBuffer(&packet, (LPBYTE)nloc->szHost, (WORD)serverNameLen); + packWord(&packet, nloc->wPort); + INT_PTR res = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY|MSG_NOHTTPGATEWAYWRAP); + SAFE_FREE((void**)&packet.pData); + + return res != SOCKET_ERROR; +} + + + +int icq_httpGatewayWrapSend(HANDLE hConn, PBYTE buf, int len, int flags, MIRANDASERVICE pfnNetlibSend) +{ + PBYTE sendBuf = buf; + int sendLen = len; + int sendResult = 0; + + while (sendLen > 0) + { // imitate polite behaviour of icq5.1 and split large packets + icq_packet packet; + WORD curLen; + int curResult; + + if (sendLen > 512) curLen = 512; else curLen = (WORD)sendLen; + // send wrapped data + packet.wLen = curLen; + write_httphdr(&packet, HTTP_PACKETTYPE_FLAP, GetGatewayIndex(hConn)); + packBuffer(&packet, sendBuf, (WORD)curLen); + + NETLIBBUFFER nlb={ (char*)packet.pData, packet.wLen, flags }; + curResult = pfnNetlibSend((WPARAM)hConn, (LPARAM)&nlb); + + SAFE_FREE((void**)&packet.pData); + + // sending failed, end loop + if (curResult <= 0) + return curResult; + // calculare real number of data bytes sent + if (curResult > 14) sendResult += curResult - 14; + // move on + sendLen -= curLen; + sendBuf += curLen; + } + + return sendResult; +} + + + +PBYTE icq_httpGatewayUnwrapRecv(NETLIBHTTPREQUEST* nlhr, PBYTE buf, int len, int* outBufLen, void *(*NetlibRealloc)(void *, size_t)) +{ + WORD wLen, wType; + DWORD dwPackSeq; + PBYTE tbuf; + int i, copyBytes; + + + tbuf = buf; + for(i = 0;;) + { + if (tbuf - buf + 2 > len) + break; + unpackWord(&tbuf, &wLen); + if (wLen < 12) + break; + if (tbuf - buf + wLen > len) + break; + tbuf += 2; /* version */ + unpackWord(&tbuf, &wType); + tbuf += 4; /* flags */ + unpackDWord(&tbuf, &dwPackSeq); + if (wType == HTTP_PACKETTYPE_FLAP) + { // it is normal data packet + copyBytes = wLen - 12; + if (copyBytes > len - i) + { + /* invalid data - do our best to get something out of it */ + copyBytes = len - i; + } + memcpy(buf + i, tbuf, copyBytes); + i += copyBytes; + } + else if (wType == HTTP_PACKETTYPE_LOGINREPLY) + { // our "virtual connection" was established, good + BYTE bRes; + + unpackByte(&tbuf, &bRes); + wLen -= 1; + if (!bRes) + Netlib_Logf( NULL, "Gateway Connection #%d Established.", dwPackSeq); + else + Netlib_Logf( NULL, "Gateway Connection #%d Failed, error: %d", dwPackSeq, bRes); + } + else if (wType == HTTP_PACKETTYPE_CLOSEREPLY) + { // "virtual connection" closed - only received if any other "virual connection" still active + Netlib_Logf( NULL, "Gateway Connection #%d Closed.", dwPackSeq); + } + tbuf += wLen - 12; + } + *outBufLen = i; + + return buf; +} + + + +int icq_httpGatewayWalkTo(HANDLE hConn, NETLIBOPENCONNECTION* nloc) +{ // this is bad simplification - for avatars to work we need to handle + // two "virtual connections" at the same time + icq_packet packet; + DWORD dwGatewaySeq = GetGatewayIndex(hConn); + + packet.wLen = 0; + write_httphdr(&packet, HTTP_PACKETTYPE_CLOSE, dwGatewaySeq); + Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY|MSG_NOHTTPGATEWAYWRAP); + // we closed virtual connection, open new one + dwGatewaySeq++; + SetGatewayIndex(hConn, dwGatewaySeq); + return icq_httpGatewayBegin(hConn, nloc); +} -- cgit v1.2.3