📄 hostbrowser.cpp
字号:
else if ( strHeader.CompareNoCase( _T("Content-Type") ) == 0 )
{
if ( strValue.CompareNoCase( _T("application/x-gnutella-packets") ) == 0 )
m_nProtocol = PROTOCOL_G1;
else if ( strValue.CompareNoCase( _T("application/x-gnutella2") ) == 0 )
m_nProtocol = PROTOCOL_G2;
else if ( strValue.CompareNoCase( _T("application/x-shareaza") ) == 0 )
m_nProtocol = PROTOCOL_G2;
else if ( strValue.CompareNoCase( _T("text/html") ) == 0 )
m_nProtocol = 0;
}
else if ( strHeader.CompareNoCase( _T("Content-Encoding") ) == 0 )
{
m_bDeflate = strValue.CompareNoCase( _T("deflate") ) == 0;
}
else if ( strHeader.CompareNoCase( _T("Content-Length") ) == 0 )
{
_stscanf( strValue, _T("%lu"), &m_nLength );
}
return TRUE;
}
BOOL CHostBrowser::OnHeadersComplete()
{
if ( m_nProtocol < 0 || m_nLength == 0 )
{
theApp.Message( MSG_ERROR, IDS_BROWSE_BAD_RESPONSE, (LPCTSTR)m_sAddress );
Stop();
return FALSE;
}
m_nState = hbsContent;
m_nReceived = 0;
m_pBuffer = new CBuffer();
m_mInput.tLast = GetTickCount();
if ( m_bDeflate )
{
m_pInflate = new z_stream;
z_streamp pStream = (z_streamp)m_pInflate;
ZeroMemory( pStream, sizeof(z_stream) );
if ( inflateInit( pStream ) != Z_OK )
{
delete pStream;
m_pInflate = NULL;
Stop();
return FALSE;
}
}
switch ( m_nProtocol )
{
case 0:
theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
(LPCTSTR)m_sAddress, _T("HTML") );
break;
case PROTOCOL_G1:
theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
(LPCTSTR)m_sAddress, _T("Gnutella-1") );
break;
case PROTOCOL_G2:
theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
(LPCTSTR)m_sAddress, _T("Gnutella-2") );
break;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CHostBrowser read content
BOOL CHostBrowser::ReadContent()
{
if ( m_nReceived < m_nLength )
{
DWORD nVolume = min( m_nLength - m_nReceived, m_pInput->m_nLength );
m_nReceived += nVolume;
if ( m_bDeflate && m_pInflate != NULL )
{
z_streamp pStream = (z_streamp)m_pInflate;
while ( nVolume || m_pBuffer->m_nLength == m_pBuffer->m_nBuffer || pStream->avail_out == 0 )
{
m_pBuffer->EnsureBuffer( 1024 );
pStream->next_in = m_pInput->m_pBuffer;
pStream->avail_in = m_pInput->m_nLength;
pStream->next_out = m_pBuffer->m_pBuffer + m_pBuffer->m_nLength;
pStream->avail_out = m_pBuffer->m_nBuffer - m_pBuffer->m_nLength;
inflate( pStream, Z_SYNC_FLUSH );
m_pInput->Remove( m_pInput->m_nLength - pStream->avail_in );
nVolume -= ( m_pInput->m_nLength - pStream->avail_in );
DWORD nBlock = ( m_pBuffer->m_nBuffer - m_pBuffer->m_nLength ) - pStream->avail_out;
m_pBuffer->m_nLength += nBlock;
if ( ! nBlock ) break;
}
}
else
{
m_pBuffer->AddBuffer( m_pInput, nVolume );
}
}
switch ( m_nProtocol )
{
case 0:
if ( ! StreamHTML() ) return FALSE;
break;
case PROTOCOL_G1:
if ( ! StreamPacketsG1() ) return FALSE;
break;
case PROTOCOL_G2:
if ( ! StreamPacketsG2() ) return FALSE;
break;
}
if ( m_nReceived < m_nLength ) return TRUE;
Stop( TRUE );
if ( m_pProfile->IsValid() && m_pNotify != NULL ) m_pNotify->OnProfileReceived();
theApp.Message( MSG_SYSTEM, IDS_BROWSE_FINISHED, (LPCTSTR)m_sAddress, m_nHits );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CHostBrowser packet streaming
BOOL CHostBrowser::StreamPacketsG1()
{
for ( BOOL bSuccess = TRUE ; bSuccess ; )
{
GNUTELLAPACKET* pPacket = (GNUTELLAPACKET*)m_pBuffer->m_pBuffer;
if ( m_pBuffer->m_nLength < sizeof(*pPacket) ) break;
DWORD nLength = sizeof(*pPacket) + pPacket->m_nLength;
if ( pPacket->m_nLength < 0 || nLength >= (DWORD)Settings.Gnutella1.MaximumPacket * 8 )
{
theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
Stop();
return FALSE;
}
if ( m_pBuffer->m_nLength < nLength ) break;
CG1Packet* pPacketObject = CG1Packet::New( pPacket );
try
{
bSuccess = OnPacket( pPacketObject );
}
catch ( CException* pException )
{
pException->Delete();
}
pPacketObject->Release();
m_pBuffer->Remove( nLength );
}
if ( ! bSuccess ) Stop();
return bSuccess;
}
BOOL CHostBrowser::StreamPacketsG2()
{
CG2Packet* pPacket;
while ( pPacket = CG2Packet::ReadBuffer( m_pBuffer ) )
{
BOOL bSuccess = FALSE;
try
{
bSuccess = OnPacket( pPacket );
}
catch ( CException* pException )
{
pException->Delete();
}
pPacket->Release();
if ( ! bSuccess )
{
Stop();
return FALSE;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CHostBrowser packet interpreter
BOOL CHostBrowser::OnPacket(CG1Packet* pPacket)
{
if ( pPacket->m_nType != G1_PACKET_HIT || pPacket->m_nLength <= 27 )
return TRUE;
CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
if ( pHits == NULL )
{
theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
return FALSE;
}
m_bCanPush = TRUE;
m_pClientID = pHits->m_pClientID;
for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext ) m_nHits++;
Downloads.OnQueryHits( pHits );
if ( ! m_bCanChat && pHits->m_bChat ) m_bCanChat = TRUE;
if ( m_pNotify != NULL )
m_pNotify->OnBrowseHits( pHits );
else
pHits->Delete();
return TRUE;
}
BOOL CHostBrowser::OnPacket(CG2Packet* pPacket)
{
if ( pPacket->IsType( G2_PACKET_HIT ) )
{
CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
if ( pHits == NULL )
{
theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
return FALSE;
}
m_bCanPush = TRUE;
m_pClientID = pHits->m_pClientID;
for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext )
{
m_nHits++;
}
Downloads.OnQueryHits( pHits );
if ( ! m_bCanChat && pHits->m_bChat )
{
m_bCanChat = TRUE;
if ( m_pNotify && m_pProfile != NULL ) m_pNotify->OnProfileReceived();
}
if ( m_pNotify != NULL )
m_pNotify->OnBrowseHits( pHits );
else
pHits->Delete();
}
else if ( pPacket->IsType( G2_PACKET_PHYSICAL_FOLDER ) )
{
if ( m_pNotify != NULL ) m_pNotify->OnPhysicalTree( pPacket );
}
else if ( pPacket->IsType( G2_PACKET_VIRTUAL_FOLDER ) )
{
if ( m_pNotify != NULL ) m_pNotify->OnVirtualTree( pPacket );
}
else if ( pPacket->IsType( G2_PACKET_PROFILE_DELIVERY ) )
{
OnProfilePacket( pPacket );
if ( m_pProfile != NULL && m_pNotify != NULL )
{
m_pNotify->OnProfileReceived();
}
}
else if ( pPacket->IsType( G2_PACKET_PROFILE_AVATAR ) )
{
if ( m_pNotify != NULL ) m_pNotify->OnHeadPacket( pPacket );
}
return TRUE;
}
void CHostBrowser::OnProfilePacket(CG2Packet* pPacket)
{
CHAR szType[9];
DWORD nLength;
while ( pPacket->ReadPacket( szType, nLength ) )
{
DWORD nOffset = pPacket->m_nPosition + nLength;
if ( strcmp( szType, "XML" ) == 0 )
{
CXMLElement* pXML = CXMLElement::FromString( pPacket->ReadString( nLength ), TRUE );
if ( pXML != NULL )
{
if ( m_pProfile == NULL ) m_pProfile = new CGProfile();
if ( ! m_pProfile->FromXML( pXML ) ) delete pXML;
if ( m_pProfile != NULL && ! m_pProfile->IsValid() )
{
delete m_pProfile;
m_pProfile = NULL;
}
}
}
pPacket->m_nPosition = nOffset;
}
}
//////////////////////////////////////////////////////////////////////
// CHostBrowser HTML streaming
BOOL CHostBrowser::StreamHTML()
{
CString strLine;
CQueryHit* pHits = NULL;
while ( m_pBuffer->ReadLine( strLine ) )
{
if ( Settings.General.Debug && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) )
{
theApp.Message( MSG_DEBUG, _T("HTML-BROWSE: %s"), (LPCTSTR)strLine );
}
int nPosHTTP = strLine.Find( _T("http://") );
while ( nPosHTTP >= 0 && strLine.Find( _T("/get/") ) > nPosHTTP )
{
CString strURI = strLine.Mid( nPosHTTP ).SpanExcluding( _T("?&\"'<>") );
CString strName;
DWORD nSize = 0;
int nPosSize = strLine.Find( _T("<TD NOWRAP>") );
if ( nPosSize >= 0 && nPosSize < nPosHTTP )
{
CString strSize = strLine.Mid( nPosSize + 11 ).SpanExcluding( _T("</") );
float nFloat = 0;
if ( _stscanf( strSize, _T("%f"), &nFloat ) == 1 && nFloat > 0 )
{
if ( strSize.Find( _T(" GB") ) >= 0 )
nFloat *= 1024*1024*1024;
else if ( strSize.Find( _T(" MB") ) >= 0 )
nFloat *= 1024*1024;
else if ( strSize.Find( _T(" KB") ) >= 0 )
nFloat *= 1024;
nSize = (DWORD)nFloat;
}
}
strLine = strLine.Mid( nPosHTTP + strURI.GetLength() );
int nPosName = strLine.Find( _T(">") );
if ( nPosName >= 0 )
{
strName = strLine.Mid( nPosName + 1 ).SpanExcluding( _T("<>") );
}
if ( strName.IsEmpty() && ( nPosName = strURI.ReverseFind( '/' ) ) > 0 )
{
strName = URLDecode( strURI.Mid( nPosName + 1 ) );
}
CQueryHit* pHit = new CQueryHit( PROTOCOL_NULL, NULL );
pHit->m_pAddress = m_pHost.sin_addr;
pHit->m_nPort = htons( m_pHost.sin_port );
pHit->m_pVendor = m_pVendor ? m_pVendor : VendorCache.m_pNull;
pHit->m_bPush = ( m_tPushed ) ? TS_TRUE : TS_FALSE;
pHit->m_bBrowseHost = TRUE;
pHit->m_nSize = nSize;
pHit->m_sName = strName;
pHit->m_sURL = strURI;
if ( m_bCanPush ) pHit->m_pClientID = m_pClientID;
pHit->m_pNext = pHits;
pHits = pHit;
m_nHits ++;
nPosHTTP = strLine.Find( _T("http://") );
}
}
if ( pHits != NULL )
{
if ( m_pNotify != NULL )
m_pNotify->OnBrowseHits( pHits );
else
pHits->Delete();
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -