diff options
Diffstat (limited to 'miranda-wine/src/modules/netlib/netlibhttpproxy.c')
-rw-r--r-- | miranda-wine/src/modules/netlib/netlibhttpproxy.c | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/miranda-wine/src/modules/netlib/netlibhttpproxy.c b/miranda-wine/src/modules/netlib/netlibhttpproxy.c new file mode 100644 index 0000000..f3fc82e --- /dev/null +++ b/miranda-wine/src/modules/netlib/netlibhttpproxy.c @@ -0,0 +1,610 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+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 "commonheaders.h"
+#include "netlib.h"
+
+#define HTTPGETTIMEOUT 55000 //in ms. http GETs through most proxies will give up after a while so the request needs to be re-sent
+
+static int HttpGatewaySendGet(struct NetlibConnection *nlc)
+{
+ NETLIBHTTPREQUEST nlhrSend={0};
+ NETLIBHTTPHEADER httpHeaders[3];
+ char szUrl[512];
+ struct NetlibConnection nlcSend;
+
+ nlc->s=socket(AF_INET,SOCK_STREAM,0);
+ if(nlc->s==INVALID_SOCKET) {
+ Netlib_Logf(nlc->nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
+ return 0;
+ }
+
+ if(connect(nlc->s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR) {
+ Netlib_Logf(nlc->nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
+ return 0;
+ }
+
+ nlhrSend.cbSize=sizeof(nlhrSend);
+ nlhrSend.nlc=nlc;
+
+ /*
+ * Gena01 - one small change here, just in case there is a timeout or a problem and we died while
+ * receiving
+ */
+ nlhrSend.requestType=(nlc->nlhpi.szHttpGetUrl == NULL) ? REQUEST_POST : REQUEST_GET;
+ nlhrSend.flags=NLHRF_GENERATEHOST|NLHRF_DUMPPROXY|NLHRF_SMARTAUTHHEADER; + if (nlc->nlhpi.flags & NLHPIF_HTTP11) nlhrSend.flags |= NLHRF_HTTP11; +
+ /*
+ * Gena01 - fixing a possible crash, can't use GET Sequence if there is no GET URL
+ */
+ if ((nlc->nlhpi.flags&NLHPIF_USEGETSEQUENCE) && (nlc->nlhpi.szHttpGetUrl != NULL)) {
+ EnterCriticalSection(&nlc->csHttpSequenceNums);
+
+ mir_snprintf(szUrl,SIZEOF(szUrl),"%s%u",nlc->nlhpi.szHttpGetUrl,nlc->nlhpi.firstGetSequence);
+ nlc->nlhpi.firstGetSequence++;
+ if(nlc->nlhpi.flags&NLHPIF_GETPOSTSAMESEQUENCE) nlc->nlhpi.firstPostSequence++;
+ LeaveCriticalSection(&nlc->csHttpSequenceNums);
+ nlhrSend.szUrl=szUrl;
+ }
+ else nlhrSend.szUrl=(nlc->nlhpi.szHttpGetUrl == NULL) ? nlc->nlhpi.szHttpPostUrl : nlc->nlhpi.szHttpGetUrl;
+ nlhrSend.headers=httpHeaders;
+ nlhrSend.headersCount= 3;
+ httpHeaders[0].szName="User-Agent";
+ httpHeaders[0].szValue=nlc->nlu->user.szHttpGatewayUserAgent;
+ httpHeaders[1].szName="Cache-Control";
+ httpHeaders[1].szValue="no-store, no-cache";
+ httpHeaders[2].szName="Pragma";
+ httpHeaders[2].szValue="no-cache";
+
+ nlcSend=*nlc;
+ nlcSend.usingHttpGateway=0;
+
+ if (nlc->nlhpi.szHttpGetUrl != NULL) {
+
+ Netlib_Logf(nlc->nlu,"%s %d: Sending data.[ICQ GET] ",__FILE__,__LINE__);
+ if(NetlibHttpSendRequest((WPARAM)&nlcSend,(LPARAM)&nlhrSend)==SOCKET_ERROR) {
+ nlc->usingHttpGateway=1;
+ return 0;
+ }
+ nlc->dwLastGetSentTime=GetTickCount();
+ return 1;
+ }
+
+ /*
+ * Gena01 - small addition here, if we doing a POST then insert our packet here
+ */
+ if (nlc->pHttpProxyPacketQueue != NULL) {
+ struct NetlibHTTPProxyPacketQueue *p = nlc->pHttpProxyPacketQueue;
+
+ nlc->pHttpProxyPacketQueue = nlc->pHttpProxyPacketQueue->next;
+
+ nlhrSend.dataLength=p->dataBufferLen;
+ nlhrSend.pData=(char*)p->dataBuffer;
+
+ mir_free(p);
+ }
+
+ if(NetlibHttpSendRequest((WPARAM)&nlcSend,(LPARAM)&nlhrSend)==SOCKET_ERROR) {
+ struct NetlibHTTPProxyPacketQueue *p = nlc->pHttpProxyPacketQueue;
+ + mir_free(nlhrSend.pData); +
+ nlc->usingHttpGateway=1;
+
+ /*
+ * Gena01 - we need to drop ALL pending packets. Connection died!
+ */
+ while (p != NULL) {
+ struct NetlibHTTPProxyPacketQueue *t = p;
+
+ p = p->next;
+
+ mir_free(t->dataBuffer);
+ mir_free(t);
+ }
+
+ nlc->pHttpProxyPacketQueue = NULL; /* empty Queue */
+
+ return 0;
+ }
+ mir_free(nlhrSend.pData); + nlc->dwLastGetSentTime=GetTickCount();
+ return 1;
+}
+
+/*
+ * Gena01 - this is the old POST method, I renamed it and left it intact for ICQ support. it's called
+ * when we have both GET and POST URLs specified.
+ */
+int NetlibHttpGatewayOLDPost(struct NetlibConnection *nlc,const char *buf,int len,int flags)
+{
+ NETLIBHTTPREQUEST nlhrSend={0},*nlhrReply;
+ NETLIBHTTPHEADER httpHeaders[4];
+ char szUrl[512];
+ struct NetlibConnection nlcSend={0};
+
+ nlcSend.handleType=NLH_CONNECTION;
+ nlcSend.nlu=nlc->nlu;
+ nlcSend.hInstSecurityDll=nlc->hInstSecurityDll;
+ nlcSend.s=socket(AF_INET,SOCK_STREAM,0);
+ if(nlcSend.s==INVALID_SOCKET) {
+ Netlib_Logf(nlc->nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
+ return SOCKET_ERROR;
+ }
+ nlcSend.hOkToCloseEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
+ nlcSend.dontCloseNow=0;
+ NetlibInitializeNestedCS(&nlcSend.ncsRecv);
+ NetlibInitializeNestedCS(&nlcSend.ncsSend);
+
+ if(connect(nlcSend.s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR) {
+ Netlib_Logf(nlc->nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
+ NetlibDeleteNestedCS(&nlcSend.ncsRecv);
+ NetlibDeleteNestedCS(&nlcSend.ncsSend);
+ CloseHandle(nlcSend.hOkToCloseEvent);
+ closesocket(nlcSend.s);
+ return SOCKET_ERROR;
+ }
+
+ nlhrSend.cbSize=sizeof(nlhrSend);
+ nlhrSend.nlc=nlc;
+ nlhrSend.requestType=REQUEST_POST;
+ nlhrSend.flags=NLHRF_GENERATEHOST|NLHRF_DUMPPROXY|NLHRF_SMARTAUTHHEADER;
+ if(flags&MSG_NODUMP) nlhrSend.flags|=NLHRF_NODUMP;
+ if(nlc->nlhpi.flags&NLHPIF_USEPOSTSEQUENCE) {
+ EnterCriticalSection(&nlc->csHttpSequenceNums);
+ mir_snprintf(szUrl,SIZEOF(szUrl),"%s%u",nlc->nlhpi.szHttpPostUrl,nlc->nlhpi.firstPostSequence);
+ nlc->nlhpi.firstPostSequence++;
+ if(nlc->nlhpi.flags&NLHPIF_GETPOSTSAMESEQUENCE) nlc->nlhpi.firstGetSequence++;
+ LeaveCriticalSection(&nlc->csHttpSequenceNums);
+ nlhrSend.szUrl=szUrl;
+ }
+ else nlhrSend.szUrl=nlc->nlhpi.szHttpPostUrl;
+ nlhrSend.headers=httpHeaders;
+ nlhrSend.headersCount=3;
+ httpHeaders[0].szName="User-Agent";
+ httpHeaders[0].szValue=nlc->nlu->user.szHttpGatewayUserAgent;
+ httpHeaders[1].szName="Cache-Control";
+ httpHeaders[1].szValue="no-store, no-cache";
+ httpHeaders[2].szName="Connection";
+ httpHeaders[2].szValue="close";
+ httpHeaders[3].szName="Pragma";
+ httpHeaders[3].szValue="no-cache";
+ nlhrSend.dataLength=len;
+ nlhrSend.pData=(char*)buf;
+ if(NetlibHttpSendRequest((WPARAM)&nlcSend,(LPARAM)&nlhrSend)==SOCKET_ERROR) {
+ NetlibDeleteNestedCS(&nlcSend.ncsRecv);
+ NetlibDeleteNestedCS(&nlcSend.ncsSend);
+ CloseHandle(nlcSend.hOkToCloseEvent);
+ closesocket(nlcSend.s);
+ return SOCKET_ERROR;
+ }
+
+ nlhrReply=(NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)&nlcSend,flags&MSG_NODUMP?MSG_NODUMP:MSG_DUMPPROXY);
+ if(nlhrReply==NULL
+ || nlhrReply->resultCode<200 || nlhrReply->resultCode>=300) {
+ NetlibDeleteNestedCS(&nlcSend.ncsRecv);
+ NetlibDeleteNestedCS(&nlcSend.ncsSend);
+ CloseHandle(nlcSend.hOkToCloseEvent);
+ closesocket(nlcSend.s);
+ if(nlhrReply) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
+ }
+ return SOCKET_ERROR;
+ }
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+
+ NetlibDeleteNestedCS(&nlcSend.ncsRecv);
+ NetlibDeleteNestedCS(&nlcSend.ncsSend);
+ CloseHandle(nlcSend.hOkToCloseEvent);
+ closesocket(nlcSend.s);
+ return len;
+}
+
+int NetlibHttpGatewayPost(struct NetlibConnection *nlc,const char *buf,int len,int flags)
+{
+ struct NetlibHTTPProxyPacketQueue *p;
+
+ if (nlc->nlhpi.szHttpGetUrl != NULL)
+ return NetlibHttpGatewayOLDPost(nlc, buf, len, flags);
+
+ /*
+ * Gena01 - many changes here, do compare against the other version.
+ *
+ * Change #1: simplify to use similar code to GET
+ * Change #2: we need to allow to parse POST reply if szHttpGetUrl is NULL
+ * Change #3: Keep connection open if we need to.
+ *
+ * Impact: NONE! Since currently miranda doesn't allow szHttpGetUrl to be NULL, it will not connect
+ * with the new plugins that use this code.
+ */
+
+ p = mir_alloc(sizeof(struct NetlibHTTPProxyPacketQueue));
+ p->dataBuffer = mir_alloc(len);
+ memcpy(p->dataBuffer, buf, len);
+ p->dataBufferLen = len;
+ p->next = NULL;
+
+ /*
+ * Now check to see where to insert this in our queue
+ */
+ if (nlc->pHttpProxyPacketQueue == NULL) {
+ nlc->pHttpProxyPacketQueue = p;
+ } else {
+ struct NetlibHTTPProxyPacketQueue *t = nlc->pHttpProxyPacketQueue;
+
+ while (t->next != NULL)
+ t = t->next;
+
+ t->next = p;
+ }
+
+
+ /*
+ * Gena01 - fake a Send!! tell 'em all is ok. We catch errors in Recv.
+ */
+ return len;
+}
+
+#define NETLIBHTTP_RETRYCOUNT 3
+#define NETLIBHTTP_RETRYTIMEOUT 5000
+
+int NetlibHttpGatewayRecv(struct NetlibConnection *nlc,char *buf,int len,int flags)
+{
+ DWORD dwTimeNow;
+ int timedout;
+ NETLIBHTTPREQUEST *nlhrReply;
+ PBYTE dataBuffer;
+ int contentLength,i,bytesRecved;
+ int recvResult;
+ int retryCount;
+
+ /*
+ * Gena01 - we need to send packet here, since we didn't do it before.
+ */
+ if ((nlc->nlhpi.szHttpGetUrl == NULL) && (nlc->s == INVALID_SOCKET) && nlc->dataBuffer == NULL ) {
+
+ if ( nlc->pollingTimeout == 0 )
+ nlc->pollingTimeout = 30;
+
+ /* We Need to sleep/wait for the data to send before we do receive */
+ for ( retryCount = 0; retryCount < nlc->pollingTimeout; retryCount++ )
+ {
+ if ( nlc->pHttpProxyPacketQueue != NULL )
+ break;
+
+ if ( SleepEx( 1000, TRUE ))
+ return SOCKET_ERROR;
+ }
+
+/* if ( retryCount == nlc->pollingTimeout )
+ { SetLastError( ERROR_TIMEOUT );
+ return SOCKET_ERROR;
+ }
+*/
+ if ( nlc->pHttpProxyPacketQueue == 0 && nlc->nlu->user.pfnHttpGatewayWrapSend != NULL )
+ nlc->nlu->user.pfnHttpGatewayWrapSend((HANDLE)nlc,"",0,MSG_NOHTTPGATEWAYWRAP,NetlibSend); +
+ if(!HttpGatewaySendGet(nlc)) {
+ return SOCKET_ERROR;
+ }
+ }
+ /********************/
+ if(nlc->dataBuffer) {
+ if(nlc->dataBufferLen<=len) {
+ contentLength=nlc->dataBufferLen;
+ CopyMemory(buf,nlc->dataBuffer,nlc->dataBufferLen);
+ if(!(flags&MSG_PEEK)) {
+ mir_free(nlc->dataBuffer);
+ nlc->dataBuffer=NULL;
+ nlc->dataBufferLen=0;
+ }
+ return contentLength;
+ }
+ CopyMemory(buf,nlc->dataBuffer,len);
+ if(!(flags&MSG_PEEK)) {
+ nlc->dataBufferLen-=len;
+ MoveMemory(nlc->dataBuffer,nlc->dataBuffer+len,nlc->dataBufferLen);
+ nlc->dataBuffer=(PBYTE)mir_realloc(nlc->dataBuffer,nlc->dataBufferLen);
+ }
+ return len;
+ }
+ for( retryCount = 0;;) {
+ timedout=0;
+ dwTimeNow=GetTickCount();
+ if(dwTimeNow>=nlc->dwLastGetSentTime+HTTPGETTIMEOUT) timedout=1;
+ else if(!WaitUntilReadable(nlc->s,nlc->dwLastGetSentTime+HTTPGETTIMEOUT-dwTimeNow)) {
+ if(GetLastError()==ERROR_TIMEOUT) timedout=1;
+ else return SOCKET_ERROR;
+ }
+ if(timedout) {
+ closesocket(nlc->s);
+ nlc->s=INVALID_SOCKET;
+ if(!HttpGatewaySendGet(nlc)) return SOCKET_ERROR;
+ retryCount = 0;
+ continue;
+ }
+ nlhrReply=(NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc,flags|MSG_RAW|MSG_DUMPPROXY);
+ if(nlhrReply==NULL) return SOCKET_ERROR;
+ // ignore 1xx result codes
+ if (nlhrReply->resultCode < 200)
+ { + NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply); + continue;
+ } + // 0.3.1+
+ // Attempt to retry NETLIBHTTP_RETRYCOUNT times if the result code is >300
+ if (nlhrReply->resultCode >= 300)
+ {
+ if (retryCount < NETLIBHTTP_RETRYCOUNT) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ Netlib_Logf(nlc->nlu, "Error received from proxy, retrying");
+ retryCount++;
+ closesocket(nlc->s);
+ nlc->s = INVALID_SOCKET;
+ Sleep(NETLIBHTTP_RETRYTIMEOUT); // wait 5 seconds
+ // retry the connection
+ Netlib_Logf(nlc->nlu,"%s %d: ResultCode?? Doing GET.",__FILE__,__LINE__);
+ if(HttpGatewaySendGet(nlc))
+ continue;
+ SetLastError(ERROR_GEN_FAILURE);
+ return SOCKET_ERROR;
+ }
+ }
+ retryCount = 0;
+ contentLength=-1;
+ for(i=0;i<nlhrReply->headersCount;i++)
+ { + if(!lstrcmpiA(nlhrReply->headers[i].szName,"Content-Length")) {
+ contentLength=atoi(nlhrReply->headers[i].szValue);
+ break;
+ }
+ } +
+ /*
+ if(contentLength<0) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ SetLastError(ERROR_INVALID_DATA);
+ return SOCKET_ERROR;
+ }*/
+ if(contentLength==0 && nlc->nlu->user.szHttpGatewayHello != NULL)
+ { + NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply); + continue;
+ } +
+
+ if (contentLength < 0) {
+ /* create initial buffer */
+ contentLength = 2048;
+
+ dataBuffer=(PBYTE)mir_alloc(contentLength);
+
+ /* error and exit */
+ if(dataBuffer==NULL) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return SOCKET_ERROR;
+ }
+
+ /* now we need to get the bytes and add them to our buffer */
+ bytesRecved = 0;
+
+ do {
+ recvResult=NLRecv(nlc,dataBuffer+bytesRecved,contentLength-bytesRecved,MSG_RAW|MSG_DUMPPROXY);
+ if(recvResult==SOCKET_ERROR) {
+ mir_free(dataBuffer);
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ if(recvResult==0) SetLastError(ERROR_HANDLE_EOF);
+ return SOCKET_ERROR;
+ }
+ bytesRecved+=recvResult;
+ } while (recvResult > 0);
+ contentLength = bytesRecved;
+ } else {
+ if(contentLength > 0) {
+ dataBuffer=(PBYTE)mir_alloc(contentLength);
+ if(dataBuffer==NULL) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return SOCKET_ERROR;
+ }
+ for(bytesRecved=0;bytesRecved<contentLength;) {
+ recvResult=NLRecv(nlc,dataBuffer+bytesRecved,contentLength-bytesRecved,MSG_RAW|MSG_DUMPPROXY);
+ if(recvResult==0 || recvResult==SOCKET_ERROR) {
+ mir_free(dataBuffer);
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ if(recvResult==0) SetLastError(ERROR_HANDLE_EOF);
+ return SOCKET_ERROR;
+ }
+ bytesRecved+=recvResult;
+ } }
+ else dataBuffer = NULL;
+ }
+
+ closesocket(nlc->s);
+ nlc->s=INVALID_SOCKET;
+
+ /*
+ * Gena01 - ok, ICQ does it here so that when we enter this function again we have reply
+ * pending. This is quite clever, since GET always gets replies from ICQ server
+ *
+ */
+ if (nlc->nlhpi.szHttpGetUrl != NULL) {
+ Netlib_Logf(nlc->nlu,"%s %d: Doing GET, Again????",__FILE__,__LINE__);
+
+ if(!HttpGatewaySendGet(nlc)) {
+ mir_free(dataBuffer);
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ return SOCKET_ERROR;
+ }
+ }
+
+ if(nlc->nlu->user.pfnHttpGatewayUnwrapRecv && !(flags&MSG_NOHTTPGATEWAYWRAP)) {
+ PBYTE newBuffer;
+ newBuffer=nlc->nlu->user.pfnHttpGatewayUnwrapRecv(nlhrReply,dataBuffer,contentLength,&contentLength,mir_realloc);
+ if(newBuffer==NULL) {
+ mir_free(dataBuffer);
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ return SOCKET_ERROR;
+ }
+ dataBuffer=newBuffer;
+ }
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ if(contentLength>0) break;
+ if((contentLength==0)&&(nlc->nlhpi.szHttpGetUrl==NULL))
+ break;
+ mir_free(dataBuffer);
+ }
+ if(contentLength<=len) {
+ if(flags&MSG_PEEK) {
+ nlc->dataBuffer=dataBuffer;
+ nlc->dataBufferLen=contentLength;
+ }
+ CopyMemory(buf,dataBuffer,contentLength);
+ if(!(flags&MSG_PEEK)) mir_free(dataBuffer);
+ return contentLength;
+ }
+ CopyMemory(buf,dataBuffer,len);
+ if(!(flags&MSG_PEEK)) {
+ MoveMemory(dataBuffer,dataBuffer+len,contentLength-len);
+ dataBuffer=(PBYTE)mir_realloc(dataBuffer,contentLength-len);
+ nlc->dataBufferLen=contentLength-len;
+ }
+ else nlc->dataBufferLen=contentLength;
+ nlc->dataBuffer=dataBuffer;
+
+ Netlib_Logf(nlc->nlu,"%s %d: NetlibHTTPGatewayRecv EXIT!",__FILE__,__LINE__);
+ return len;
+}
+
+int NetlibInitHttpConnection(struct NetlibConnection *nlc,struct NetlibUser *nlu,NETLIBOPENCONNECTION *nloc)
+{
+ NETLIBHTTPREQUEST nlhrSend={0},*nlhrReply=NULL;
+ NETLIBHTTPHEADER httpHeaders[3];
+
+ nlc->nlhpi.firstGetSequence=nlc->nlhpi.firstPostSequence=1;
+
+ /*
+ * Gena01 - ok we set nlhrReply to be null, also if the szHttpGatewayHello is NULL, then
+ * we don't send any requests/replies. We do have a socket open though. Could we
+ * re-use it maybe?
+ */
+ if (nlu->user.szHttpGatewayHello != NULL) {
+ nlhrSend.cbSize=sizeof(nlhrSend);
+ nlhrSend.nlc=nlc;
+ nlhrSend.requestType=REQUEST_GET;
+ nlhrSend.flags=NLHRF_GENERATEHOST|NLHRF_DUMPPROXY|NLHRF_SMARTAUTHHEADER; + if (nlc->nlhpi.flags & NLHPIF_HTTP11) nlhrSend.flags |= NLHRF_HTTP11; + + nlhrSend.szUrl=nlu->user.szHttpGatewayHello;
+ nlhrSend.headers=httpHeaders;
+ nlhrSend.headersCount=3;
+ httpHeaders[0].szName="User-Agent";
+ httpHeaders[0].szValue=nlu->user.szHttpGatewayUserAgent;
+ httpHeaders[1].szName="Cache-Control";
+ httpHeaders[1].szValue="no-store, no-cache";
+ httpHeaders[2].szName="Pragma";
+ httpHeaders[2].szValue="no-cache";
+ if(NetlibHttpSendRequest((WPARAM)nlc,(LPARAM)&nlhrSend)==SOCKET_ERROR)
+ return 0;
+
+ nlhrReply=(NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc,MSG_DUMPPROXY);
+ if(nlhrReply==NULL) return 0;
+
+ if(nlhrReply->resultCode<200 || nlhrReply->resultCode>=300) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
+ return 0;
+ }
+ }
+ if(!nlu->user.pfnHttpGatewayInit(nlc,nloc,nlhrReply)) {
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+ return 0;
+ }
+ NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
+
+ /*
+ * Gena01 - Ok, we should be able to use just POST. Needed for Yahoo, NO GET requests
+ */
+ if(nlc->nlhpi.szHttpPostUrl==NULL) {
+ SetLastError(ERROR_BAD_FORMAT);
+ return 0;
+ }
+ closesocket(nlc->s);
+ nlc->s=INVALID_SOCKET;
+
+ nlc->usingHttpGateway=1;
+
+ /* don't send anything if only using POST? */
+ if(nlc->nlhpi.szHttpGetUrl!= NULL)
+ if(!HttpGatewaySendGet(nlc))
+ return 0;
+
+ //now properly connected
+ if(nlu->user.pfnHttpGatewayBegin)
+ if(!nlu->user.pfnHttpGatewayBegin(nlc,nloc))
+ return 0;
+ return 1;
+}
+
+int NetlibHttpGatewaySetInfo(WPARAM wParam,LPARAM lParam)
+{
+ NETLIBHTTPPROXYINFO *nlhpi=(NETLIBHTTPPROXYINFO*)lParam;
+ struct NetlibConnection *nlc=(struct NetlibConnection*)wParam;
+
+ if(GetNetlibHandleType(nlc)!=NLH_CONNECTION || nlhpi==NULL || nlhpi->cbSize!=sizeof(NETLIBHTTPPROXYINFO) || nlhpi->szHttpPostUrl==NULL) {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ if(nlc->nlhpi.szHttpGetUrl) mir_free(nlc->nlhpi.szHttpGetUrl);
+ if(nlc->nlhpi.szHttpPostUrl) mir_free(nlc->nlhpi.szHttpPostUrl);
+ nlc->nlhpi=*nlhpi;
+
+ if (nlc->nlhpi.szHttpGetUrl)
+ nlc->nlhpi.szHttpGetUrl=mir_strdup(nlc->nlhpi.szHttpGetUrl);
+
+ nlc->nlhpi.szHttpPostUrl=mir_strdup(nlc->nlhpi.szHttpPostUrl);
+ return 1;
+}
+
+int NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam)
+{
+ struct NetlibUser * nu = (struct NetlibUser*)wParam;
+ if (GetNetlibHandleType(nu)!=NLH_USER) return ERROR_INVALID_PARAMETER;
+ if (nu->szStickyHeaders) { mir_free(nu->szStickyHeaders); nu->szStickyHeaders=NULL; }
+ if (lParam) {
+ nu->szStickyHeaders=mir_strdup((char*)lParam); // pointer is ours
+ }
+ return 0;
+}
+
+int NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam)
+{
+ int oldTimeout;
+ struct NetlibConnection *nlc=(struct NetlibConnection*)wParam;
+ if (GetNetlibHandleType(nlc)!=NLH_CONNECTION) return -1;
+ oldTimeout = nlc->pollingTimeout;
+ nlc->pollingTimeout = lParam;
+ return oldTimeout;
+}
|