summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2016-06-08 11:43:48 +0000
committerGeorge Hazan <george.hazan@gmail.com>2016-06-08 11:43:48 +0000
commit9e46f2867a9c84436cb7f2a0a71c45ffee041030 (patch)
treea353849407a788fc73db675c638e6231ee18b091 /src
parent3266441e7a1fe35191953f572358af1c855172b5 (diff)
fixes #1019 (infinite loop in NetlibHttpRecvChunkHeader() parser)
git-svn-id: http://svn.miranda-ng.org/main/trunk@16943 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src')
-rw-r--r--src/mir_app/src/netlib.cpp39
-rw-r--r--src/mir_app/src/netlib.h78
-rw-r--r--src/mir_app/src/netlibbind.cpp8
-rw-r--r--src/mir_app/src/netlibhttp.cpp98
-rw-r--r--src/mir_app/src/netlibhttpproxy.cpp106
-rw-r--r--src/mir_app/src/netlibopenconn.cpp57
-rw-r--r--src/mir_app/src/netlibpktrecver.cpp2
-rw-r--r--src/mir_app/src/netlibsock.cpp9
8 files changed, 221 insertions, 176 deletions
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);