static NetlibConnection* NetlibHttpProcessUrl(NETLIBHTTPREQUEST *nlhr, NetlibUser *nlu, NetlibConnection *nlc, const char *szUrl = NULL) { NETLIBOPENCONNECTION nloc; if (szUrl == NULL) NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, nloc); else NetlibConnFromUrl(szUrl, false, nloc); nloc.flags |= NLOCF_HTTP; if (nloc.flags & NLOCF_SSL) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL; if (nlc != NULL) { bool httpProxy = !(nloc.flags & NLOCF_SSL) && nlc->proxyType == PROXYTYPE_HTTP; bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort; if (!httpProxy && !sameHost) { NetlibDoClose(nlc); mir_free((char*)nlc->nloc.szHost); nlc->nloc = nloc; return NetlibDoConnect(nlc) ? nlc : NULL; } } else nlc = (NetlibConnection*)NetlibOpenConnection((WPARAM)nlu, (LPARAM)&nloc); mir_free((char*)nloc.szHost); return nlc; }
bool NetlibReconnect(NetlibConnection *nlc) { char buf[4]; bool opened = nlc->s != INVALID_SOCKET; if (opened) { switch (WaitUntilReadable(nlc->s, 0, true)) { case SOCKET_ERROR: opened = false; break; case 0: opened = true; break; case 1: opened = recv(nlc->s, buf, 1, MSG_PEEK) > 0; break; } if (!opened) NetlibDoClose(nlc, true); } if (!opened) { if (Miranda_Terminated()) return false; if (nlc->usingHttpGateway) { nlc->proxyAuthNeeded = true; return my_connect(nlc, &nlc->nloc); } return NetlibDoConnect(nlc); } return true; }
INT_PTR NetlibOpenConnection(WPARAM wParam,LPARAM lParam) { NETLIBOPENCONNECTION *nloc = (NETLIBOPENCONNECTION*)lParam; struct NetlibUser *nlu = (struct NetlibUser*)wParam; struct NetlibConnection *nlc; NetlibLogf(nlu,"Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags); if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) || nloc == NULL || (nloc->cbSize != NETLIBOPENCONNECTION_V1_SIZE && nloc->cbSize != sizeof(NETLIBOPENCONNECTION)) || nloc->szHost == NULL || nloc->wPort == 0) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } nlc = (struct NetlibConnection*)mir_calloc(sizeof(struct NetlibConnection)); nlc->handleType = NLH_CONNECTION; nlc->nlu = nlu; nlc->nloc = *nloc; nlc->nloc.szHost = mir_strdup(nloc->szHost); nlc->s = INVALID_SOCKET; nlc->s2 = INVALID_SOCKET; nlc->dnsThroughProxy = nlu->settings.dnsThroughProxy != 0; InitializeCriticalSection(&nlc->csHttpSequenceNums); nlc->hOkToCloseEvent = CreateEvent(NULL,TRUE,TRUE,NULL); nlc->dontCloseNow = 0; NetlibInitializeNestedCS(&nlc->ncsSend); NetlibInitializeNestedCS(&nlc->ncsRecv); if (!NetlibDoConnect(nlc)) { FreePartiallyInitedConnection(nlc); return 0; } if (iUPnPCleanup == 0) { EnterCriticalSection(&csNetlibUser); if (iUPnPCleanup == 0) { iUPnPCleanup = 1; forkthread(NetlibUPnPCleanup, 0, NULL); } LeaveCriticalSection(&csNetlibUser); } return (INT_PTR)nlc; }
static bool NetlibHttpGatewaySend(NetlibConnection *nlc, RequestType reqType, const char *buf, int len) { NETLIBHTTPREQUEST nlhrSend = {0}; char szUrl[512]; nlhrSend.cbSize = sizeof(nlhrSend); nlhrSend.nlc = nlc; nlhrSend.pData = (char*)buf; nlhrSend.dataLength = len; nlhrSend.flags = NLHRF_GENERATEHOST | NLHRF_DUMPPROXY | NLHRF_SMARTAUTHHEADER | NLHRF_NOPROXY | NLHRF_REDIRECT; if (nlc->nlhpi.flags & NLHPIF_HTTP11) nlhrSend.flags |= NLHRF_HTTP11; switch (reqType) { case reqHelloGet: nlhrSend.requestType = REQUEST_GET; nlhrSend.szUrl = nlc->nlu->user.szHttpGatewayHello; break; case reqOldGet: nlhrSend.requestType = REQUEST_GET; nlhrSend.timeout = -1; if ((nlc->nlhpi.flags & NLHPIF_USEGETSEQUENCE) && (nlc->nlhpi.szHttpGetUrl != NULL)) { mir_cslock lck(nlc->csHttpSequenceNums); mir_snprintf(szUrl, SIZEOF(szUrl), "%s%u", nlc->nlhpi.szHttpGetUrl, nlc->nlhpi.firstGetSequence++); if (nlc->nlhpi.flags & NLHPIF_GETPOSTSAMESEQUENCE) nlc->nlhpi.firstPostSequence++; nlhrSend.szUrl = szUrl; } else nlhrSend.szUrl = nlc->nlhpi.szHttpGetUrl; break; case reqOldPost: nlhrSend.requestType = REQUEST_POST; if ((nlc->nlhpi.flags & NLHPIF_USEPOSTSEQUENCE) && (nlc->nlhpi.szHttpPostUrl != NULL)) { mir_snprintf(szUrl, SIZEOF(szUrl), "%s%u", nlc->nlhpi.szHttpPostUrl, nlc->nlhpi.firstPostSequence); nlhrSend.szUrl = szUrl; } else nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl; break; case reqNewPost: nlhrSend.requestType = REQUEST_POST; nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl; break; } if (nlc->usingDirectHttpGateway) { NETLIBOPENCONNECTION nloc; NetlibConnFromUrl(nlhrSend.szUrl, false, nloc); bool sameHost = lstrcmpA(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort; if (!sameHost) { NetlibDoClose(nlc); mir_free((char*)nlc->nloc.szHost); nlc->nloc = nloc; if (!NetlibDoConnect(nlc)) return false; } else mir_free((char*)nloc.szHost); } nlhrSend.headersCount = 3; nlhrSend.headers = (NETLIBHTTPHEADER*)alloca(sizeof(NETLIBHTTPHEADER) * nlhrSend.headersCount); nlhrSend.headers[0].szName = "User-Agent"; nlhrSend.headers[0].szValue = nlc->nlu->user.szHttpGatewayUserAgent; nlhrSend.headers[1].szName = "Cache-Control"; nlhrSend.headers[1].szValue = "no-cache, no-store "; nlhrSend.headers[2].szName = "Pragma"; nlhrSend.headers[2].szValue = "no-cache"; // nlhrSend.headers[3].szName = "Accept-Encoding"; // nlhrSend.headers[3].szValue = "deflate, gzip"; return NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) != SOCKET_ERROR; }