00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Network.h"
00026 #include "Buffer.h"
00027 #include "G1Packet.h"
00028 #include "G2Packet.h"
00029 #include "GProfile.h"
00030 #include "Neighbours.h"
00031 #include "HostBrowser.h"
00032 #include "Transfers.h"
00033 #include "QueryHit.h"
00034 #include "Downloads.h"
00035 #include "VendorCache.h"
00036 #include "WndBrowseHost.h"
00037 #include "XML.h"
00038 #include <zlib.h>
00039
00040 #ifdef _DEBUG
00041 #undef THIS_FILE
00042 static char THIS_FILE[]=__FILE__;
00043 #define new DEBUG_NEW
00044 #endif
00045
00046
00048
00049
00050 CHostBrowser::CHostBrowser(CBrowseHostWnd* pNotify, IN_ADDR* pAddress, WORD nPort, BOOL bMustPush, GGUID* pClientID)
00051 {
00052 m_nState = hbsNull;
00053 m_pNotify = pNotify;
00054 m_pProfile = NULL;
00055
00056 m_bNewBrowse = FALSE;
00057 m_pAddress = *pAddress;
00058 m_nPort = nPort;
00059 m_bMustPush = bMustPush;
00060 m_bCanPush = FALSE;
00061
00062 if ( pClientID != NULL )
00063 {
00064 m_bCanPush = TRUE;
00065 m_pClientID = *pClientID;
00066 }
00067
00068 m_tPushed = 0;
00069 m_bConnect = FALSE;
00070 m_nHits = 0;
00071 m_pVendor = NULL;
00072 m_bCanChat = FALSE;
00073
00074 m_pBuffer = NULL;
00075 m_pInflate = NULL;
00076 }
00077
00078 CHostBrowser::~CHostBrowser()
00079 {
00080 Stop();
00081
00082 if ( m_pProfile ) delete m_pProfile;
00083 }
00084
00086
00087
00088 BOOL CHostBrowser::Browse()
00089 {
00090 CSingleLock pLock( &Transfers.m_pSection, TRUE );
00091
00092 if ( m_hSocket != INVALID_SOCKET ) return FALSE;
00093
00094 m_sAddress = inet_ntoa( m_pAddress );
00095
00096 if ( m_bMustPush )
00097 {
00098 if ( SendPush( FALSE ) )
00099 {
00100 theApp.Message( MSG_SYSTEM, IDS_BROWSE_PUSHED_TO, (LPCTSTR)m_sAddress );
00101 }
00102 else
00103 {
00104 theApp.Message( MSG_ERROR, IDS_BROWSE_CANT_PUSH_TO, (LPCTSTR)m_sAddress );
00105 return FALSE;
00106 }
00107 }
00108 else
00109 {
00110 if ( ConnectTo( &m_pAddress, m_nPort ) )
00111 {
00112 theApp.Message( MSG_SYSTEM, IDS_BROWSE_CONNECTING_TO, (LPCTSTR)m_sAddress );
00113 }
00114 else
00115 {
00116 theApp.Message( MSG_ERROR, IDS_BROWSE_CANT_CONNECT_TO, (LPCTSTR)m_sAddress );
00117 return FALSE;
00118 }
00119 }
00120
00121 m_nState = hbsConnecting;
00122 m_nHits = 0;
00123
00124 if ( m_pProfile != NULL ) delete m_pProfile;
00125 m_pProfile = NULL;
00126
00127 return TRUE;
00128 }
00129
00130 void CHostBrowser::Stop(BOOL bCompleted)
00131 {
00132 CSingleLock pLock( &Transfers.m_pSection, TRUE );
00133
00134 if ( m_hSocket != INVALID_SOCKET )
00135 {
00136 theApp.Message( MSG_DEFAULT, IDS_BROWSE_CLOSED, (LPCTSTR)m_sAddress );
00137 }
00138
00139 CTransfer::Close();
00140
00141 m_nState = hbsNull;
00142 m_tPushed = 0;
00143
00144 if ( m_pBuffer != NULL )
00145 {
00146 delete m_pBuffer;
00147 m_pBuffer = NULL;
00148 }
00149
00150 if ( m_pInflate != NULL )
00151 {
00152 z_streamp pStream = (z_streamp)m_pInflate;
00153 inflateEnd( pStream );
00154 delete pStream;
00155 m_pInflate = NULL;
00156 }
00157 }
00158
00159 BOOL CHostBrowser::IsBrowsing() const
00160 {
00161 return m_nState != hbsNull;
00162 }
00163
00164 float CHostBrowser::GetProgress() const
00165 {
00166 if ( m_nState != hbsContent || m_nLength == 0 || m_nLength == 0xFFFFFFFF ) return 0;
00167
00168 return (float)m_nReceived / (float)m_nLength;
00169 }
00170
00172
00173
00174 BOOL CHostBrowser::OnConnected()
00175 {
00176 CTransfer::OnConnected();
00177 SendRequest();
00178 return TRUE;
00179 }
00180
00181 BOOL CHostBrowser::OnRead()
00182 {
00183 if ( m_pInput == NULL || m_pOutput == NULL ) return TRUE;
00184
00185 CTransfer::OnRead();
00186
00187 switch ( m_nState )
00188 {
00189 case hbsRequesting:
00190 if ( ! ReadResponseLine() ) return FALSE;
00191 if ( m_nState != hbsHeaders ) break;
00192
00193 case hbsHeaders:
00194 if ( ! ReadHeaders() ) return FALSE;
00195 if ( m_nState != hbsContent ) break;
00196
00197 case hbsContent:
00198 return ReadContent();
00199
00200 }
00201
00202 return TRUE;
00203 }
00204
00205 void CHostBrowser::OnDropped(BOOL bError)
00206 {
00207 if ( m_hSocket == INVALID_SOCKET ) return;
00208
00209 if ( m_nState == hbsConnecting )
00210 {
00211 theApp.Message( MSG_ERROR, IDS_BROWSE_CANT_CONNECT_TO, (LPCTSTR)m_sAddress );
00212 if ( ! m_tPushed && SendPush( TRUE ) ) return;
00213 }
00214 else
00215 {
00216 if ( m_nLength == 0xFFFFFFFF )
00217 {
00218 m_nLength = m_pInput->m_nLength;
00219 ReadContent();
00220 return;
00221 }
00222
00223 theApp.Message( MSG_ERROR, IDS_BROWSE_DROPPED, (LPCTSTR)m_sAddress );
00224 }
00225
00226 Stop();
00227 }
00228
00229 BOOL CHostBrowser::OnRun()
00230 {
00231 CTransfer::OnRun();
00232
00233 DWORD nNow = GetTickCount();
00234
00235 switch ( m_nState )
00236 {
00237 case hbsConnecting:
00238 if ( nNow - m_tConnected > Settings.Connection.TimeoutConnect * 2 )
00239 {
00240 OnDropped( TRUE );
00241 return FALSE;
00242 }
00243 break;
00244 case hbsRequesting:
00245 case hbsHeaders:
00246 if ( nNow - m_tConnected > Settings.Connection.TimeoutHandshake * 3 )
00247 {
00248 theApp.Message( MSG_ERROR, IDS_BROWSE_TIMEOUT, (LPCTSTR)m_sAddress );
00249 Stop();
00250 return FALSE;
00251 }
00252 break;
00253 case hbsContent:
00254 if ( nNow - m_mInput.tLast > Settings.Connection.TimeoutTraffic )
00255 {
00256 theApp.Message( MSG_ERROR, IDS_BROWSE_TIMEOUT, (LPCTSTR)m_sAddress );
00257 Stop();
00258 return FALSE;
00259 }
00260 }
00261
00262 return TRUE;
00263 }
00264
00266
00267
00268 BOOL CHostBrowser::SendPush(BOOL bMessage)
00269 {
00270 if ( ! m_bCanPush ) return FALSE;
00271
00272 if ( Network.SendPush( &m_pClientID, 0 ) )
00273 {
00274 CTransfer::Close();
00275 m_tPushed = GetTickCount();
00276
00277 if ( bMessage )
00278 theApp.Message( MSG_DEFAULT, IDS_BROWSE_PUSHED_TO, (LPCTSTR)m_sAddress );
00279
00280 return TRUE;
00281 }
00282 else
00283 {
00284 return FALSE;
00285 }
00286 }
00287
00288 BOOL CHostBrowser::OnPush(GGUID* pClientID, CConnection* pConnection)
00289 {
00290 if ( m_tPushed == 0 ) return FALSE;
00291 if ( m_hSocket != INVALID_SOCKET ) return FALSE;
00292
00293 if ( m_pClientID != *pClientID ) return FALSE;
00294
00295 AttachTo( pConnection );
00296
00297 m_pAddress = m_pHost.sin_addr;
00298 m_nPort = htons( m_pHost.sin_port );
00299
00300 SendRequest();
00301
00302 return TRUE;
00303 }
00304
00306
00307
00308 void CHostBrowser::SendRequest()
00309 {
00310 if ( m_hSocket == INVALID_SOCKET ) return;
00311
00312 if ( m_bNewBrowse )
00313 {
00314 m_pOutput->Print( "GET /gnutella/browse/v1 HTTP/1.1\r\n" );
00315 }
00316 else
00317 {
00318 m_pOutput->Print( Settings.Downloads.RequestHTTP11 ? _T("GET / HTTP/1.1\r\n") : _T("GET / HTTP/1.0\r\n") );
00319 }
00320
00321 CString strHeader = Settings.SmartAgent();
00322
00323 if ( strHeader.GetLength() )
00324 {
00325 m_pOutput->Print( _T("User-Agent: ") + strHeader + _T("\r\n") );
00326 }
00327
00328 m_pOutput->Print( "Accept: text/html, application/x-gnutella-packets, application/x-gnutella2\r\n" );
00329 m_pOutput->Print( "Accept-Encoding: deflate\r\n" );
00330 m_pOutput->Print( "Connection: close\r\n" );
00331
00332 strHeader.Format( _T("Host: %s:%lu\r\n\r\n"),
00333 (LPCTSTR)m_sAddress, htons( m_pHost.sin_port ) );
00334 m_pOutput->Print( strHeader );
00335
00336 CTransfer::OnWrite();
00337
00338 m_nState = hbsRequesting;
00339 m_nProtocol = -1;
00340 m_bDeflate = FALSE;
00341 m_nLength = 0xFFFFFFFF;
00342 m_bConnect = TRUE;
00343
00344 m_mInput.pLimit = m_mOutput.pLimit = &Settings.Bandwidth.Downloads;
00345
00346 theApp.Message( MSG_DEFAULT, IDS_BROWSE_SENT_REQUEST, (LPCTSTR)m_sAddress );
00347 }
00348
00350
00351
00352 BOOL CHostBrowser::ReadResponseLine()
00353 {
00354 CString strLine, strCode, strMessage;
00355
00356 if ( ! m_pInput->ReadLine( strLine ) ) return TRUE;
00357 if ( strLine.IsEmpty() ) return TRUE;
00358
00359 if ( strLine.GetLength() > 512 ) strLine = _T("#LINE_TOO_LONG#");
00360
00361 if ( strLine.GetLength() >= 12 && strLine.Left( 9 ) == _T("HTTP/1.1 ") )
00362 {
00363 strCode = strLine.Mid( 9, 3 );
00364 strMessage = strLine.Mid( 12 );
00365 }
00366 else if ( strLine.GetLength() >= 12 && strLine.Left( 9 ) == _T("HTTP/1.0 ") )
00367 {
00368 strCode = strLine.Mid( 9, 3 );
00369 strMessage = strLine.Mid( 12 );
00370 }
00371 else if ( strLine.GetLength() >= 8 && strLine.Left( 4 ) == _T("HTTP") )
00372 {
00373 strCode = strLine.Mid( 5, 3 );
00374 strMessage = strLine.Mid( 8 );
00375 }
00376 else
00377 {
00378 theApp.Message( MSG_DEBUG, _T("UNKNOWN BROWSE RESPONSE: %s: %s"), (LPCTSTR)m_sAddress, (LPCTSTR)strLine );
00379 theApp.Message( MSG_ERROR, IDS_BROWSE_NOT_HTTP, (LPCTSTR)m_sAddress );
00380 Stop();
00381 return FALSE;
00382 }
00383
00384 if ( strCode == _T("200") || strCode == _T("206") )
00385 {
00386 m_nState = hbsHeaders;
00387 }
00388 else
00389 {
00390 strMessage.TrimLeft();
00391 if ( strMessage.GetLength() > 256 ) strMessage = _T("No Message");
00392
00393 theApp.Message( MSG_ERROR, IDS_BROWSE_HTTPCODE, (LPCTSTR)m_sAddress,
00394 (LPCTSTR)strCode, (LPCTSTR)strMessage );
00395
00396 Stop();
00397 return FALSE;
00398 }
00399
00400 return TRUE;
00401 }
00402
00404
00405
00406 BOOL CHostBrowser::OnHeaderLine(CString& strHeader, CString& strValue)
00407 {
00408 theApp.Message( MSG_DEBUG, _T("%s: BROWSE HEADER: %s: %s"), (LPCTSTR)m_sAddress, (LPCTSTR)strHeader, (LPCTSTR)strValue );
00409
00410 if ( strHeader.CompareNoCase( _T("Server") ) == 0 )
00411 {
00412 m_sServer = strValue;
00413 if ( m_sServer.GetLength() > 64 ) m_sServer = m_sServer.Left( 64 );
00414
00415 m_pVendor = VendorCache.LookupByName( m_sServer );
00416 }
00417 else if ( strHeader.CompareNoCase( _T("Content-Type") ) == 0 )
00418 {
00419 if ( strValue.CompareNoCase( _T("application/x-gnutella-packets") ) == 0 )
00420 m_nProtocol = PROTOCOL_G1;
00421 else if ( strValue.CompareNoCase( _T("application/x-gnutella2") ) == 0 )
00422 m_nProtocol = PROTOCOL_G2;
00423 else if ( strValue.CompareNoCase( _T("application/x-shareaza") ) == 0 )
00424 m_nProtocol = PROTOCOL_G2;
00425 else if ( strValue.CompareNoCase( _T("text/html") ) == 0 )
00426 m_nProtocol = 0;
00427 }
00428 else if ( strHeader.CompareNoCase( _T("Content-Encoding") ) == 0 )
00429 {
00430 m_bDeflate = strValue.CompareNoCase( _T("deflate") ) == 0;
00431 }
00432 else if ( strHeader.CompareNoCase( _T("Content-Length") ) == 0 )
00433 {
00434 _stscanf( strValue, _T("%lu"), &m_nLength );
00435 }
00436
00437 return TRUE;
00438 }
00439
00440 BOOL CHostBrowser::OnHeadersComplete()
00441 {
00442 if ( m_nProtocol < 0 || m_nLength == 0 )
00443 {
00444 theApp.Message( MSG_ERROR, IDS_BROWSE_BAD_RESPONSE, (LPCTSTR)m_sAddress );
00445 Stop();
00446 return FALSE;
00447 }
00448
00449 m_nState = hbsContent;
00450 m_nReceived = 0;
00451 m_pBuffer = new CBuffer();
00452 m_mInput.tLast = GetTickCount();
00453
00454 if ( m_bDeflate )
00455 {
00456 m_pInflate = new z_stream;
00457 z_streamp pStream = (z_streamp)m_pInflate;
00458 ZeroMemory( pStream, sizeof(z_stream) );
00459
00460 if ( inflateInit( pStream ) != Z_OK )
00461 {
00462 delete pStream;
00463 m_pInflate = NULL;
00464 Stop();
00465 return FALSE;
00466 }
00467 }
00468
00469 switch ( m_nProtocol )
00470 {
00471 case 0:
00472 theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
00473 (LPCTSTR)m_sAddress, _T("HTML") );
00474 break;
00475 case PROTOCOL_G1:
00476 theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
00477 (LPCTSTR)m_sAddress, _T("Gnutella-1") );
00478 break;
00479 case PROTOCOL_G2:
00480 theApp.Message( MSG_DEFAULT, IDS_BROWSE_DOWNLOADING_FROM,
00481 (LPCTSTR)m_sAddress, _T("Gnutella-2") );
00482 break;
00483 }
00484
00485 return TRUE;
00486 }
00487
00489
00490
00491 BOOL CHostBrowser::ReadContent()
00492 {
00493 if ( m_nReceived < m_nLength )
00494 {
00495 DWORD nVolume = min( m_nLength - m_nReceived, m_pInput->m_nLength );
00496 m_nReceived += nVolume;
00497
00498 if ( m_bDeflate && m_pInflate != NULL )
00499 {
00500 z_streamp pStream = (z_streamp)m_pInflate;
00501
00502 while ( nVolume || m_pBuffer->m_nLength == m_pBuffer->m_nBuffer || pStream->avail_out == 0 )
00503 {
00504 m_pBuffer->EnsureBuffer( 1024 );
00505
00506 pStream->next_in = m_pInput->m_pBuffer;
00507 pStream->avail_in = m_pInput->m_nLength;
00508 pStream->next_out = m_pBuffer->m_pBuffer + m_pBuffer->m_nLength;
00509 pStream->avail_out = m_pBuffer->m_nBuffer - m_pBuffer->m_nLength;
00510
00511 inflate( pStream, Z_SYNC_FLUSH );
00512
00513 m_pInput->Remove( m_pInput->m_nLength - pStream->avail_in );
00514 nVolume -= ( m_pInput->m_nLength - pStream->avail_in );
00515
00516 DWORD nBlock = ( m_pBuffer->m_nBuffer - m_pBuffer->m_nLength ) - pStream->avail_out;
00517 m_pBuffer->m_nLength += nBlock;
00518 if ( ! nBlock ) break;
00519 }
00520 }
00521 else
00522 {
00523 m_pBuffer->AddBuffer( m_pInput, nVolume );
00524 }
00525 }
00526
00527 switch ( m_nProtocol )
00528 {
00529 case 0:
00530 if ( ! StreamHTML() ) return FALSE;
00531 break;
00532 case PROTOCOL_G1:
00533 if ( ! StreamPacketsG1() ) return FALSE;
00534 break;
00535 case PROTOCOL_G2:
00536 if ( ! StreamPacketsG2() ) return FALSE;
00537 break;
00538 }
00539
00540 if ( m_nReceived < m_nLength ) return TRUE;
00541
00542 Stop( TRUE );
00543
00544 if ( m_pProfile->IsValid() && m_pNotify != NULL ) m_pNotify->OnProfileReceived();
00545
00546 theApp.Message( MSG_SYSTEM, IDS_BROWSE_FINISHED, (LPCTSTR)m_sAddress, m_nHits );
00547
00548 return TRUE;
00549 }
00550
00552
00553
00554 BOOL CHostBrowser::StreamPacketsG1()
00555 {
00556 BOOL bSuccess = TRUE;
00557 for ( ; bSuccess ; )
00558 {
00559 GNUTELLAPACKET* pPacket = (GNUTELLAPACKET*)m_pBuffer->m_pBuffer;
00560 if ( m_pBuffer->m_nLength < sizeof(*pPacket) ) break;
00561
00562 DWORD nLength = sizeof(*pPacket) + pPacket->m_nLength;
00563
00564 if ( pPacket->m_nLength < 0 || nLength >= (DWORD)Settings.Gnutella1.MaximumPacket * 8 )
00565 {
00566 theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
00567 Stop();
00568 return FALSE;
00569 }
00570
00571 if ( m_pBuffer->m_nLength < nLength ) break;
00572
00573 CG1Packet* pPacketObject = CG1Packet::New( pPacket );
00574
00575 try
00576 {
00577 bSuccess = OnPacket( pPacketObject );
00578 }
00579 catch ( CException* pException )
00580 {
00581 pException->Delete();
00582 }
00583
00584 pPacketObject->Release();
00585
00586 m_pBuffer->Remove( nLength );
00587 }
00588
00589 if ( ! bSuccess ) Stop();
00590
00591 return bSuccess;
00592 }
00593
00594 BOOL CHostBrowser::StreamPacketsG2()
00595 {
00596 CG2Packet* pPacket;
00597
00598 while ( pPacket = CG2Packet::ReadBuffer( m_pBuffer ) )
00599 {
00600 BOOL bSuccess = FALSE;
00601
00602 try
00603 {
00604 bSuccess = OnPacket( pPacket );
00605 }
00606 catch ( CException* pException )
00607 {
00608 pException->Delete();
00609 }
00610
00611 pPacket->Release();
00612
00613 if ( ! bSuccess )
00614 {
00615 Stop();
00616 return FALSE;
00617 }
00618 }
00619
00620 return TRUE;
00621 }
00622
00624
00625
00626 BOOL CHostBrowser::OnPacket(CG1Packet* pPacket)
00627 {
00628 if ( pPacket->m_nType != G1_PACKET_HIT || pPacket->m_nLength <= 27 )
00629 return TRUE;
00630
00631 CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
00632
00633 if ( pHits == NULL )
00634 {
00635 theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
00636 return FALSE;
00637 }
00638
00639 m_bCanPush = TRUE;
00640 m_pClientID = pHits->m_pClientID;
00641
00642 for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext ) m_nHits++;
00643
00644 Downloads.OnQueryHits( pHits );
00645
00646 if ( ! m_bCanChat && pHits->m_bChat ) m_bCanChat = TRUE;
00647
00648 if ( m_pNotify != NULL )
00649 m_pNotify->OnBrowseHits( pHits );
00650 else
00651 pHits->Delete();
00652
00653 return TRUE;
00654 }
00655
00656 BOOL CHostBrowser::OnPacket(CG2Packet* pPacket)
00657 {
00658 if ( pPacket->IsType( G2_PACKET_HIT ) )
00659 {
00660 CQueryHit* pHits = CQueryHit::FromPacket( pPacket );
00661
00662 if ( pHits == NULL )
00663 {
00664 theApp.Message( MSG_ERROR, IDS_BROWSE_PACKET_ERROR, (LPCTSTR)m_sAddress );
00665 return FALSE;
00666 }
00667
00668 m_bCanPush = TRUE;
00669 m_pClientID = pHits->m_pClientID;
00670
00671 for ( CQueryHit* pCount = pHits ; pCount ; pCount = pCount->m_pNext )
00672 {
00673 m_nHits++;
00674 }
00675
00676 Downloads.OnQueryHits( pHits );
00677
00678 if ( ! m_bCanChat && pHits->m_bChat )
00679 {
00680 m_bCanChat = TRUE;
00681 if ( m_pNotify && m_pProfile != NULL ) m_pNotify->OnProfileReceived();
00682 }
00683
00684 if ( m_pNotify != NULL )
00685 m_pNotify->OnBrowseHits( pHits );
00686 else
00687 pHits->Delete();
00688 }
00689 else if ( pPacket->IsType( G2_PACKET_PHYSICAL_FOLDER ) )
00690 {
00691 if ( m_pNotify != NULL ) m_pNotify->OnPhysicalTree( pPacket );
00692 }
00693 else if ( pPacket->IsType( G2_PACKET_VIRTUAL_FOLDER ) )
00694 {
00695 if ( m_pNotify != NULL ) m_pNotify->OnVirtualTree( pPacket );
00696 }
00697 else if ( pPacket->IsType( G2_PACKET_PROFILE_DELIVERY ) )
00698 {
00699 OnProfilePacket( pPacket );
00700
00701 if ( m_pProfile != NULL && m_pNotify != NULL )
00702 {
00703 m_pNotify->OnProfileReceived();
00704 }
00705 }
00706 else if ( pPacket->IsType( G2_PACKET_PROFILE_AVATAR ) )
00707 {
00708 if ( m_pNotify != NULL ) m_pNotify->OnHeadPacket( pPacket );
00709 }
00710
00711 return TRUE;
00712 }
00713
00714 void CHostBrowser::OnProfilePacket(CG2Packet* pPacket)
00715 {
00716 CHAR szType[9];
00717 DWORD nLength;
00718
00719 while ( pPacket->ReadPacket( szType, nLength ) )
00720 {
00721 DWORD nOffset = pPacket->m_nPosition + nLength;
00722
00723 if ( strcmp( szType, "XML" ) == 0 )
00724 {
00725 CXMLElement* pXML = CXMLElement::FromString( pPacket->ReadString( nLength ), TRUE );
00726
00727 if ( pXML != NULL )
00728 {
00729 if ( m_pProfile == NULL ) m_pProfile = new CGProfile();
00730 if ( ! m_pProfile->FromXML( pXML ) ) delete pXML;
00731 if ( m_pProfile != NULL && ! m_pProfile->IsValid() )
00732 {
00733 delete m_pProfile;
00734 m_pProfile = NULL;
00735 }
00736 }
00737 }
00738
00739 pPacket->m_nPosition = nOffset;
00740 }
00741 }
00742
00744
00745
00746 BOOL CHostBrowser::StreamHTML()
00747 {
00748 CString strLine;
00749
00750 CQueryHit* pHits = NULL;
00751
00752 while ( m_pBuffer->ReadLine( strLine ) )
00753 {
00754 if ( Settings.General.Debug && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) )
00755 {
00756 theApp.Message( MSG_DEBUG, _T("HTML-BROWSE: %s"), (LPCTSTR)strLine );
00757 }
00758
00759 int nPosHTTP = strLine.Find( _T("http://") );
00760
00761 while ( nPosHTTP >= 0 && strLine.Find( _T("/get/") ) > nPosHTTP )
00762 {
00763 CString strURI = strLine.Mid( nPosHTTP ).SpanExcluding( _T("?&\"'<>") );
00764 CString strName;
00765 DWORD nSize = 0;
00766
00767 int nPosSize = strLine.Find( _T("<TD NOWRAP>") );
00768
00769 if ( nPosSize >= 0 && nPosSize < nPosHTTP )
00770 {
00771 CString strSize = strLine.Mid( nPosSize + 11 ).SpanExcluding( _T("</") );
00772 float nFloat = 0;
00773
00774 if ( _stscanf( strSize, _T("%f"), &nFloat ) == 1 && nFloat > 0 )
00775 {
00776 if ( strSize.Find( _T(" GB") ) >= 0 )
00777 nFloat *= 1024*1024*1024;
00778 else if ( strSize.Find( _T(" MB") ) >= 0 )
00779 nFloat *= 1024*1024;
00780 else if ( strSize.Find( _T(" KB") ) >= 0 )
00781 nFloat *= 1024;
00782
00783 nSize = (DWORD)nFloat;
00784 }
00785 }
00786
00787 strLine = strLine.Mid( nPosHTTP + strURI.GetLength() );
00788
00789 int nPosName = strLine.Find( _T(">") );
00790
00791 if ( nPosName >= 0 )
00792 {
00793 strName = strLine.Mid( nPosName + 1 ).SpanExcluding( _T("<>") );
00794 }
00795
00796 if ( strName.IsEmpty() && ( nPosName = strURI.ReverseFind( '/' ) ) > 0 )
00797 {
00798 strName = URLDecode( strURI.Mid( nPosName + 1 ) );
00799 }
00800
00801 CQueryHit* pHit = new CQueryHit( PROTOCOL_NULL, NULL );
00802
00803 pHit->m_pAddress = m_pHost.sin_addr;
00804 pHit->m_nPort = htons( m_pHost.sin_port );
00805 pHit->m_pVendor = m_pVendor ? m_pVendor : VendorCache.m_pNull;
00806 pHit->m_bPush = ( m_tPushed ) ? TS_TRUE : TS_FALSE;
00807 pHit->m_bBrowseHost = TRUE;
00808 pHit->m_nSize = nSize;
00809 pHit->m_sName = strName;
00810 pHit->m_sURL = strURI;
00811
00812 if ( m_bCanPush ) pHit->m_pClientID = m_pClientID;
00813
00814 pHit->m_pNext = pHits;
00815 pHits = pHit;
00816
00817 m_nHits ++;
00818
00819 nPosHTTP = strLine.Find( _T("http://") );
00820 }
00821 }
00822
00823 if ( pHits != NULL )
00824 {
00825 if ( m_pNotify != NULL )
00826 m_pNotify->OnBrowseHits( pHits );
00827 else
00828 pHits->Delete();
00829 }
00830
00831 return TRUE;
00832 }