From 07ddfbd5994267e0f1aba52040a25db90ed8924b Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 22 Dec 2012 21:43:08 +0000 Subject: IMO2sProxy reverted. maybe will be needed later git-svn-id: http://svn.miranda-ng.org/main/trunk@2809 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../src/imo2skype/miranda/io_layer_netlib.c | 340 +++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c (limited to 'plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c') diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c new file mode 100644 index 0000000000..378f72e65f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c @@ -0,0 +1,340 @@ +/* Module: io_layer_netlib.c + Purpose: IO Layer for Internet communication using Miranda NETLIB + Author: leecher + Date: 20.04.2011 :=) +*/ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "include/newpluginapi.h" +#include "include/m_netlib.h" +#include "fifo.h" +#include "memlist.h" +#include "io_layer.h" + +#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13" + +typedef struct +{ + IOLAYER vtbl; + int iRecursion; + NETLIBHTTPREQUEST *nlhrReply; + LPVOID lpErrorBuf; + HANDLE nlc; +} IOLAYER_INST; + +typedef struct +{ + HANDLE hNetlib; + TYP_LIST *hCookies; + TYP_FIFO *hCookieStr; + char *pszCookies; + LONG lRefCount; + CRITICAL_SECTION cs; +} IOLAYER_SINGLETON; + +static IOLAYER_SINGLETON *m_hNL = NULL; + +static void IoLayer_Exit (IOLAYER *hPIO); +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); +static void IoLayer_Cancel(IOLAYER *hIO); +static char *IoLayer_GetLastError(IOLAYER *hIO); +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData); +static void IoLayer_FreeEscapeString(char *pszData); +static void FetchLastError (IOLAYER_INST *hIO); +static void add_cookies(char *pszCookies); +static void refresh_cookies(); +static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IOLAYER *IoLayerNETLIB_Init(void) +{ + IOLAYER_INST *hIO; + + if (CallService (MS_SYSTEM_GETVERSION, 0, 0) < 0x080000 || // Miranda HTTPS support starting with 0.8.0.0 + !(hIO = calloc(1, sizeof(IOLAYER_INST)))) + return NULL; + + // NETLIB only works as singleton + if (!m_hNL) + { + NETLIBUSER nlu={0}; + + if (!(m_hNL = calloc (1, sizeof(IOLAYER_SINGLETON)))) + { + free (hIO); + return NULL; + } + m_hNL->lRefCount++; + + // Init Netlib + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING; + nlu.szDescriptiveName = "imo2sproxy connection"; + nlu.szSettingsModule = "IMOPROXY"; + nlu.szHttpGatewayUserAgent = USER_AGENT; + if (!(m_hNL->hNetlib = (HANDLE)CallService (MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu)) || + !(m_hNL->hCookies = List_Init(0)) || + !(m_hNL->hCookieStr = Fifo_Init(0))) + { + IoLayer_Exit((IOLAYER*)hIO); + return NULL; + } + m_hNL->pszCookies = ""; + InitializeCriticalSection (&m_hNL->cs); + } else m_hNL->lRefCount++; + + // Init Vtbl + hIO->vtbl.Exit = IoLayer_Exit; + hIO->vtbl.Post = IoLayer_Post; + hIO->vtbl.Get = IoLayer_Get; + hIO->vtbl.Cancel = IoLayer_Cancel; + hIO->vtbl.GetLastError = IoLayer_GetLastError; + hIO->vtbl.EscapeString = IoLayer_EscapeString; + hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; + + return (IOLAYER*)hIO; +} +// ----------------------------------------------------------------------------- + +static void IoLayer_Exit (IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (InterlockedDecrement(&m_hNL->lRefCount) <= 0) + { + if (m_hNL->hNetlib) Netlib_CloseHandle (m_hNL->hNetlib); + if (m_hNL->hCookies) { + List_FreeElements(m_hNL->hCookies); + List_Exit (m_hNL->hCookies); + } + if (m_hNL->hCookieStr) Fifo_Exit(m_hNL->hCookieStr); + DeleteCriticalSection (&m_hNL->cs); + free (m_hNL); + m_hNL = NULL; + } + free (hIO); +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + NETLIBHTTPREQUEST nlhr={0}; + NETLIBHTTPHEADER headers[5]; + int i; + char *pszCookies = NULL; + + + /* + char szDbg[256]; + sprintf (szDbg, "Thread %d with hIO %08X requests %s\n", GetCurrentThreadId(), hIO, pszURL); + OutputDebugString(szDbg); + */ + + // Build basic request + nlhr.cbSize = sizeof(nlhr); + nlhr.flags = NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_REDIRECT; + if (!pdwLength) nlhr.flags |= NLHRF_DUMPASTEXT; // pdwLength needed -> Binary data + nlhr.requestType = pszPostFields?REQUEST_POST:REQUEST_GET; + nlhr.szUrl = pszURL; + nlhr.pData = pszPostFields; + nlhr.dataLength = cbPostFields; + nlhr.headers = headers; + + // Add headers + EnterCriticalSection (&m_hNL->cs); + if (m_hNL->pszCookies && *m_hNL->pszCookies) + { + headers[nlhr.headersCount].szName = "Cookie"; + headers[nlhr.headersCount++].szValue = pszCookies = strdup(m_hNL->pszCookies); + } + headers[nlhr.headersCount].szName = "User-Agent"; + headers[nlhr.headersCount++].szValue = USER_AGENT; + headers[nlhr.headersCount].szName = "Accept-Encoding"; + headers[nlhr.headersCount++].szValue = "deflate, gzip"; + headers[nlhr.headersCount].szName = "Content-Type"; + headers[nlhr.headersCount++].szValue = "application/x-www-form-urlencoded; charset=UTF-8"; + headers[nlhr.headersCount].szName = "X-Requested-With"; + headers[nlhr.headersCount++].szValue = "XMLHttpRequest"; + LeaveCriticalSection (&m_hNL->cs); + + // Do the transaction + nlhr.nlc = hIO->nlc = OpenConnection (&nlhr); + if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); + hIO->nlhrReply = (NETLIBHTTPREQUEST*)CallService (MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nlhr); + hIO->nlc = NULL; + + if (pszCookies) free (pszCookies); + if (!hIO->nlhrReply) + { + FetchLastError (hIO); + return NULL; + } + + if (!hIO->nlhrReply || !hIO->nlhrReply->dataLength || !hIO->nlhrReply->pData) + { + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) + strcpy (hIO->lpErrorBuf, "Reply contained no data"); + return NULL; + } + + // Error handling + if (hIO->nlhrReply->resultCode < 200 || hIO->nlhrReply->resultCode >= 300) + { + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) + sprintf (hIO->lpErrorBuf, "HTTP transaction returned status %d", hIO->nlhrReply->resultCode); + return NULL; + } + + // Process headers to collect cookies + EnterCriticalSection (&m_hNL->cs); + for (i=0; inlhrReply->headersCount; i++) + { + if (!strnicmp(hIO->nlhrReply->headers[i].szName, "Set-Cookie", 10)) + add_cookies(hIO->nlhrReply->headers[i].szValue); + } + LeaveCriticalSection (&m_hNL->cs); + + // Return reply + if (pdwLength) *pdwLength = hIO->nlhrReply->dataLength; + return hIO->nlhrReply->pData; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength) +{ + return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_Cancel(IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->nlc && Netlib_CloseHandle(hIO->nlc)) + hIO->nlc = NULL; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_GetLastError(IOLAYER *hIO) +{ + return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData) +{ + return (char*)CallService (MS_NETLIB_URLENCODE, 0, (LPARAM)pszData); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_FreeEscapeString(char *pszData) +{ + HeapFree(GetProcessHeap(), 0, pszData); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void FetchLastError (IOLAYER_INST *hIO) +{ + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (LPTSTR)&hIO->lpErrorBuf, 0, NULL); +} + +// ----------------------------------------------------------------------------- + +static void add_cookies(char *pszCookies) +{ + int i, nCount, iLenCmp, iLenCookie; + char *p, *pszCookie = NULL; + + if (!(p = strchr(pszCookies, '='))) return; + iLenCmp=p-pszCookies+1; + if ((p=strchr (p, ';')) || (p=strchr (p, ';'))) iLenCookie = p-pszCookies; + else iLenCookie=strlen(pszCookies); + + for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); + if (!strncmp(pszCookie, pszCookies, iLenCmp)) + break; + } + + if (i==nCount) pszCookie = NULL; + if (pszCookie = realloc (pszCookie, iLenCookie+1)) + { + strncpy (pszCookie, pszCookies, iLenCookie); + pszCookie[iLenCookie]=0; + if (ihCookies, pszCookie, i); + else + List_Push (m_hNL->hCookies, pszCookie); + } + refresh_cookies (); +} + +// ----------------------------------------------------------------------------- + +static void refresh_cookies() +{ + int i, nCount; + + Fifo_Reset (m_hNL->hCookieStr); + for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); + Fifo_Add (m_hNL->hCookieStr, pszCookie, strlen(pszCookie)); + Fifo_Add (m_hNL->hCookieStr, "; ", 2); + } + Fifo_Add (m_hNL->hCookieStr, "", 1); + m_hNL->pszCookies = Fifo_Get (m_hNL->hCookieStr, NULL); +} + +// ----------------------------------------------------------------------------- + +static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr) +{ + NETLIBOPENCONNECTION nloc={0}; + BOOL secur = (nlhr->flags & NLHRF_SSL) || _strnicmp(nlhr->szUrl, "https", 5) == 0; + char* phost = strstr(nlhr->szUrl, "://"); + char *ppath, *pcolon; + + // Poor man's InternetCrackUrl + nloc.cbSize = sizeof(NETLIBOPENCONNECTION); + if (phost) phost+=3; else phost=nlhr->szUrl; + nloc.szHost = _alloca (strlen(phost)+1); + strcpy ((char*)nloc.szHost, phost); + if (ppath = strchr(nloc.szHost, '/')) *ppath = '\0'; + if (pcolon = strrchr(nloc.szHost, ':')) + { + *pcolon = '\0'; + nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10); + } + else nloc.wPort = secur ? 443 : 80; + nloc.flags = (secur ? NLOCF_SSL : 0) | NLOCF_HTTP; + if (secur) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL; + + // Open connection + return (HANDLE)CallService (MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nloc); +} \ No newline at end of file -- cgit v1.2.3