⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadtransferhttp.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}
	else if ( strHeader.CompareNoCase( _T("X-Delete-Source") ) == 0 )
	{
		m_bBadResponse = TRUE;
	}
	else if (	strHeader.CompareNoCase( _T("X-Nick") ) == 0 ||
				strHeader.CompareNoCase( _T("X-Name") ) == 0 ||
				strHeader.CompareNoCase( _T("X-UserName") ) == 0 )
	{
		m_pSource->m_sNick = URLDecode( strValue );
	}
	else if ( strHeader.CompareNoCase( _T("X-Features") ) == 0 )
	{
		if ( _tcsistr( strValue, _T("g2/") ) != NULL ) m_pSource->SetGnutella( 2 );
		if ( _tcsistr( strValue, _T("gnet2/") ) != NULL ) m_pSource->SetGnutella( 2 );
		if ( _tcsistr( strValue, _T("gnutella2/") ) != NULL ) m_pSource->SetGnutella( 2 );
		m_pSource->SetGnutella( 1 );
	}
	
	return CTransfer::OnHeaderLine( strHeader, strValue );
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP end of headers

BOOL CDownloadTransferHTTP::OnHeadersComplete()
{
	if ( m_bBadResponse )
	{
		Close( TS_FALSE );
		return FALSE;
	}
	else if ( ! m_pSource->CanInitiate( TRUE, TRUE ) )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_DISABLED,
			(LPCTSTR)m_pDownload->GetDisplayName(), (LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );
		Close( TS_FALSE );
		return FALSE;
	}
	else if ( m_bBusyFault )
	{
		m_nOffset = SIZE_UNKNOWN;
		
		if ( Settings.Downloads.QueueLimit > 0 && m_nQueuePos > Settings.Downloads.QueueLimit )
		{
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_QUEUE_HUGE,
				(LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName(), m_nQueuePos );
			Close( TS_FALSE );
			return FALSE;
		}
		else if ( m_bQueueFlag && m_nRetryDelay >= 600000 )
		{
			m_pSource->m_tAttempt = GetTickCount() + m_nRetryDelay;
			m_bQueueFlag = FALSE;
		}
		
		if ( m_bQueueFlag )
		{
			SetState( dtsFlushing );
			m_tContent = m_mInput.tLast = GetTickCount();
			return ReadFlush();
		}
		else
		{
			SetState( dtsBusy );
			m_tRequest = GetTickCount();
			return TRUE;
		}
	}
	else if ( ! m_bGotRanges && ! m_bTigerFetch && ! m_bMetaFetch )
	{
		m_pSource->SetAvailableRanges( NULL );
	}
	
	if ( m_bRangeFault )
	{
		if ( m_pHost.sin_addr.S_un.S_addr == Network.m_pHost.sin_addr.S_un.S_addr )
		{
			Close( TS_FALSE );
			return FALSE;
		}
		
		m_nOffset = SIZE_UNKNOWN;
		SetState( dtsFlushing );
		m_tContent = m_mInput.tLast = GetTickCount();
		
		return ReadFlush();
	}
	else if ( m_nContentLength == SIZE_UNKNOWN )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_SIZE, (LPCTSTR)m_sAddress,
			(LPCTSTR)m_pDownload->GetDisplayName() );
		Close( TS_FALSE );
		return FALSE;
	}
	else if ( m_bTigerFetch )
	{
		if ( ! m_bGotRange )
		{
			m_nOffset = 0;
			m_nLength = m_nContentLength;
		}
		else if ( m_nOffset > 0 )
		{
			theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_TIGER_RANGE, (LPCTSTR)m_sAddress );
			Close( TS_FALSE );
			return FALSE;
		}
		
		if (	m_sContentType.CompareNoCase( _T("application/tigertree-breadthfirst") ) &&
				m_sContentType.CompareNoCase( _T("application/dime") ) )
		{
			theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_TIGER_RANGE, (LPCTSTR)m_sAddress );
			Close( TS_FALSE );
			return FALSE;
		}
		
		SetState( dtsTiger );
		m_tContent = m_mInput.tLast = GetTickCount();
		
		theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_TIGER_RECV, (LPCTSTR)m_sAddress,
			(LPCTSTR)m_pSource->m_sServer );
		
		return ReadTiger();
	}
	else if ( m_bMetaFetch )
	{
		if ( ! m_bGotRange )
		{
			m_nOffset = 0;
			m_nLength = m_nContentLength;
		}
		
		SetState( dtsMetadata );
		m_tContent = m_mInput.tLast = GetTickCount();
		
		theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_METADATA_RECV,
			(LPCTSTR)m_sAddress, (LPCTSTR)m_pSource->m_sServer );
		
		return ReadMetadata();
	}
	else if ( ! m_bGotRange )
	{
		if ( m_pDownload->m_nSize == SIZE_UNKNOWN )
		{
			m_pDownload->m_nSize = m_nContentLength;
		}
		else if ( m_pDownload->m_nSize != m_nContentLength )
		{
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_SIZE, (LPCTSTR)m_sAddress,
				(LPCTSTR)m_pDownload->GetDisplayName() );
			Close( TS_FALSE );
			return FALSE;
		}
		
		if ( m_nOffset == SIZE_UNKNOWN && ! m_pDownload->GetFragment( this ) )
		{
			Close( TS_TRUE );
			return FALSE;
		}
		
		if ( ! m_pDownload->IsPositionEmpty( 0 ) )
		{
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_RANGE, (LPCTSTR)m_sAddress,
				(LPCTSTR)m_pDownload->GetDisplayName() );
			Close( TS_TRUE );
			return FALSE;
		}
		
		m_nOffset = 0;
		m_nLength = m_nContentLength;
	}
	
	if ( m_nContentLength != m_nLength )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_RANGE, (LPCTSTR)m_sAddress,
			(LPCTSTR)m_pDownload->GetDisplayName() );
		Close( TS_FALSE );
		return FALSE;
	}
	
	if ( ! m_bKeepAlive ) m_pSource->m_bCloseConn = TRUE;
	
	theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_CONTENT, (LPCTSTR)m_sAddress,
		(LPCTSTR)m_pSource->m_sServer );
	
	SetState( dtsDownloading );
	m_nPosition = 0;
	m_tContent = m_mInput.tLast = GetTickCount();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP read content

BOOL CDownloadTransferHTTP::ReadContent()
{
	if ( m_pInput->m_nLength > 0 )
	{
		m_pSource->SetValid();
		
		DWORD nLength	= (DWORD)min( (QWORD)m_pInput->m_nLength, m_nLength - m_nPosition );
		BOOL bSubmit	= FALSE;
		
		if ( m_bRecvBackwards )
		{
			BYTE* pBuffer = new BYTE[ nLength ];
			CBuffer::ReverseBuffer( m_pInput->m_pBuffer, pBuffer, nLength );
			bSubmit = m_pDownload->SubmitData(
				m_nOffset + m_nLength - m_nPosition - nLength, pBuffer, nLength );
			delete [] pBuffer;
		}
		else
		{
			bSubmit = m_pDownload->SubmitData(
						m_nOffset + m_nPosition, m_pInput->m_pBuffer, nLength );
		}
		
		m_pInput->Clear();	// Clear the buffer, we don't want any crap
		m_nPosition += nLength;
		m_nDownloaded += nLength;
		
		if ( ! bSubmit && m_pDownload->GetProgress() < 0.95f )
		{
			BOOL bUseful = FALSE;
			
			if ( m_bRecvBackwards )
			{
				bUseful = m_pDownload->IsRangeUseful( m_nOffset, m_nLength - m_nPosition );
			}
			else
			{
				bUseful = m_pDownload->IsRangeUseful( m_nOffset + m_nPosition, m_nLength - m_nPosition );
			}
			
			if ( /* m_bInitiated || */ ! bUseful )
			{
				theApp.Message( MSG_DEFAULT, IDS_DOWNLOAD_FRAGMENT_OVERLAP, (LPCTSTR)m_sAddress );
				Close( TS_TRUE );
				return FALSE;
			}
		}
	}
	
	if ( m_nPosition >= m_nLength )
	{
		m_pSource->AddFragment( m_nOffset, m_nLength );
		return StartNextFragment();
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP read Metadata

BOOL CDownloadTransferHTTP::ReadMetadata()
{
	if ( m_pInput->m_nLength < m_nLength ) return TRUE;
	
	CString strXML = m_pInput->ReadString( (DWORD)m_nLength, CP_UTF8 );
	
	if ( CXMLElement* pXML = CXMLElement::FromString( strXML, TRUE ) )
	{
		if ( m_pDownload->m_pXML == NULL )
		{
			m_pDownload->m_pXML = pXML;
		}
		else
		{
			delete pXML;
		}
	}
	
	m_pInput->Remove( (DWORD)m_nLength );
	
	return StartNextFragment();
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP read tiger tree

BOOL CDownloadTransferHTTP::ReadTiger()
{
	if ( m_pInput->m_nLength < m_nLength ) return TRUE;
	
	if ( m_sContentType.CompareNoCase( _T("application/tigertree-breadthfirst") ) == 0 )
	{
		m_pDownload->SetTigerTree( m_pInput->m_pBuffer, (DWORD)m_nLength );
		m_pInput->Remove( (DWORD)m_nLength );
	}
	else if ( m_sContentType.CompareNoCase( _T("application/dime") ) == 0 )
	{
		CString strID, strType, strUUID = _T("x");
		DWORD nFlags, nBody;
		
		while ( m_pInput->ReadDIME( &nFlags, &strID, &strType, &nBody ) )
		{
			theApp.Message( MSG_DEBUG, _T("THEX DIME: %i, '%s', '%s', %i"),
				nFlags, (LPCTSTR)strID, (LPCTSTR)strType, nBody );
			
			if ( ( nFlags & 1 ) && strType.CompareNoCase( _T("text/xml") ) == 0 && nBody < 1024*1024 )
			{
				BOOL bSize = FALSE, bDigest = FALSE, bEncoding = FALSE;
				CString strXML;
				
				strXML = m_pInput->ReadString( nBody, CP_UTF8 );
				
				if ( CXMLElement* pXML = CXMLElement::FromString( strXML ) )
				{
					if ( pXML->IsNamed( _T("hashtree") ) )
					{
						if ( CXMLElement* pxFile = pXML->GetElementByName( _T("file") ) )
						{
							QWORD nSize = 0;
							_stscanf( pxFile->GetAttributeValue( _T("size") ), _T("%I64i"), &nSize );
							bSize = ( nSize == m_pDownload->m_nSize );
						}
						if ( CXMLElement* pxDigest = pXML->GetElementByName( _T("digest") ) )
						{
							if ( pxDigest->GetAttributeValue( _T("algorithm") ).CompareNoCase( _T("http://open-content.net/spec/digest/tiger") ) == 0 )
							{
								bDigest = ( pxDigest->GetAttributeValue( _T("outputsize") ) == _T("24") );
							}
						}
						if ( CXMLElement* pxTree = pXML->GetElementByName( _T("serializedtree") ) )
						{
							bEncoding = ( pxTree->GetAttributeValue( _T("type") ).CompareNoCase( _T("http://open-content.net/spec/thex/breadthfirst") ) == 0 );
							strUUID = pxTree->GetAttributeValue( _T("uri") );
						}
					}
					delete pXML;
				}
				
				theApp.Message( MSG_DEBUG, _T("THEX XML: size=%i, digest=%i, encoding=%i"),
					bSize, bDigest, bEncoding );
				
				if ( ! bSize || ! bDigest || ! bEncoding ) break;
			}
			else if ( strID == strUUID && strType.CompareNoCase( _T("http://open-content.net/spec/thex/breadthfirst") ) == 0 )
			{
				m_pDownload->SetTigerTree( m_pInput->m_pBuffer, nBody );
			}
			else if ( strType.CompareNoCase( _T("http://edonkey2000.com/spec/md4-hashset") ) == 0 )
			{
				m_pDownload->SetHashset( m_pInput->m_pBuffer, nBody );
			}
			
			m_pInput->Remove( ( nBody + 3 ) & ~3 );
			if ( nFlags & 2 ) break;
		}
		
		m_pInput->Clear();
	}
	
	return StartNextFragment();
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP read flushing

BOOL CDownloadTransferHTTP::ReadFlush()
{
	if ( m_nContentLength == SIZE_UNKNOWN ) m_nContentLength = 0;
	
	DWORD nRemove = min( m_pInput->m_nLength, (DWORD)m_nContentLength );
	m_nContentLength -= nRemove;
	
	m_pInput->Remove( nRemove );
	
	if ( m_nContentLength == 0 )
	{
		if ( m_bQueueFlag )
		{
			SetState( dtsQueued );
			m_tRequest = GetTickCount() + m_nRetryDelay;

			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_QUEUED,
				(LPCTSTR)m_sAddress, m_nQueuePos, m_nQueueLen,
				(LPCTSTR)m_sQueueName );
		}
		else
		{
			return StartNextFragment();
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadTransferHTTP dropped connection handler

void CDownloadTransferHTTP::OnDropped(BOOL bError)
{
	if ( m_nState == dtsConnecting )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_CONNECT_ERROR, (LPCTSTR)m_sAddress );
		if ( m_pSource != NULL ) m_pSource->PushRequest();
		Close( TS_UNKNOWN );
	}
	else if ( m_nState == dtsBusy )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_BUSY, (LPCTSTR)m_sAddress, Settings.Downloads.RetryDelay / 1000 );
		Close( TS_TRUE );
	}
	else
	{
//		if ( m_nState == dtsDownloading && m_nLength && m_pSource )
//			m_pSource->m_bCloseConn = TRUE;
		
		if ( m_bBusyFault || m_bQueueFlag )
		{
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_BUSY, (LPCTSTR)m_sAddress, Settings.Downloads.RetryDelay / 1000 );
			Close( TS_TRUE );
		}
		else
		{
			theApp.Message( MSG_ERROR, IDS_DOWNLOAD_DROPPED, (LPCTSTR)m_sAddress );
			Close( m_nState >= dtsDownloading ? TS_TRUE : TS_UNKNOWN );
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -