From 9e46f2867a9c84436cb7f2a0a71c45ffee041030 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 8 Jun 2016 11:43:48 +0000 Subject: fixes #1019 (infinite loop in NetlibHttpRecvChunkHeader() parser) git-svn-id: http://svn.miranda-ng.org/main/trunk@16943 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/mir_app/src/netlib.cpp | 39 +++++-------- src/mir_app/src/netlib.h | 78 +++++++++++++++++++++++--- src/mir_app/src/netlibbind.cpp | 8 +-- src/mir_app/src/netlibhttp.cpp | 98 ++++++++++++++++----------------- src/mir_app/src/netlibhttpproxy.cpp | 106 ++++++++++++++++-------------------- src/mir_app/src/netlibopenconn.cpp | 57 +++++++++++-------- src/mir_app/src/netlibpktrecver.cpp | 2 +- src/mir_app/src/netlibsock.cpp | 9 ++- 8 files changed, 221 insertions(+), 176 deletions(-) (limited to 'src/mir_app') diff --git a/src/mir_app/src/netlib.cpp b/src/mir_app/src/netlib.cpp index 013795a2f4..44d7282648 100644 --- a/src/mir_app/src/netlib.cpp +++ b/src/mir_app/src/netlib.cpp @@ -266,13 +266,12 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM) mir_free(nlu->user.szHttpGatewayHello); mir_free(nlu->user.szHttpGatewayUserAgent); mir_free(nlu->szStickyHeaders); - break; } + break; + case NLH_CONNECTION: { - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - HANDLE waitHandles[4]; - DWORD waitResult; + NetlibConnection *nlc = (NetlibConnection*)wParam; WaitForSingleObject(hConnectionHeaderMutex, INFINITE); if (nlc->usingHttpGateway) @@ -280,36 +279,26 @@ INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM) else { if (nlc->s != INVALID_SOCKET) NetlibDoClose(nlc, nlc->termRequested); - if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2); + 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(_countof(waitHandles), waitHandles, TRUE, INFINITE); + HANDLE waitHandles[4] = { hConnectionHeaderMutex, nlc->hOkToCloseEvent, nlc->ncsRecv.hMutex, nlc->ncsSend.hMutex }; + DWORD waitResult = WaitForMultipleObjects(_countof(waitHandles), waitHandles, TRUE, INFINITE); if (waitResult >= WAIT_OBJECT_0 + _countof(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); + delete nlc; + + ReleaseMutex(hConnectionHeaderMutex); } - break; + return 1; case NLH_BOUNDPORT: return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam); @@ -340,10 +329,10 @@ static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM) WaitForSingleObject(hConnectionHeaderMutex, INFINITE); switch (GetNetlibHandleType((void*)wParam)) { case NLH_CONNECTION: - s = ((struct NetlibConnection*)wParam)->s; + s = ((NetlibConnection*)wParam)->s; break; case NLH_BOUNDPORT: - s = ((struct NetlibBoundPort*)wParam)->s; + s = ((NetlibBoundPort*)wParam)->s; break; default: s = INVALID_SOCKET; diff --git a/src/mir_app/src/netlib.h b/src/mir_app/src/netlib.h index 0b9bead7ad..bacad422df 100644 --- a/src/mir_app/src/netlib.h +++ b/src/mir_app/src/netlib.h @@ -64,8 +64,60 @@ typedef union _SOCKADDR_INET_M { USHORT si_family; } SOCKADDR_INET_M, *PSOCKADDR_INET_M; -struct NetlibConnection +class NetlibBinBuffer { + char *m_buf; + int m_len; + +public: + NetlibBinBuffer() : + m_buf(NULL), + m_len(0) + { + } + + ~NetlibBinBuffer() + { + mir_free(m_buf); + } + + char* data() const { return m_buf; } + bool isEmpty() const { return m_len == 0; } + int length() const { return m_len; } + + void append(void *pBuf, int bufLen) + { + m_buf = (char*)mir_realloc(m_buf, bufLen + m_len); + if (m_buf) { + memcpy(m_buf + m_len, pBuf, bufLen); + m_len += bufLen; + } + else m_len = 0; + } + + void appendBefore(void *pBuf, int bufLen) + { + m_buf = (char*)mir_realloc(m_buf, bufLen + m_len); + if (m_buf) { + memmove(m_buf + bufLen, m_buf, m_len); + memcpy(m_buf, pBuf, bufLen); + m_len += bufLen; + } + else m_len = 0; + } + + void remove(int sz) + { + memmove(m_buf, m_buf + sz, m_len - sz); + m_len -= sz; + } +}; + +struct NetlibConnection : public MZeroedObject +{ + NetlibConnection(); + ~NetlibConnection(); + int handleType; SOCKET s, s2; bool usingHttpGateway; @@ -73,23 +125,31 @@ struct NetlibConnection bool proxyAuthNeeded; bool dnsThroughProxy; bool termRequested; + NetlibUser *nlu; - NETLIBHTTPPROXYINFO nlhpi; - PBYTE dataBuffer; - int dataBufferLen; - CRITICAL_SECTION csHttpSequenceNums; + NETLIBOPENCONNECTION nloc; + + char *szNewUrl; + + mir_cs csHttpSequenceNums; HANDLE hOkToCloseEvent; LONG dontCloseNow; NetlibNestedCriticalSection ncsSend, ncsRecv; + + // SSL support HSSL hSsl; - NetlibHTTPProxyPacketQueue * pHttpProxyPacketQueue; - char *szNewUrl; + NetlibBinBuffer foreBuf; + + // proxy support + NETLIBHTTPPROXYINFO nlhpi; + NetlibHTTPProxyPacketQueue *pHttpProxyPacketQueue; + int proxyType; char *szProxyServer; WORD wProxyPort; - int proxyType; + CMStringA szProxyBuf; + int pollingTimeout; unsigned lastPost; - NETLIBOPENCONNECTION nloc; }; struct NetlibBoundPort { diff --git a/src/mir_app/src/netlibbind.cpp b/src/mir_app/src/netlibbind.cpp index 467bbae04b..7b78ee1431 100644 --- a/src/mir_app/src/netlibbind.cpp +++ b/src/mir_app/src/netlibbind.cpp @@ -160,15 +160,9 @@ static void NetlibBindAcceptThread(void* param) NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%p)", nlbp->wPort, ptrA(NetlibAddressToString(&sin)), s); - NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection)); - nlc->handleType = NLH_CONNECTION; + NetlibConnection *nlc = new NetlibConnection(); nlc->nlu = nlbp->nlu; nlc->s = s; - nlc->s2 = INVALID_SOCKET; - InitializeCriticalSection(&nlc->csHttpSequenceNums); - nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - NetlibInitializeNestedCS(&nlc->ncsSend); - NetlibInitializeNestedCS(&nlc->ncsRecv); if (nlbp->pfnNewConnectionV2) nlbp->pfnNewConnectionV2(nlc, ntohl(sin.Ipv4.sin_addr.S_un.S_addr), nlbp->pExtra); diff --git a/src/mir_app/src/netlibhttp.cpp b/src/mir_app/src/netlibhttp.cpp index e5e6e2b78d..6d985dba28 100644 --- a/src/mir_app/src/netlibhttp.cpp +++ b/src/mir_app/src/netlibhttp.cpp @@ -84,7 +84,7 @@ static int RecvWithTimeoutTime(NetlibConnection *nlc, unsigned dwTimeoutTime, ch { DWORD dwTimeNow; - if (!sslApi.pending(nlc->hSsl)) { + if (nlc->foreBuf.isEmpty() && !sslApi.pending(nlc->hSsl)) { while ((dwTimeNow = GetTickCount()) < dwTimeoutTime) { unsigned dwDeltaTime = min(dwTimeoutTime - dwTimeNow, 1000); int res = WaitUntilReadable(nlc->s, dwDeltaTime); @@ -284,7 +284,6 @@ static int HttpPeekFirstResponseLine(NetlibConnection *nlc, DWORD dwTimeoutTime, while (true) { bytesPeeked = RecvWithTimeoutTime(nlc, dwTimeoutTime, buffer, _countof(buffer) - 1, MSG_PEEK | recvFlags); - if (bytesPeeked == 0) { SetLastError(ERROR_HANDLE_EOF); return 0; @@ -370,7 +369,7 @@ static int SendHttpRequestAndData(NetlibConnection *nlc, CMStringA &httpRequest, INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam) { - NetlibConnection *nlc = (struct NetlibConnection*)wParam; + NetlibConnection *nlc = (NetlibConnection*)wParam; NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam; NETLIBHTTPREQUEST *nlhrReply = NULL; HttpSecurityContext httpSecurity; @@ -509,12 +508,12 @@ INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam) if (nlu->szStickyHeaders != NULL) httpRequest.AppendFormat("%s\r\n", nlu->szStickyHeaders); - //send it + // send it bytesSent = SendHttpRequestAndData(nlc, httpRequest, nlhr, !doneContentLengthHeader); if (bytesSent == SOCKET_ERROR) break; - //ntlm reply + // ntlm reply if (doneContentLengthHeader && nlhr->requestType != REQUEST_HEAD) break; @@ -717,15 +716,14 @@ INT_PTR NetlibHttpFreeRequestStruct(WPARAM, LPARAM lParam) return 1; } +#define NHRV_BUF_SIZE 8192 + INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam) { - NetlibConnection *nlc = (struct NetlibConnection*)wParam; + NetlibConnection *nlc = (NetlibConnection*)wParam; if (!NetlibEnterNestedCS(nlc, NLNCS_RECV)) return 0; - char *peol, *pbuffer; - int headersCount = 0, bufferSize = 8192; - DWORD dwRequestTimeoutTime = GetTickCount() + HTTPRECVDATATIMEOUT; NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST)); nlhr->cbSize = sizeof(NETLIBHTTPREQUEST); @@ -739,30 +737,22 @@ INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam) return 0; } - char *buffer = (char*)mir_alloc(bufferSize + 1); - int bytesPeeked = NLRecv(nlc, buffer, min(firstLineLength, bufferSize), lParam | MSG_DUMPASTEXT); + char *buffer = (char*)_alloca(NHRV_BUF_SIZE + 1); + int bytesPeeked = NLRecv(nlc, buffer, min(firstLineLength, NHRV_BUF_SIZE), lParam | MSG_DUMPASTEXT); if (bytesPeeked != firstLineLength) { NetlibLeaveNestedCS(&nlc->ncsRecv); NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); - if (bytesPeeked != SOCKET_ERROR) SetLastError(ERROR_HANDLE_EOF); - mir_free(buffer); + if (bytesPeeked != SOCKET_ERROR) + SetLastError(ERROR_HANDLE_EOF); return 0; } // Make sure all headers arrived + NetlibBinBuffer buf; + int headersCount = 0; bytesPeeked = 0; for (bool headersCompleted = false; !headersCompleted;) { - if (bytesPeeked >= bufferSize) { - bufferSize += 8192; - mir_free(buffer); - if (bufferSize > 32 * 1024) { - bytesPeeked = 0; - break; - } - buffer = (char*)mir_alloc(bufferSize + 1); - } - - bytesPeeked = RecvWithTimeoutTime(nlc, dwRequestTimeoutTime, buffer, bufferSize, MSG_PEEK | MSG_NODUMP | lParam); + bytesPeeked = RecvWithTimeoutTime(nlc, dwRequestTimeoutTime, buffer, NHRV_BUF_SIZE, lParam | MSG_DUMPASTEXT); if (bytesPeeked == 0) break; @@ -770,36 +760,37 @@ INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam) bytesPeeked = 0; break; } - buffer[bytesPeeked] = 0; + + buf.append(buffer, bytesPeeked); - for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) { - peol = strchr(pbuffer, '\n'); + headersCount = 0; + for (char *pbuffer = (char*)buf.data();; headersCount++) { + char *peol = strchr(pbuffer, '\n'); if (peol == NULL) break; if (peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) { - bytesPeeked = peol - buffer + 1; + bytesPeeked = peol - (char*)buf.data() + 1; headersCompleted = true; break; } + pbuffer = peol + 1; } } // Receive headers - if (bytesPeeked > 0) - bytesPeeked = NLRecv(nlc, buffer, bytesPeeked, lParam | MSG_DUMPASTEXT); if (bytesPeeked <= 0) { NetlibLeaveNestedCS(&nlc->ncsRecv); NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); - mir_free(buffer); return 0; } - buffer[bytesPeeked] = 0; nlhr->headersCount = headersCount; nlhr->headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER) * headersCount); - for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) { - peol = strchr(pbuffer, '\n'); - if (peol == NULL || peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) break; + headersCount = 0; + for (char *pbuffer = buf.data();; headersCount++) { + char *peol = strchr(pbuffer, '\n'); + if (peol == NULL || peol == pbuffer || (peol == (pbuffer+1) && *pbuffer == '\r')) + break; *peol = 0; char *pColon = strchr(pbuffer, ':'); @@ -809,13 +800,19 @@ INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam) break; } - *(pColon++) = 0; + *pColon = 0; nlhr->headers[headersCount].szName = mir_strdup(rtrim(pbuffer)); - nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon)); + nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon+1)); + pbuffer = peol + 1; + } + + // remove processed data + if (bytesPeeked > 0) { + buf.remove(bytesPeeked); + nlc->foreBuf.appendBefore(buf.data(), buf.length()); } NetlibLeaveNestedCS(&nlc->ncsRecv); - mir_free(buffer); return (INT_PTR)nlhr; } @@ -973,31 +970,34 @@ char* gzip_decode(char *gzip_data, int *len_ptr, int window) static int NetlibHttpRecvChunkHeader(NetlibConnection *nlc, bool first, DWORD flags) { - char data[1000]; + NetlibBinBuffer buf; while (true) { - int recvResult = NLRecv(nlc, data, _countof(data)-1, MSG_RAW | MSG_PEEK); + char data[1000]; + int recvResult = NLRecv(nlc, data, _countof(data) - 1, MSG_RAW | flags); if (recvResult <= 0 || recvResult >= _countof(data)) return SOCKET_ERROR; - data[recvResult] = 0; + buf.append(data, recvResult); // add chunk - char *peol1 = strchr(data, '\n'); + char *peol1 = strchr(buf.data(), '\n'); if (peol1 == NULL) continue; - char *peol2 = first ? peol1 : strchr(peol1 + 1, '\n'); + const char *peol2 = first ? peol1 : strchr(peol1 + 1, '\n'); if (peol2 == NULL) continue; - int sz = peol2 - data + 1; - int r = strtol(first ? data : peol1 + 1, NULL, 16); + int sz = peol2 - buf.data() + 1; + int r = strtol(first ? buf.data() : peol1 + 1, NULL, 16); if (r == 0) { - char *peol3 = strchr(peol2 + 1, '\n'); - if (peol3 == NULL) continue; - sz = peol3 - data + 1; + const char *peol3 = strchr(peol2 + 1, '\n'); + if (peol3 == NULL) + continue; + sz = peol3 - buf.data() + 1; } - NLRecv(nlc, data, sz, MSG_RAW | flags); + buf.remove(sz); // remove all our data from buffer + nlc->foreBuf.appendBefore(buf.data(), buf.length()); return r; } } diff --git a/src/mir_app/src/netlibhttpproxy.cpp b/src/mir_app/src/netlibhttpproxy.cpp index f5216d1b38..4f1caf3f2b 100644 --- a/src/mir_app/src/netlibhttpproxy.cpp +++ b/src/mir_app/src/netlibhttpproxy.cpp @@ -36,16 +36,13 @@ RequestType; static int HttpGatewayReadSetResult(NetlibConnection *nlc, char *buf, int num, int peek) { - if (nlc->dataBufferLen == 0) return 0; + if (nlc->szProxyBuf.GetLength() == 0) return 0; - int bytes = min(num, nlc->dataBufferLen); - int rbytes = nlc->dataBufferLen - bytes; + int bytes = min(num, nlc->szProxyBuf.GetLength()); - memcpy(buf, nlc->dataBuffer, bytes); - if (!peek) { - memmove(nlc->dataBuffer, nlc->dataBuffer + bytes, rbytes); - nlc->dataBufferLen = rbytes; - } + memcpy(buf, nlc->szProxyBuf, bytes); + if (!peek) + nlc->szProxyBuf.Delete(0, bytes); return bytes; } @@ -165,26 +162,24 @@ static bool NetlibHttpGatewayStdPost(NetlibConnection *nlc, int &numPackets) static bool NetlibHttpGatewayOscarPost(NetlibConnection *nlc, const char *buf, int len, int flags) { - NetlibConnection nlcSend = { 0 }; - nlcSend.handleType = NLH_CONNECTION; - nlcSend.nlu = nlc->nlu; - nlcSend.nlhpi = nlc->nlhpi; - nlcSend.s = nlc->s2; - nlcSend.usingHttpGateway = nlc->usingHttpGateway; - nlcSend.szProxyServer = nlc->szProxyServer; - nlcSend.wProxyPort = nlc->wProxyPort; - nlcSend.proxyType = nlc->proxyType; - - if (!NetlibReconnect(&nlcSend)) return false; - nlc->s2 = nlcSend.s; - - nlcSend.hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - NetlibInitializeNestedCS(&nlcSend.ncsRecv); - NetlibInitializeNestedCS(&nlcSend.ncsSend); - - bool res = NetlibHttpGatewaySend(&nlcSend, reqOldPost, buf, len); + NetlibConnection *nlcSend = new NetlibConnection(); + nlcSend->nlu = nlc->nlu; + nlcSend->nlhpi = nlc->nlhpi; + nlcSend->s = nlc->s2; + nlcSend->usingHttpGateway = nlc->usingHttpGateway; + nlcSend->szProxyServer = nlc->szProxyServer; + nlcSend->wProxyPort = nlc->wProxyPort; + nlcSend->proxyType = nlc->proxyType; + if (!NetlibReconnect(nlcSend)) { + delete nlcSend; + return false; + } + + nlc->s2 = nlcSend->s; + + bool res = NetlibHttpGatewaySend(nlcSend, reqOldPost, buf, len); if (res) { - NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(&nlcSend, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY); + NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlcSend, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY); if (nlhrReply != NULL) { if (nlhrReply->resultCode != 200) { NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode); @@ -195,12 +190,8 @@ static bool NetlibHttpGatewayOscarPost(NetlibConnection *nlc, const char *buf, i else res = false; } - NetlibDeleteNestedCS(&nlcSend.ncsSend); - NetlibDeleteNestedCS(&nlcSend.ncsRecv); - CloseHandle(nlcSend.hOkToCloseEvent); - - nlc->s2 = nlcSend.s; - mir_free((char*)nlcSend.nloc.szHost); + nlc->s2 = nlcSend->s; + delete nlcSend; mir_cslock lck(nlc->csHttpSequenceNums); nlc->nlhpi.firstPostSequence++; @@ -259,7 +250,7 @@ int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags) { bool peek = (flags & MSG_PEEK) != 0; - if (nlc->dataBufferLen != 0 && (!peek || nlc->dataBufferLen >= len)) + if (nlc->szProxyBuf.GetLength() != 0 && (!peek || nlc->szProxyBuf.GetLength() >= len)) return HttpGatewayReadSetResult(nlc, buf, len, peek); NetlibUser *nlu = nlc->nlu; @@ -332,32 +323,25 @@ int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags) 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; - + nlc->szProxyBuf.Append(nlhrReply->pData, nlhrReply->dataLength); 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); + int bytes = min(len, nlhrReply->dataLength); - nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes); - if (rbytes) memcpy(nlc->dataBuffer, nlhrReply->pData + bytes, rbytes); - nlc->dataBufferLen = rbytes; + memcpy(buf, nlhrReply->pData, bytes); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return bytes; - } + if (nlhrReply->dataLength > bytes) + nlc->szProxyBuf.SetString(nlhrReply->pData + bytes, nlhrReply->dataLength - bytes); + else + nlc->szProxyBuf.Empty(); + + NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); + return bytes; } else { - if ((peek && nlc->dataBufferLen != 0) || nlhrReply->pData) { + if ((peek && nlc->szProxyBuf.GetLength() != 0) || nlhrReply->pData) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return HttpGatewayReadSetResult(nlc, buf, len, peek); } @@ -417,7 +401,7 @@ int NetlibInitHttpConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENC INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam) { NETLIBHTTPPROXYINFO *nlhpi = (NETLIBHTTPPROXYINFO*)lParam; - NetlibConnection *nlc = (struct NetlibConnection*)wParam; + NetlibConnection *nlc = (NetlibConnection*)wParam; if (GetNetlibHandleType(nlc) != NLH_CONNECTION || nlhpi == NULL || nlhpi->cbSize < (sizeof(NETLIBHTTPPROXYINFO) - sizeof(int)) || @@ -436,24 +420,26 @@ INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam) nlc->nlhpi.szHttpGetUrl = mir_strdup(nlc->nlhpi.szHttpGetUrl); nlc->nlhpi.szHttpPostUrl = mir_strdup(nlc->nlhpi.szHttpPostUrl); - return 1; } INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam) { - NetlibUser * nu = (NetlibUser*)wParam; - if (GetNetlibHandleType(nu) != NLH_USER) return ERROR_INVALID_PARAMETER; + NetlibUser *nu = (NetlibUser*)wParam; + if (GetNetlibHandleType(nu) != NLH_USER) + return ERROR_INVALID_PARAMETER; + replaceStr(nu->szStickyHeaders, (char*)lParam); // pointer is ours return 0; } INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam) { - int oldTimeout; - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - if (GetNetlibHandleType(nlc) != NLH_CONNECTION) return -1; - oldTimeout = nlc->pollingTimeout; + NetlibConnection *nlc = (NetlibConnection*)wParam; + if (GetNetlibHandleType(nlc) != NLH_CONNECTION) + return -1; + + int oldTimeout = nlc->pollingTimeout; nlc->pollingTimeout = lParam; return oldTimeout; } diff --git a/src/mir_app/src/netlibopenconn.cpp b/src/mir_app/src/netlibopenconn.cpp index 103f7eda20..0dd4312c59 100644 --- a/src/mir_app/src/netlibopenconn.cpp +++ b/src/mir_app/src/netlibopenconn.cpp @@ -342,19 +342,9 @@ static void FreePartiallyInitedConnection(NetlibConnection *nlc) { DWORD dwOriginalLastError = GetLastError(); - if (GetNetlibHandleType(nlc) == NLH_CONNECTION) { - if (nlc->s != INVALID_SOCKET) - closesocket(nlc->s); - mir_free(nlc->nlhpi.szHttpPostUrl); - mir_free(nlc->nlhpi.szHttpGetUrl); - mir_free((char*)nlc->nloc.szHost); - mir_free(nlc->szProxyServer); - NetlibDeleteNestedCS(&nlc->ncsSend); - NetlibDeleteNestedCS(&nlc->ncsRecv); - CloseHandle(nlc->hOkToCloseEvent); - DeleteCriticalSection(&nlc->csHttpSequenceNums); - mir_free(nlc); - } + if (GetNetlibHandleType(nlc) == NLH_CONNECTION) + delete nlc; + SetLastError(dwOriginalLastError); } @@ -840,21 +830,12 @@ INT_PTR NetlibOpenConnection(WPARAM wParam, LPARAM lParam) NetlibLogf(nlu, "Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags); - NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(struct NetlibConnection)); - nlc->handleType = NLH_CONNECTION; + NetlibConnection *nlc = new NetlibConnection(); 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; @@ -890,3 +871,33 @@ INT_PTR NetlibStartSsl(WPARAM wParam, LPARAM lParam) return nlc->hSsl != NULL; } + +NetlibConnection::NetlibConnection() +{ + handleType = NLH_CONNECTION; + s = s2 = INVALID_SOCKET; + hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + NetlibInitializeNestedCS(&ncsSend); + NetlibInitializeNestedCS(&ncsRecv); +} + +NetlibConnection::~NetlibConnection() +{ + handleType = 0; + + if (s != INVALID_SOCKET) + closesocket(s); + + mir_free(szNewUrl); + mir_free(szProxyServer); + + mir_free(nlhpi.szHttpPostUrl); + mir_free(nlhpi.szHttpGetUrl); + + mir_free((char*)nloc.szHost); + + NetlibDeleteNestedCS(&ncsSend); + NetlibDeleteNestedCS(&ncsRecv); + + CloseHandle(hOkToCloseEvent); +} diff --git a/src/mir_app/src/netlibpktrecver.cpp b/src/mir_app/src/netlibpktrecver.cpp index d9fd28c9a8..4383ba841f 100644 --- a/src/mir_app/src/netlibpktrecver.cpp +++ b/src/mir_app/src/netlibpktrecver.cpp @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam) { - NetlibConnection *nlc = (struct NetlibConnection*)wParam; + NetlibConnection *nlc = (NetlibConnection*)wParam; struct NetlibPacketRecver *nlpr; if (GetNetlibHandleType(nlc) != NLH_CONNECTION || lParam == 0) { diff --git a/src/mir_app/src/netlibsock.cpp b/src/mir_app/src/netlibsock.cpp index 3c47336ef3..58a0857d12 100644 --- a/src/mir_app/src/netlibsock.cpp +++ b/src/mir_app/src/netlibsock.cpp @@ -79,7 +79,12 @@ INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam) if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW)) recvResult = NetlibHttpGatewayRecv(nlc, nlb->buf, nlb->len, nlb->flags); else { - if (nlc->hSsl) + if (!nlc->foreBuf.isEmpty()) { + recvResult = min(nlb->len, nlc->foreBuf.length()); + memcpy(nlb->buf, nlc->foreBuf.data(), recvResult); + nlc->foreBuf.remove(recvResult); + } + else if (nlc->hSsl) recvResult = sslApi.read(nlc->hSsl, nlb->buf, nlb->len, (nlb->flags & MSG_PEEK) != 0); else recvResult = recv(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF); @@ -180,7 +185,7 @@ INT_PTR NetlibSelectEx(WPARAM, LPARAM lParam) if (sslApi.pending(conn->hSsl)) nls->hReadStatus[j] = TRUE; - if (conn->usingHttpGateway && conn->nlhpi.szHttpGetUrl == NULL && conn->dataBuffer == NULL) + if (conn->usingHttpGateway && conn->nlhpi.szHttpGetUrl == NULL && conn->szProxyBuf.IsEmpty()) nls->hReadStatus[j] = (conn->pHttpProxyPacketQueue != NULL); else nls->hReadStatus[j] = FD_ISSET(conn->s, &readfd); -- cgit v1.2.3