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

📄 uploadtransferhttp.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		strHeader = _T("Alt-Location: ") + m_sLocations + _T("\r\n");
		m_pOutput->Print( strHeader );
	}
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP open file and send headers

BOOL CUploadTransferHTTP::OpenFileSendHeaders()
{
	ASSERT( m_pDiskFile == NULL );
	
	m_pDiskFile = TransferFiles.Open( m_sFilePath, FALSE, FALSE );
	
	if ( m_pDiskFile == NULL )
	{
		SendResponse( IDR_HTML_FILENOTFOUND );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_CANTOPEN, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
		return TRUE;
	}
	
	CSingleLock pLock( &UploadQueues.m_pSection, TRUE );
	
	if ( m_pQueue != NULL && UploadQueues.Check( m_pQueue ) && m_pQueue->m_bRotate )
	{
		DWORD nLimit = m_pQueue->m_nRotateChunk;
		if ( nLimit == 0 ) nLimit = Settings.Uploads.RotateChunkLimit;
		if ( nLimit > 0 ) m_nLength = min( m_nLength, nLimit );
	}
	
	pLock.Unlock();
	
	if ( m_nLength != m_nFileSize )
		m_pOutput->Print( "HTTP/1.1 206 OK\r\n" );
	else
		m_pOutput->Print( "HTTP/1.1 200 OK\r\n" );
	
	SendDefaultHeaders();
	
	CString strExt, strResponse;
	
	int nType = m_sFileName.ReverseFind( '.' );
	if ( nType > 0 ) strExt = m_sFileName.Mid( nType );
	ShellIcons.Lookup( strExt, NULL, NULL, NULL, &strResponse );
	
	if ( strResponse.IsEmpty() )
	{
		m_pOutput->Print( "Content-Type: application/x-binary\r\n" );
	}
	else
	{
		strResponse = _T("Content-Type: ") + strResponse + _T("\r\n");
		m_pOutput->Print( strResponse );
	}
	
	strResponse.Format( _T("Content-Length: %I64i\r\n"), m_nLength );
	m_pOutput->Print( strResponse );
	
	if ( m_nLength != m_nFileSize )
	{
		strResponse.Format( _T("Content-Range: bytes=%I64i-%I64i/%I64i\r\n"), m_nOffset, m_nOffset + m_nLength - 1, m_nFileSize );
		m_pOutput->Print( strResponse );
	}
	
	if ( ! m_bHead && m_bBackwards )
	{
		m_pOutput->Print( "Content-Encoding: backwards\r\n" );
	}
	
	if ( m_bSHA1 || m_bTiger || m_bED2K ) SendFileHeaders();
	
	m_pOutput->Print( "\r\n" );
	
	if ( m_bHead )
	{
		m_pDiskFile->Release( FALSE );
		m_pDiskFile = NULL;
		
		theApp.Message( MSG_DEFAULT, IDS_UPLOAD_HEADERS, (LPCTSTR)m_sFileName,
			(LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );
		
		StartSending( upsResponse );
	}
	else
	{
		if ( m_pBaseFile->m_nRequests++ == 0 )
		{
			theApp.Message( MSG_SYSTEM, IDS_UPLOAD_FILE,
				(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
			
			if ( CLibraryFile* pFile = LibraryMaps.LookupFileByPath( m_sFilePath, TRUE, TRUE, TRUE ) )
			{
				pFile->m_nUploadsToday++;
				pFile->m_nUploadsTotal++;
				Library.Unlock();
			}
		}
		
		theApp.Message( MSG_DEFAULT,
			m_sRanges.GetLength() ? IDS_UPLOAD_PARTIAL_CONTENT : IDS_UPLOAD_CONTENT,
			m_nOffset, m_nOffset + m_nLength - 1, (LPCTSTR)m_sFileName,
			(LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );
		
		StartSending( upsUploading );
	}
	
	OnWrite();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP write handler

BOOL CUploadTransferHTTP::OnWrite()
{
	if ( m_nState == upsUploading && m_pDiskFile != NULL && m_pOutput->m_nLength == 0 )
	{
		if ( m_nPosition >= m_nLength )
		{
			OnCompleted();
			CUploadTransfer::OnWrite();
			return TRUE;
		}
		
		QWORD nPacket = min( m_nLength - m_nPosition, (QWORD)Transfers.m_nBuffer );
		BYTE* pBuffer = Transfers.m_pBuffer;
		
		if ( m_bBackwards )
		{
			QWORD nRead = 0;
			m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nLength - m_nPosition - nPacket, pBuffer, nPacket, &nRead );
			if ( nRead != nPacket ) return TRUE;
			m_pOutput->AddReversed( pBuffer, (DWORD)nPacket );
		}
		else
		{
			m_pDiskFile->Read( m_nFileBase + m_nOffset + m_nPosition, pBuffer, nPacket, &nPacket );
			if ( nPacket == 0 ) return TRUE;
			m_pOutput->Add( pBuffer, (DWORD)nPacket );
		}
		
		m_nPosition += nPacket;
		m_nUploaded += nPacket;
		
		Statistics.Current.Uploads.Volume += ( nPacket / 1024 );
	}
	
	CUploadTransfer::OnWrite();
	
	if ( m_nState >= upsResponse && m_pOutput->m_nLength == 0 )
	{
		m_nState	= ( m_nState == upsPreQueue ) ? upsQueued : upsRequest;
		m_tRequest	= GetTickCount();
	}
	
	return TRUE;
}

void CUploadTransferHTTP::OnCompleted()
{
	Uploads.SetStable( GetAverageSpeed() );
	
	m_pDiskFile->Release( FALSE );
	m_pDiskFile	= NULL;
	m_nState	= upsRequest;
	m_tRequest	= GetTickCount();
	
	m_pBaseFile->AddFragment( m_nOffset, m_nLength );
	// m_pBaseFile = NULL;
	
	theApp.Message( MSG_DEFAULT, IDS_UPLOAD_FINISHED, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP run handler

BOOL CUploadTransferHTTP::OnRun()
{
	CUploadTransfer::OnRun();
	
	DWORD tNow = GetTickCount();
	
	switch ( m_nState )
	{
	case upsRequest:
		if ( ! m_bKeepAlive && m_pOutput->m_nLength == 0 )
		{
			theApp.Message( MSG_DEFAULT, IDS_UPLOAD_DROPPED, (LPCTSTR)m_sAddress );
			Close();
			return FALSE;
		}

	case upsHeaders:
		if ( tNow - m_tRequest > Settings.Connection.TimeoutHandshake )
		{
			theApp.Message( MSG_ERROR, IDS_UPLOAD_REQUEST_TIMEOUT, (LPCTSTR)m_sAddress );
			Close();
			return FALSE;
		}
		break;

	case upsQueued:
		if ( tNow - m_tRequest > Settings.Uploads.QueuePollMax )
		{
			theApp.Message( MSG_ERROR, IDS_UPLOAD_REQUEST_TIMEOUT, (LPCTSTR)m_sAddress );
			Close();
			return FALSE;
		}
		break;

	case upsUploading:
	case upsResponse:
	case upsBrowse:
	case upsTigerTree:
	case upsMetadata:
	case upsPreview:
	case upsPreQueue:
		if ( tNow - m_mOutput.tLast > Settings.Connection.TimeoutTraffic )
		{
			theApp.Message( MSG_ERROR, IDS_UPLOAD_TRAFFIC_TIMEOUT, (LPCTSTR)m_sAddress );
			Close();
			return FALSE;
		}
		break;
		
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP dropped handler

void CUploadTransferHTTP::OnDropped(BOOL bError)
{
	theApp.Message( MSG_DEFAULT, IDS_UPLOAD_DROPPED, (LPCTSTR)m_sAddress );
	
	if ( m_nState == upsUploading && m_pBaseFile != NULL )
	{
		if ( m_bBackwards )
		{
			m_pBaseFile->AddFragment( m_nOffset + m_nLength - m_nPosition, m_nPosition );
		}
		else
		{
			m_pBaseFile->AddFragment( m_nOffset, m_nPosition );
		}
		
		m_pBaseFile = NULL;
	}
	
	Close();
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request metadata

BOOL CUploadTransferHTTP::RequestMetadata(CXMLElement* pMetadata)
{
	ASSERT( pMetadata != NULL );
	CString strXML = pMetadata->ToString( TRUE, TRUE );
	delete pMetadata;
	
#ifdef _UNICODE
	int nXML = WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), NULL, 0, NULL, NULL );
	LPSTR pszXML = new CHAR[ nXML ];
	WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), pszXML, nXML, NULL, NULL );
#else
	int nXML = strXML.GetLength();
	LPCSTR pszXML = (LPCSTR)strXML;
#endif
	
	m_pOutput->Print( "HTTP/1.1 200 OK\r\n" );
	SendDefaultHeaders();
	m_pOutput->Print( "Content-Type: text/xml\r\n" );
	
	CString strHeader;
	strHeader.Format( _T("Content-Length: %lu\r\n"), nXML );
	m_pOutput->Print( strHeader );
	m_pOutput->Print( "\r\n" );
	
	if ( ! m_bHead ) m_pOutput->Add( pszXML, nXML );
#ifdef _UNICODE
	delete [] pszXML;
#endif
	
	StartSending( upsMetadata );
	
	theApp.Message( MSG_DEFAULT, IDS_UPLOAD_METADATA_SEND,
		(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request a tiger tree hash, raw format

BOOL CUploadTransferHTTP::RequestTigerTreeRaw(CTigerTree* pTigerTree, BOOL bDelete)
{
	if ( pTigerTree == NULL )
	{
		ClearHashes();
		m_sLocations.Empty();
		
		SendResponse( IDR_HTML_FILENOTFOUND, TRUE );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		
		return TRUE;
	}
	
	BYTE* pSerialTree;
	DWORD nSerialTree;
	
	pTigerTree->ToBytes( &pSerialTree, &nSerialTree );
	if ( bDelete ) delete pTigerTree;
	
	if ( m_bRange )
	{
		if ( m_nOffset >= nSerialTree ) m_nLength = SIZE_UNKNOWN;
		else m_nLength = min( m_nLength, nSerialTree - m_nOffset );
	}
	else
	{
		m_nOffset = 0;
		m_nLength = nSerialTree;
	}
	
	if ( m_nLength <= nSerialTree )
	{
		CString strHeader;
		
		if ( m_nLength != nSerialTree )
			m_pOutput->Print( "HTTP/1.1 206 OK\r\n" );
		else
			m_pOutput->Print( "HTTP/1.1 200 OK\r\n" );
		
		SendDefaultHeaders();
		
		m_pOutput->Print( "Content-Type: application/tigertree-breadthfirst\r\n" );
		strHeader.Format( _T("Content-Length: %I64i\r\n"), m_nLength );
		m_pOutput->Print( strHeader );
		
		if ( m_nLength != nSerialTree )
		{
			strHeader.Format( _T("Content-Range: %I64i-%I64i\r\n"), m_nOffset, m_nOffset + m_nLength - 1 );
			m_pOutput->Print( strHeader );
		}
		
		m_pOutput->Print( "\r\n" );
		
		if ( ! m_bHead ) m_pOutput->Add( pSerialTree + m_nOffset, (DWORD)m_nLength );
		
		StartSending( upsTigerTree );
		
		theApp.Message( MSG_DEFAULT, IDS_UPLOAD_TIGER_SEND,
			(LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
	}
	else
	{
		m_sRanges.Format( _T("0-%I64i"), (QWORD)nSerialTree - 1 );
		ClearHashes();
		m_sLocations.Empty();
		
		SendResponse( IDR_HTML_BADRANGE, TRUE );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_BAD_RANGE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
	}
	
	delete [] pSerialTree;
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request a tiger tree hash, DIME format

BOOL CUploadTransferHTTP::RequestTigerTreeDIME(CTigerTree* pTigerTree, int nDepth, CED2K* pHashset, BOOL bDelete)
{
	if ( pTigerTree == NULL )
	{
		ClearHashes();
		m_sLocations.Empty();
		
		SendResponse( IDR_HTML_FILENOTFOUND, TRUE );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		
		if ( pHashset != NULL && bDelete ) delete pHashset;
		
		return TRUE;
	}
	
	DWORD nSerialTree;
	BYTE* pSerialTree;
	CBuffer pDIME;
	
	if ( nDepth < 1 ) nDepth = pTigerTree->GetHeight();
	else if ( nDepth > (int)pTigerTree->GetHeight() ) nDepth = pTigerTree->GetHeight();
	
	pTigerTree->ToBytes( &pSerialTree, &nSerialTree, nDepth );
	if ( bDelete ) delete pTigerTree;
	
	CString strUUID, strXML;
	GUID pUUID;
	
	Network.CreateID( (GGUID*)&pUUID );
	strUUID.Format( _T("uuid:%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x"),
		pUUID.Data1, pUUID.Data2, pUUID.Data3,
		pUUID.Data4[0], pUUID.Data4[1], pUUID.Data4[2], pUUID.Data4[3],
		pUUID.Data4[4], pUUID.Data4[5], pUUID.Data4[6], pUUID.Data4[7] );
	
	strXML.Format(	_T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n")
					_T("<!DOCTYPE hashtree SYSTEM \"http://open-content.net/spec/thex/thex.dtd\">\r\n")
					_T("<hashtree>\r\n")
					_T("\t<file size=\"%I64i\" segmentsize=\"1024\"/>\r\n")
					_T("\t<digest algorithm=\"http://open-content.net/spec/digest/tiger\" outputsize=\"24\"/>\r\n")
					_T("\t<serializedtree depth=\"%i\" type=\"http://open-content.net/spec/thex/breadthfirst\" uri=\"%s\"/>\r\n")
					_T("</hashtree>"),
					m_nFileSize, nDepth, (LPCTSTR)strUUID );
	
#ifdef _UNICODE
	int nXML = WideCharToMultiByte( CP_UTF8, 0, strXML, -1, NULL, 0, NULL, NULL );
	LPSTR pszXML = new CHAR[ nXML ];
	WideCharToMultiByte( CP_UTF8, 0, strXML, -1, pszXML, nXML, NULL, NULL );
	int nUUID = WideCharToMultiByte( CP_ACP, 0, strUUID, -1, NULL, 0, NULL, NULL );
	LPSTR pszUUID = new CHAR[ nUUID ];
	WideCharToMultiByte( CP_ACP, 0, strUUID, -1, pszUUID, nUUID, NULL, NULL );
#else
	LPCSTR pszXML	= strXML;
	LPCSTR pszUUID	= strUUID;
#endif
	

⌨️ 快捷键说明

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