diff options
-rw-r--r-- | plugins/OpenSSL/src/ssl_openssl.cpp | 78 | ||||
-rw-r--r-- | src/mir_app/src/netlib.cpp | 39 | ||||
-rw-r--r-- | src/mir_app/src/netlib.h | 78 | ||||
-rw-r--r-- | src/mir_app/src/netlibbind.cpp | 8 | ||||
-rw-r--r-- | src/mir_app/src/netlibhttp.cpp | 98 | ||||
-rw-r--r-- | src/mir_app/src/netlibhttpproxy.cpp | 106 | ||||
-rw-r--r-- | src/mir_app/src/netlibopenconn.cpp | 57 | ||||
-rw-r--r-- | src/mir_app/src/netlibpktrecver.cpp | 2 | ||||
-rw-r--r-- | src/mir_app/src/netlibsock.cpp | 9 |
9 files changed, 257 insertions, 218 deletions
diff --git a/plugins/OpenSSL/src/ssl_openssl.cpp b/plugins/OpenSSL/src/ssl_openssl.cpp index c8071b7aac..d9bcdbd89b 100644 --- a/plugins/OpenSSL/src/ssl_openssl.cpp +++ b/plugins/OpenSSL/src/ssl_openssl.cpp @@ -35,8 +35,16 @@ enum SocketState sockError }; -struct SslHandle +struct SslHandle : public MZeroedObject { + ~SslHandle() + { + if (session) + SSL_free(session); + if (ctx) + SSL_CTX_free(ctx); + } + SOCKET s; SSL_CTX *ctx; SSL *session; @@ -46,7 +54,8 @@ struct SslHandle static void SSL_library_unload(void) { /* Load Library Pointers */ - if (!bSslInitDone) return; + if (!bSslInitDone) + return; WaitForSingleObject(g_hSslMutex, INFINITE); @@ -66,7 +75,8 @@ static void SSL_library_unload(void) static bool SSL_library_load(void) { /* Load Library Pointers */ - if (bSslInitDone) return true; + if (bSslInitDone) + return true; WaitForSingleObject(g_hSslMutex, INFINITE); @@ -74,8 +84,7 @@ static bool SSL_library_load(void) g_hOpenSSLCrypto = LoadLibraryA("libeay32.dll"); g_hOpenSSL = LoadLibraryA("ssleay32.dll"); g_hWinCrypt = LoadLibraryA("crypt32.dll"); - if (g_hOpenSSL && g_hOpenSSLCrypto && g_hWinCrypt) - { + if (g_hOpenSSL && g_hOpenSSLCrypto && g_hWinCrypt) { // init OpenSSL SSL_library_init(); SSL_load_error_strings(); @@ -84,9 +93,7 @@ static bool SSL_library_load(void) bSslInitDone = true; } - else { - SSL_library_unload(); - } + else SSL_library_unload(); } return bSslInitDone; @@ -132,15 +139,7 @@ static void ReportSslError(SECURITY_STATUS scRet, int line, bool = false) void NetlibSslFree(SslHandle *ssl) { - if (ssl == NULL) return; - - /* Delete Context */ - if (ssl->session) - SSL_free(ssl->session); - if (ssl->ctx) - SSL_CTX_free(ssl->ctx); - - mir_free(ssl); + delete ssl; } BOOL NetlibSslPending(HSSL ssl) @@ -185,7 +184,7 @@ static bool ClientConnect(SslHandle *ssl, const char*) return false; } - const char* suite = SSL_GetCipherName(ssl); + const char *suite = SSL_GetCipherName(ssl); if (suite != NULL) Netlib_Logf(0, "SSL established with %s", suite); return true; @@ -193,11 +192,10 @@ static bool ClientConnect(SslHandle *ssl, const char*) static PCCERT_CONTEXT SSL_X509ToCryptCert(X509 * x509) { - int len; - unsigned char * buf = NULL; + unsigned char *buf = NULL; PCCERT_CONTEXT pCertContext = NULL; - len = i2d_X509(x509, &buf); + int len = i2d_X509(x509, &buf); if ((len >= 0) && buf) { pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, buf, len); @@ -210,7 +208,7 @@ static PCCERT_CONTEXT SSL_CertChainToCryptAnchor(SSL* session) { /* convert the active certificate chain provided in the handshake of 'session' into the format used by CryptAPI. - */ + */ PCCERT_CONTEXT anchor = NULL; // create cert store HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); @@ -225,10 +223,8 @@ static PCCERT_CONTEXT SSL_CertChainToCryptAnchor(SSL* session) // add all remaining certs to store (note: stack needs not be freed, it is not a copy) STACK_OF(X509) *server_chain = SSL_get_peer_cert_chain(session); if (server_chain) { - X509 *next_cert; - int i; - for (i = 0; i < server_chain->stack.num; i++) { - next_cert = (X509 *)server_chain->stack.data[i]; + for (int i = 0; i < server_chain->stack.num; i++) { + X509 *next_cert = (X509 *)server_chain->stack.data[i]; CertAddCertificateContextToStore(store, SSL_X509ToCryptCert(next_cert), CERT_STORE_ADD_USE_EXISTING, NULL); } } @@ -237,7 +233,8 @@ static PCCERT_CONTEXT SSL_CertChainToCryptAnchor(SSL* session) anchor = primary_cert; } else { - if (primary_cert) CertFreeCertificateContext(primary_cert); + if (primary_cert) + CertFreeCertificateContext(primary_cert); } X509_free(server_cert); @@ -322,8 +319,8 @@ cleanup: SslHandle* NetlibSslConnect(SOCKET s, const char* host, int verify) { /* negotiate SSL session, verify cert, return NULL if failed */ - - SslHandle *ssl = (SslHandle*)mir_calloc(sizeof(SslHandle)); + + SslHandle *ssl = new SslHandle(); ssl->s = s; bool res = ClientConnect(ssl, host); @@ -337,7 +334,7 @@ SslHandle* NetlibSslConnect(SOCKET s, const char* host, int verify) if (res) return ssl; - NetlibSslFree(ssl); + delete ssl; return NULL; } @@ -364,17 +361,15 @@ int NetlibSslRead(SslHandle *ssl, char *buf, int num, int peek) if (err <= 0) { int err2 = SSL_get_error(ssl->session, err); - switch (err2) { - case SSL_ERROR_ZERO_RETURN: + if (err2 == SSL_ERROR_ZERO_RETURN) { Netlib_Logf(0, "SSL connection gracefully closed"); ssl->state = sockClosed; - break; - default: - Netlib_Logf(0, "SSL failure recieving data (%d, %d, %d)", err, err2, WSAGetLastError()); - ssl->state = sockError; - return SOCKET_ERROR; + return 0; } - return 0; + + Netlib_Logf(0, "SSL failure recieving data (%d, %d, %d)", err, err2, WSAGetLastError()); + ssl->state = sockError; + return SOCKET_ERROR; } return err; @@ -389,7 +384,7 @@ int NetlibSslWrite(SslHandle *ssl, const char *buf, int num) int err = SSL_write(ssl->session, buf, num); if (err > 0) return err; - + int err2 = SSL_get_error(ssl->session, err); switch (err2) { case SSL_ERROR_ZERO_RETURN: @@ -406,7 +401,7 @@ int NetlibSslWrite(SslHandle *ssl, const char *buf, int num) static INT_PTR GetSslApi(WPARAM, LPARAM lParam) { - SSL_API* pSsl = (SSL_API*)lParam; + SSL_API *pSsl = (SSL_API*)lParam; if (pSsl == NULL) return FALSE; @@ -424,8 +419,7 @@ static INT_PTR GetSslApi(WPARAM, LPARAM lParam) int LoadSslModule(void) { - if (!SSL_library_load()) - { + if (!SSL_library_load()) { MessageBoxW(NULL, TranslateT("OpenSSL library loading failed"), TranslateT("OpenSSL error"), MB_ICONERROR | MB_OK); return 1; } 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);
|