示例#1
0
bool CUrlClient::SendHttpBlockRequests()
{
	USES_CONVERSION;
	m_dwLastBlockReceived = ::GetTickCount();
	if (reqfile == NULL)
		throw CString(_T("Failed to send block requests - No 'reqfile' attached"));

	CreateBlockRequests(PARTSIZE / EMBLOCKSIZE);
	if (m_PendingBlocks_list.IsEmpty()){
//==> Extended Failed/Success Statistic by NetF [shadow2004]
#ifdef FSSTATS
		SetDownloadState(DS_NONEEDEDPARTS, REASON_NoNeededParts);
#else
		SetDownloadState(DS_NONEEDEDPARTS);
#endif
//<== Extended Failed/Success Statistic by NetF [shadow2004]
        SwapToAnotherFile(_T("A4AF for NNP file. UrlClient::SendHttpBlockRequests()"), true, false, false, NULL, true, true);
		return false;
	}
	
	POSITION pos = m_PendingBlocks_list.GetHeadPosition();
	Pending_Block_Struct* pending = m_PendingBlocks_list.GetNext(pos);
	m_uReqStart = pending->block->StartOffset;
	m_uReqEnd = pending->block->EndOffset;
	bool bMergeBlocks = true;
	while (pos)
	{
		POSITION posLast = pos;
		pending = m_PendingBlocks_list.GetNext(pos);
		if (bMergeBlocks && pending->block->StartOffset == m_uReqEnd + 1)
			m_uReqEnd = pending->block->EndOffset;
		else
		{
			bMergeBlocks = false;
			reqfile->RemoveBlockFromList(pending->block->StartOffset, pending->block->EndOffset);
			delete pending->block;
			delete pending;
			m_PendingBlocks_list.RemoveAt(posLast);
		}
	}

	m_nUrlStartPos = m_uReqStart;

	CStringA strHttpRequest;
	strHttpRequest.AppendFormat("GET %s HTTP/1.0\r\n", m_strUrlPath);
	strHttpRequest.AppendFormat("Accept: */*\r\n");
	strHttpRequest.AppendFormat("Range: bytes=%u-%u\r\n", m_uReqStart, m_uReqEnd);
	strHttpRequest.AppendFormat("Connection: Keep-Alive\r\n");
	strHttpRequest.AppendFormat("Host: %s\r\n", T2CA(m_strHost));
	strHttpRequest.AppendFormat("\r\n");

	if (thePrefs.GetDebugClientTCPLevel() > 0)
		Debug(_T("Sending HTTP request:\n%hs"), strHttpRequest);
	CRawPacket* pHttpPacket = new CRawPacket(strHttpRequest);
	theStats.AddUpDataOverheadFileRequest(pHttpPacket->size);
	socket->SendPacket(pHttpPacket);
	STATIC_DOWNCAST(CHttpClientDownSocket, socket)->SetHttpState(HttpStateRecvExpected);
	return true;
}
示例#2
0
bool CUpDownClient::SendHttpBlockRequests()
{
	USES_CONVERSION;
	ASSERT( GetDownloadState() == DS_DOWNLOADING );
	ASSERT( m_ePeerCacheDownState == PCDS_WAIT_CLIENT_REPLY || m_ePeerCacheDownState == PCDS_DOWNLOADING );

	m_bPeerCacheDownHit = false;
	m_dwLastBlockReceived = ::GetTickCount();
	if (reqfile == NULL)
		throw CString(_T("Failed to send block requests - No 'reqfile' attached"));

	CreateBlockRequests(1);
	if (m_PendingBlocks_list.IsEmpty()){
		if (m_pPCDownSocket != NULL){
			m_pPCDownSocket->Safe_Delete();
			ASSERT( m_pPCDownSocket == NULL );
			SetPeerCacheDownState(PCDS_NONE);
		}
		SetDownloadState(DS_NONEEDEDPARTS);
        SwapToAnotherFile(_T("A4AF for NNP file. CUpDownClient::SendHttpBlockRequests()"), true, false, false, NULL, true, true);
		return false;
	}

	// PeerCache does not support persistant HTTP connections
	if (m_pPCDownSocket != NULL)
	{
		m_pPCDownSocket->Safe_Delete();
		ASSERT( m_pPCDownSocket == NULL );
		SetPeerCacheDownState(PCDS_NONE);
		return SendPeerCacheFileRequest();
	}

	ASSERT( m_pPCDownSocket == NULL );
	m_pPCDownSocket = new CPeerCacheDownSocket(this);
	m_pPCDownSocket->SetTimeOut(GetPeerCacheSocketDownloadTimeout());
	if (!m_pPCDownSocket->Create()){
		m_pPCDownSocket->Safe_Delete();
		ASSERT( m_pPCDownSocket == NULL );
		return false;
	}

	ASSERT( !m_pPCDownSocket->IsConnected() );
	SOCKADDR_IN sockAddr = {0};
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons( theApp.m_pPeerCache->GetCachePort() );
	sockAddr.sin_addr.S_un.S_addr = theApp.m_pPeerCache->GetCacheIP();
	//Try to always tell the socket to WaitForOnConnect before you call Connect.
	m_pPCDownSocket->WaitForOnConnect();
	m_pPCDownSocket->Connect((SOCKADDR*)&sockAddr, sizeof sockAddr);

	POSITION pos = m_PendingBlocks_list.GetHeadPosition();
	Pending_Block_Struct* pending = m_PendingBlocks_list.GetNext(pos);
	ASSERT( pending->block->StartOffset <= pending->block->EndOffset );

	m_uReqStart = pending->block->StartOffset;
	m_uReqEnd = pending->block->EndOffset;
	m_nUrlStartPos = (uint64)-1;

	CStringA strPCRequest;
	strPCRequest.AppendFormat("GET http://%s/.ed2khash=%s HTTP/1.0\r\n", ipstrA(m_uPeerCacheRemoteIP), md4strA(reqfile->GetFileHash()));
	strPCRequest.AppendFormat("X-ED2K-PushId: %u\r\n", m_uPeerCacheDownloadPushId);
	strPCRequest.AppendFormat("Range: bytes=%I64u-%I64u\r\n", m_uReqStart, m_uReqEnd);
	strPCRequest.AppendFormat("User-Agent: eMule/%s\r\n", T2CA(theApp.m_strCurVersionLong));
	strPCRequest.AppendFormat("X-Network: eDonkey,Kademlia\r\n");
	strPCRequest.AppendFormat("\r\n");

	if (thePrefs.GetDebugClientTCPLevel() > 0){
		DebugSend("PeerCache-GET", this, reqfile->GetFileHash());
		Debug(_T("  %hs\n"), strPCRequest);
	}
	CRawPacket* pHttpPacket = new CRawPacket(strPCRequest);
	theStats.AddUpDataOverheadFileRequest(pHttpPacket->size);
	m_pPCDownSocket->SendPacket(pHttpPacket);
	m_pPCDownSocket->SetHttpState(HttpStateRecvExpected);
	SetPeerCacheDownState(PCDS_WAIT_CACHE_REPLY);
	return true;
}