Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

HostBrowser.cpp

Go to the documentation of this file.
00001 //
00002 // HostBrowser.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // CHostBrowser construction
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 // CHostBrowser browse control
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 // CHostBrowser event handling
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 // CHostBrowser push handling
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 // CHostBrowser send request
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 // CHostBrowser read response line
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 // CHostBrowser read headers
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 // CHostBrowser read content
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 // CHostBrowser packet streaming
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 // CHostBrowser packet interpreter
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 // CHostBrowser HTML streaming
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 }

Generated on Thu Dec 15 10:39:43 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2