Exemple #1
0
static int NetlibHttpRecvChunkHeader(NetlibConnection *nlc, bool first, DWORD flags)
{
	char data[1000];

	while (true) {
		int recvResult = NLRecv(nlc, data, _countof(data)-1, MSG_RAW | MSG_PEEK);
		if (recvResult <= 0 || recvResult >= _countof(data))
			return SOCKET_ERROR;

		data[recvResult] = 0;

		char *peol1 = strchr(data, '\n');
		if (peol1 == NULL)
			continue;

		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);
		if (r == 0) {
			char *peol3 = strchr(peol2 + 1, '\n');
			if (peol3 == NULL) continue;
			sz = peol3 - data + 1;
		}
		NLRecv(nlc, data, sz, MSG_RAW | flags);
		return r;
	}
}
bool RecvUntilTimeout(NetlibConnection *nlc, char *buf, int len, int flags, DWORD dwTimeout)
{
	int nReceived = 0;
	DWORD dwTimeNow, dwCompleteTime = GetTickCount() + dwTimeout;

	while ((dwTimeNow = GetTickCount()) < dwCompleteTime) {
		if (WaitUntilReadable(nlc->s, dwCompleteTime - dwTimeNow) <= 0) return false;
		nReceived = NLRecv(nlc, buf, len, flags);
		if (nReceived <= 0) return false;

		buf += nReceived;
		len -= nReceived;
		if (len <= 0) return true;
	}
	SetLastError(ERROR_TIMEOUT);
	return false;
}
Exemple #3
0
INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam)
{
	struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam;
	NETLIBPACKETRECVER *nlprParam = (NETLIBPACKETRECVER*)lParam;

	if (GetNetlibHandleType(nlpr) != NLH_PACKETRECVER || nlprParam == NULL || nlprParam->cbSize != sizeof(NETLIBPACKETRECVER) || nlprParam->bytesUsed > nlpr->packetRecver.bytesAvailable) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return SOCKET_ERROR;
	}
	if (Miranda_Terminated()) { /* HACK: Lame, break while loops of protocols that can't kill their while loops, (cough, ICQ, cough) */
		SetLastError(ERROR_TIMEOUT);
		return SOCKET_ERROR;
	}
	nlpr->packetRecver.dwTimeout = nlprParam->dwTimeout;
	if (nlprParam->bytesUsed == 0) {
		if (nlpr->packetRecver.bytesAvailable == nlpr->packetRecver.bufferSize) {
			nlpr->packetRecver.bytesAvailable = 0;
			NetlibLogf(nlpr->nlc->nlu, "Packet recver: packet overflowed buffer, ditching");
		}
	}
	else {
		MoveMemory(nlpr->packetRecver.buffer, nlpr->packetRecver.buffer + nlprParam->bytesUsed, nlpr->packetRecver.bytesAvailable - nlprParam->bytesUsed);
		nlpr->packetRecver.bytesAvailable -= nlprParam->bytesUsed;
	}
	
	if (nlprParam->dwTimeout != INFINITE) {
		if (!si.pending(nlpr->nlc->hSsl) && WaitUntilReadable(nlpr->nlc->s, nlprParam->dwTimeout) <= 0) {
			*nlprParam = nlpr->packetRecver;
			return SOCKET_ERROR;
		}
	}
	
	INT_PTR recvResult = NLRecv(nlpr->nlc, (char*)nlpr->packetRecver.buffer + nlpr->packetRecver.bytesAvailable, nlpr->packetRecver.bufferSize - nlpr->packetRecver.bytesAvailable, 0);
	if (recvResult > 0)
		nlpr->packetRecver.bytesAvailable += recvResult;
	*nlprParam = nlpr->packetRecver;
	return recvResult;
}
Exemple #4
0
INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam)
{
	NetlibConnection *nlc = (struct 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);
	nlhr->nlc = nlc;  // Needed to id connection in the protocol HTTP gateway wrapper functions
	nlhr->requestType = REQUEST_RESPONSE;

	int firstLineLength = 0;
	if (!HttpPeekFirstResponseLine(nlc, dwRequestTimeoutTime, lParam | MSG_PEEK, &nlhr->resultCode, &nlhr->szResultDescr, &firstLineLength)) {
		NetlibLeaveNestedCS(&nlc->ncsRecv);
		NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr);
		return 0;
	}

	char *buffer = (char*)mir_alloc(bufferSize + 1);
	int bytesPeeked = NLRecv(nlc, buffer, min(firstLineLength, bufferSize), lParam | MSG_DUMPASTEXT);
	if (bytesPeeked != firstLineLength) {
		NetlibLeaveNestedCS(&nlc->ncsRecv);
		NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr);
		if (bytesPeeked != SOCKET_ERROR) SetLastError(ERROR_HANDLE_EOF);
		mir_free(buffer);
		return 0;
	}

	// Make sure all headers arrived
	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);
		if (bytesPeeked == 0)
			break;

		if (bytesPeeked == SOCKET_ERROR) {
			bytesPeeked = 0;
			break;
		}
		buffer[bytesPeeked] = 0;

		for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) {
			peol = strchr(pbuffer, '\n');
			if (peol == NULL) break;
			if (peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) {
				bytesPeeked = peol - buffer + 1;
				headersCompleted = true;
				break;
			}
		}
	}

	// 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;
		*peol = 0;

		char *pColon = strchr(pbuffer, ':');
		if (pColon == NULL) {
			NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); nlhr = NULL;
			SetLastError(ERROR_INVALID_DATA);
			break;
		}

		*(pColon++) = 0;
		nlhr->headers[headersCount].szName = mir_strdup(rtrim(pbuffer));
		nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon));
	}

	NetlibLeaveNestedCS(&nlc->ncsRecv);
	mir_free(buffer);
	return (INT_PTR)nlhr;
}