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

📄 uploadtransferhttp.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}
	}
	else if ( StartsWith( m_sRequest, _T("/gnutella/preview/v1?urn:") ) && Settings.Uploads.SharePreviews )
	{
		LPCTSTR pszURN = (LPCTSTR)m_sRequest + 21;
		CLibraryFile* pShared = LibraryMaps.LookupFileByURN( pszURN, TRUE, TRUE, TRUE );
		if ( pShared != NULL ) return RequestPreview( pShared );
	}
	else if ( StartsWith( m_sRequest, _T("/uri-res/N2R?urn:") ) )
	{
		LPCTSTR pszURN = (LPCTSTR)m_sRequest + 13;
		
		if ( CLibraryFile* pShared = LibraryMaps.LookupFileByURN( pszURN, TRUE, TRUE, TRUE ) )
		{
			return RequestSharedFile( pShared );
		}
		
		CDownload* pDownload = Downloads.FindByURN( pszURN );
		
		if ( pDownload != NULL && pDownload->IsShared() && pDownload->IsStarted() )
		{
			return RequestPartialFile( pDownload );
		}
	}
	else if ( StartsWith( m_sRequest, _T("/get/") ) )
	{
		DWORD nIndex = 0;
		
		CString strFile	= m_sRequest.Mid( 5 );
		int nChar		= strFile.Find( '/' );
		
		if ( _stscanf( strFile, _T("%lu/"), &nIndex ) == 1 && nChar > 0 && nChar < strFile.GetLength() - 1 )
		{
			strFile = strFile.Mid( nChar + 1 );
			
			CLibraryFile* pFile = Library.LookupFile( nIndex, TRUE, TRUE, TRUE );
			
			if ( pFile != NULL && pFile->m_sName.CompareNoCase( strFile ) )
			{
				Library.Unlock();
				pFile = NULL;
			}
			
			if ( pFile == NULL )
			{
				pFile = LibraryMaps.LookupFileByName( strFile, TRUE, TRUE, TRUE );
			}
			
			if ( pFile != NULL ) return RequestSharedFile( pFile );
		}
		else
		{
			strFile = strFile.Mid( nChar + 1 );
			CLibraryFile* pFile = LibraryMaps.LookupFileByName( strFile, TRUE, TRUE, TRUE );
			if ( pFile != NULL ) return RequestSharedFile( pFile );
		}
	}
	else
	{
		CString strFile = m_sRequest.Mid( 1 );
		CLibraryFile* pFile = LibraryMaps.LookupFileByName( strFile, TRUE, TRUE, TRUE );
		if ( pFile != NULL ) return RequestSharedFile( pFile );
	}
	
	if ( m_sFileName.IsEmpty() )
	{
		if ( m_bSHA1 ) m_sFileName = CSHA::HashToString( &m_pSHA1, TRUE );
	}
	
	SendResponse( IDR_HTML_FILENOTFOUND );
	theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
	
	return TRUE;
}

BOOL CUploadTransferHTTP::IsNetworkDisabled()
{
	if ( Settings.Connection.RequireForTransfers == FALSE ) return FALSE;
	
	if ( m_nGnutella == 2 )
	{
		if ( ! Settings.Gnutella2.EnableToday ) return TRUE;
	}
	else if ( m_nGnutella == 1 )
	{
		if ( ! Settings.Gnutella1.EnableToday ) return TRUE;
	}
	else
	{
		if ( ! Settings.Gnutella1.EnableToday &&
			 ! Settings.Gnutella2.EnableToday ) return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request a shared file

BOOL CUploadTransferHTTP::RequestSharedFile(CLibraryFile* pFile)
{
	ASSERT( pFile != NULL );
	
	if ( ! RequestComplete( pFile ) )
	{
		Library.Unlock();
		SendResponse( IDR_HTML_HASHMISMATCH );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_HASH_MISMATCH, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		return TRUE;
	}
	
	m_bTigerTree	= m_bTiger;
	m_bMetadata		= ( pFile->m_pMetadata != NULL && ( pFile->m_bMetadataAuto == FALSE || pFile->m_nVirtualSize > 0 ) );
	
	if ( ! m_bSHA1 && ! m_bTiger && ! m_bED2K ) m_sLocations.Empty();
	
	if ( m_nLength == SIZE_UNKNOWN ) m_nLength = m_nFileSize - m_nOffset;
	
	if ( m_nOffset >= m_nFileSize || m_nOffset + m_nLength > m_nFileSize )
	{
		Library.Unlock();
		SendResponse( IDR_HTML_BADRANGE );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_BAD_RANGE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		return TRUE;
	}
	
	CString strLocations;
	if ( Settings.Library.SourceMesh ) strLocations = pFile->GetAlternateSources( &m_pSourcesSent, 15, TRUE );
	if ( m_sLocations.GetLength() ) pFile->AddAlternateSources( m_sLocations );
	m_sLocations = strLocations;
	
	Library.Unlock();
	
	return QueueRequest();
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request a partial file

BOOL CUploadTransferHTTP::RequestPartialFile(CDownload* pDownload)
{
	ASSERT( pDownload != NULL );
	ASSERT( pDownload->IsStarted() );
	
	if ( ! RequestPartial( pDownload ) )
	{
		SendResponse( IDR_HTML_HASHMISMATCH );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_HASH_MISMATCH, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		return TRUE;
	}
	
	ASSERT( m_nFileBase == 0 );
	
	m_bTigerTree	= ( m_bTiger && pDownload->GetTigerTree() != NULL );
	m_bMetadata		= ( pDownload->m_pXML != NULL );
	
	if ( m_sLocations.GetLength() ) pDownload->AddSourceURLs( m_sLocations, TRUE );
	if ( Settings.Library.SourceMesh ) m_sLocations = pDownload->GetSourceURLs( &m_pSourcesSent, 15, TRUE, NULL );
	
	m_sRanges = pDownload->GetAvailableRanges();
	
	if ( m_bRange && m_nOffset == 0 && m_nLength == SIZE_UNKNOWN )
	{
		pDownload->GetRandomRange( m_nOffset, m_nLength );
	}
	
	if ( m_nLength == SIZE_UNKNOWN ) m_nLength = m_nFileSize - m_nOffset;
	
	if ( pDownload->ClipUploadRange( m_nOffset, m_nLength ) )
	{
		return QueueRequest();
	}
	
	if ( pDownload->IsMoving() )
	{
		if ( GetTickCount() - pDownload->m_tCompleted < 30000 )
		{
			m_pOutput->Print( "HTTP/1.1 503 Range Temporarily Unavailable\r\n" );
		}
		else
		{
			SendResponse( IDR_HTML_FILENOTFOUND );
			theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
			return TRUE;
		}
	}
	else if ( pDownload->GetTransferCount() )
	{
		m_pOutput->Print( "HTTP/1.1 503 Range Temporarily Unavailable\r\n" );
	}
	else
	{
		m_pOutput->Print( "HTTP/1.1 416 Requested Range Unavailable\r\n" );
	}
	
	SendDefaultHeaders();
	SendFileHeaders();
	
	m_pOutput->Print( "Content-Length: 0\r\n" );
	m_pOutput->Print( "\r\n" );
	
	StartSending( upsResponse );
	
	theApp.Message( MSG_DEFAULT, IDS_UPLOAD_BAD_RANGE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP queue the request if necessary

BOOL CUploadTransferHTTP::QueueRequest()
{
	if ( m_bHead ) return OpenFileSendHeaders();
	
	AllocateBaseFile();
	
	UINT nError		= 0;
	int nPosition	= 0;
	
	if ( Uploads.AllowMoreTo( &m_pHost.sin_addr ) )
	{
		if ( ( nPosition = UploadQueues.GetPosition( this, TRUE ) ) >= 0 )
		{
			ASSERT( m_pQueue != NULL );
			ASSERT( m_pQueue->CanAccept( m_nProtocol, m_sFileName, m_nFileSize, m_bFilePartial, m_sFileTags ) );
			
			if ( nPosition == 0 )
			{
				// Queued, and ready to send
				return OpenFileSendHeaders();
			}
			else
			{
				// Queued, but must wait
			}
		}
		else if ( UploadQueues.Enqueue( this ) )
		{
			ASSERT( m_pQueue != NULL );
			ASSERT( m_pQueue->CanAccept( m_nProtocol, m_sFileName, m_nFileSize, m_bFilePartial, m_sFileTags ) );
			
			nPosition = UploadQueues.GetPosition( this, TRUE );
			ASSERT( nPosition >= 0 );
			
			if ( nPosition == 0 )
			{
				// Queued, and ready to send
				return OpenFileSendHeaders();
			}
			else if ( m_bQueueMe )
			{
				// Queued, but must wait
			}
			else
			{
				// Client can't queue, so dequeue and return busy
				UploadQueues.Dequeue( this );
				ASSERT( m_pQueue == NULL );
			}
		}
		else
		{
			// Unable to queue anywhere
		}
	}
	else
	{
		// Too many from this host
		
		UploadQueues.Dequeue( this );
		ASSERT( m_pQueue == NULL );
        
		nError = IDS_UPLOAD_BUSY_HOST;
	}
	
	if ( m_pQueue != NULL )
	{
		CString strHeader, strName;
		
		m_pOutput->Print( "HTTP/1.1 503 Busy Queued\r\n" );
		
		SendDefaultHeaders();
		SendFileHeaders();
		
		DWORD nTimeScale = ( nPosition <= 2 ) ? 2000 : 1000;
		
		CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
		
		if ( UploadQueues.Check( m_pQueue ) )
		{
			strName = m_pQueue->m_sName;
			Replace( strName, _T("\""), _T("'") );
			
			strHeader.Format( _T("X-Queue: position=%i,length=%i,limit=%i,pollMin=%lu,pollMax=%lu,id=\"%s\"\r\n"),
				nPosition,
				m_pQueue->GetQueuedCount(),
				m_pQueue->GetTransferCount( TRUE ),
				Settings.Uploads.QueuePollMin / nTimeScale,
				Settings.Uploads.QueuePollMax / nTimeScale,
				(LPCTSTR)strName );
			
			theApp.Message( MSG_DEFAULT, IDS_UPLOAD_QUEUED, (LPCTSTR)m_sFileName,
				(LPCTSTR)m_sAddress, nPosition, m_pQueue->GetQueuedCount(),
				(LPCTSTR)strName );
		}
		
		pLock.Unlock();
		
		m_pOutput->Print( strHeader );
		m_pOutput->Print( "Content-Length: 0\r\n" );
		m_pOutput->Print( "\r\n" );
		
		StartSending( upsPreQueue );
	}
	else
	{
		SendResponse( IDR_HTML_BUSY, TRUE );
		
		if ( ! nError ) nError = m_bQueueMe ? IDS_UPLOAD_BUSY_QUEUE : IDS_UPLOAD_BUSY_OLD;
		theApp.Message( MSG_ERROR, nError, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP default response headers

void CUploadTransferHTTP::SendDefaultHeaders()
{
	CString strLine = Settings.SmartAgent( Settings.General.UserAgent );
	
	if ( strLine.GetLength() )
	{
		strLine = _T("Server: ") + strLine + _T("\r\n");
		m_pOutput->Print( strLine );
	}
	
	if ( ! m_bInitiated )
	{
		strLine.Format( _T("Remote-IP: %s\r\n"),
			(LPCTSTR)CString( inet_ntoa( m_pHost.sin_addr ) ) );
		m_pOutput->Print( strLine );
	}
	
	if ( m_bKeepAlive )
	{
		m_pOutput->Print( "Connection: Keep-Alive\r\n" );
	}
	else
	{
		m_pOutput->Print( "Connection: Close\r\n" );
	}
	
	m_pOutput->Print( "Accept-Ranges: bytes\r\n" );
	
	if ( m_nRequests <= 1 )
	{
		if ( m_bInitiated ) SendMyAddress();
		strLine.Format( _T("X-PerHost: %lu\r\n"), Settings.Uploads.MaxPerHost );
		m_pOutput->Print( strLine );
		
		strLine = MyProfile.GetNick();
		
		if ( strLine.GetLength() > 0 )
		{
			strLine = _T("X-Nick: ") + URLEncode( strLine ) + _T("\r\n");
			m_pOutput->Print( strLine );
		}
	}
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP file response headers

void CUploadTransferHTTP::SendFileHeaders()
{
	CString strHeader;
	
	if ( m_bSHA1 )
	{
		if ( m_bTiger )
		{
			strHeader	= _T("X-Content-URN: urn:bitprint:")
						+ CSHA::HashToString( &m_pSHA1, FALSE ) + '.'
						+ CTigerNode::HashToString( &m_pTiger, FALSE ) + _T("\r\n");
		}
		else
		{
			strHeader = _T("X-Content-URN: ") + CSHA::HashToString( &m_pSHA1, TRUE ) + _T("\r\n");
		}
		
		m_pOutput->Print( strHeader );
	}
	else if ( m_bTiger )
	{
		strHeader = _T("X-Content-URN: ") + CTigerNode::HashToString( &m_pTiger, TRUE ) + _T("\r\n");
		m_pOutput->Print( strHeader );
	}
	
	if ( m_bED2K )
	{
		strHeader = _T("X-Content-URN: ") + CED2K::HashToString( &m_pED2K, TRUE ) + _T("\r\n");
		m_pOutput->Print( strHeader );
	}
	
	if ( m_bTigerTree && Settings.Uploads.ShareTiger )
	{
		strHeader	= _T("X-Thex-URI: /gnutella/thex/v1?")
					+ CTigerNode::HashToString( &m_pTiger, TRUE )
					+ _T("&depth=9&ed2k=0\r\n");
		m_pOutput->Print( strHeader );
	}
	
	if ( m_bMetadata )
	{
		strHeader	= _T("X-Metadata-Path: /gnutella/metadata/v1?")
					+ CTigerNode::HashToString( &m_pTiger, TRUE )
					+ _T("\r\n");
		m_pOutput->Print( strHeader );
	}
	
	if ( m_sRanges.GetLength() )
	{
		strHeader = _T("X-Available-Ranges: ") + m_sRanges + _T("\r\n");
		m_pOutput->Print( strHeader );
	}
	
	if ( m_sLocations.GetLength() )
	{

⌨️ 快捷键说明

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