INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM) { switch(GetNetlibHandleType(wParam)) { case NLH_USER: { struct NetlibUser *nlu=(struct NetlibUser*)wParam; int i; EnterCriticalSection(&csNetlibUser); i = netlibUser.getIndex(nlu); if (i >= 0) netlibUser.remove(i); LeaveCriticalSection(&csNetlibUser); NetlibFreeUserSettingsStruct(&nlu->settings); mir_free(nlu->user.szSettingsModule); mir_free(nlu->user.szDescriptiveName); mir_free(nlu->user.szHttpGatewayHello); mir_free(nlu->user.szHttpGatewayUserAgent); mir_free(nlu->szStickyHeaders); break; } case NLH_CONNECTION: { struct NetlibConnection *nlc=(struct NetlibConnection*)wParam; HANDLE waitHandles[4]; DWORD waitResult; WaitForSingleObject(hConnectionHeaderMutex,INFINITE); if (nlc->usingHttpGateway) { HttpGatewayRemovePacket(nlc, -1); } else { if(nlc->s != INVALID_SOCKET) { NetlibDoClose(nlc); } if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2); nlc->s2 = INVALID_SOCKET; } ReleaseMutex(hConnectionHeaderMutex); waitHandles[0]=hConnectionHeaderMutex; waitHandles[1]=nlc->hOkToCloseEvent; waitHandles[2]=nlc->ncsRecv.hMutex; waitHandles[3]=nlc->ncsSend.hMutex; waitResult=WaitForMultipleObjects( SIZEOF(waitHandles),waitHandles,TRUE,INFINITE); if(waitResult<WAIT_OBJECT_0 || waitResult >= WAIT_OBJECT_0 + SIZEOF(waitHandles)) { ReleaseMutex(hConnectionHeaderMutex); SetLastError(ERROR_INVALID_PARAMETER); //already been closed return 0; } nlc->handleType=0; mir_free(nlc->nlhpi.szHttpPostUrl); mir_free(nlc->nlhpi.szHttpGetUrl); mir_free(nlc->dataBuffer); mir_free((char*)nlc->nloc.szHost); mir_free(nlc->szNewUrl); mir_free(nlc->szProxyServer); NetlibDeleteNestedCS(&nlc->ncsRecv); NetlibDeleteNestedCS(&nlc->ncsSend); CloseHandle(nlc->hOkToCloseEvent); DeleteCriticalSection(&nlc->csHttpSequenceNums); ReleaseMutex(hConnectionHeaderMutex); NetlibLogf(nlc->nlu,"(%p:%u) Connection closed",nlc,nlc->s); break; } case NLH_BOUNDPORT: return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam); case NLH_PACKETRECVER: { struct NetlibPacketRecver *nlpr=(struct NetlibPacketRecver*)wParam; mir_free(nlpr->packetRecver.buffer); break; } default: SetLastError(ERROR_INVALID_PARAMETER); return 0; } mir_free((void*)wParam); return 1; }
int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags) { bool peek = (flags & MSG_PEEK) != 0; if (nlc->dataBufferLen != 0 && (!peek || nlc->dataBufferLen >= len)) { return HttpGatewayReadSetResult(nlc, buf, len, peek); } for (int retryCount = 0; retryCount < NETLIBHTTP_RETRYCOUNT;) { if (nlc->nlhpi.szHttpGetUrl == NULL && retryCount == 0) { if (nlc->pollingTimeout == 0) nlc->pollingTimeout = 30; /* We Need to sleep/wait for the data to send before we do receive */ for (int pollCount = nlc->pollingTimeout; pollCount--;) { if (nlc->pHttpProxyPacketQueue != NULL && GetTickCount() - nlc->lastPost > 1000) break; if (nlc->termRequested || (SleepEx(1000, TRUE) && Miranda_Terminated())) return SOCKET_ERROR; } nlc->lastPost = GetTickCount(); if (nlc->pHttpProxyPacketQueue == NULL && nlc->nlu->user.pfnHttpGatewayWrapSend != NULL) { if (nlc->nlu->user.pfnHttpGatewayWrapSend(nlc, (PBYTE)"", 0, MSG_NOHTTPGATEWAYWRAP, NetlibSend) == SOCKET_ERROR) return SOCKET_ERROR; } } int numPackets = 0; if (nlc->nlhpi.szHttpGetUrl) { if (!NetlibHttpGatewaySend(nlc, reqOldGet, NULL, 0)) { if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested) break; ++retryCount; continue; } } else { if (!NetlibHttpGatewayStdPost(nlc, numPackets)) { if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested) break; ++retryCount; continue; } } NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY); if (nlhrReply == NULL) return SOCKET_ERROR; if (nlc->nlu->user.pfnHttpGatewayUnwrapRecv && !(flags & MSG_NOHTTPGATEWAYWRAP)) { nlhrReply->pData = (char*)nlc->nlu->user.pfnHttpGatewayUnwrapRecv(nlhrReply, (PBYTE)nlhrReply->pData, nlhrReply->dataLength, &nlhrReply->dataLength, mir_realloc); } if (nlhrReply->resultCode >= 300) { int resultCode = nlhrReply->resultCode; NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); if (nlc->nlhpi.szHttpGetUrl && resultCode != 404) { NetlibLogf(nlc->nlu, "Error received from proxy, retrying"); continue; } else { NetlibLogf(nlc->nlu, "Error received from proxy, retry attempts exceeded (%u)", retryCount); SetLastError(ERROR_GEN_FAILURE); return SOCKET_ERROR; } } else { retryCount = 0; HttpGatewayRemovePacket(nlc, numPackets); } if (nlhrReply->dataLength) { if (peek) { int rbytes = nlc->dataBufferLen + nlhrReply->dataLength; nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes); memcpy(nlc->dataBuffer + nlc->dataBufferLen, nlhrReply->pData, nlhrReply->dataLength); nlc->dataBufferLen = rbytes; NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return HttpGatewayReadSetResult(nlc, buf, len, peek); } else { int bytes = min(len, nlhrReply->dataLength); int rbytes = nlhrReply->dataLength - bytes; memcpy(buf, nlhrReply->pData, bytes); nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes); if (rbytes) memcpy(nlc->dataBuffer, nlhrReply->pData + bytes, rbytes); nlc->dataBufferLen = rbytes; NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return bytes; } } else { if ((peek && nlc->dataBufferLen != 0) || nlhrReply->pData) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return HttpGatewayReadSetResult(nlc, buf, len, peek); } } NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); } SetLastError(ERROR_GEN_FAILURE); return SOCKET_ERROR; }