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

📄 uploadtransferhttp.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	pDIME.WriteDIME( 1, "", "text/xml", pszXML, strlen(pszXML) );
	pDIME.WriteDIME( pHashset ? 0 : 2, pszUUID, "http://open-content.net/spec/thex/breadthfirst", pSerialTree, nSerialTree );
	delete [] pSerialTree;
	
#ifdef _UNICODE
	delete [] pszUUID;
	delete [] pszXML;
#endif
	
	if ( pHashset != NULL )
	{
		pHashset->ToBytes( &pSerialTree, &nSerialTree );
		if ( bDelete ) delete pHashset;
		
		pDIME.WriteDIME( 2, "", "http://edonkey2000.com/spec/md4-hashset", pSerialTree, nSerialTree );
		delete [] pSerialTree;
	}
	
	if ( m_bRange )
	{
		if ( m_nOffset >= (QWORD)pDIME.m_nLength ) m_nLength = SIZE_UNKNOWN;
		else m_nLength = min( m_nLength, (QWORD)pDIME.m_nLength - m_nOffset );
	}
	else
	{
		m_nOffset = 0;
		m_nLength = (QWORD)pDIME.m_nLength;
	}
	
	if ( m_nLength <= pDIME.m_nLength )
	{
		CString strHeader;
		
		if ( m_nLength != pDIME.m_nLength )
			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/dime\r\n" );
		strHeader.Format( _T("Content-Length: %I64i\r\n"), m_nLength );
		m_pOutput->Print( strHeader );
		
		if ( m_nLength != pDIME.m_nLength )
		{
			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( pDIME.m_pBuffer + 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)pDIME.m_nLength - 1 );
		ClearHashes();
		m_sLocations.Empty();
		
		SendResponse( IDR_HTML_BADRANGE, TRUE );
		theApp.Message( MSG_ERROR, IDS_UPLOAD_BAD_RANGE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request preview

BOOL CUploadTransferHTTP::RequestPreview(CLibraryFile* pFile)
{
	ASSERT( pFile != NULL );
	
	m_sFileName		= pFile->m_sName;
	m_sFilePath		= pFile->GetPath();
	m_bSHA1			= pFile->m_bSHA1;
	m_pSHA1			= pFile->m_pSHA1;
	m_bTiger		= pFile->m_bTiger;
	m_pTiger		= pFile->m_pTiger;
	m_bED2K			= pFile->m_bED2K;
	m_pED2K			= pFile->m_pED2K;
	DWORD nIndex	= pFile->m_nIndex;
	BOOL bCached	= pFile->m_bCachedPreview;
	
	Library.Unlock();
	
	int nExisting = Uploads.GetCount( this, upsPreview );
	
	if ( nExisting >= (int)Settings.Uploads.PreviewTransfers )
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_PREVIEW_BUSY, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
		m_pOutput->Print( "HTTP/1.1 503 Busy\r\n" );
		SendDefaultHeaders();
		StartSending( upsResponse );
		return TRUE;
	}
	
	CImageServices pServices;
	CImageFile pImage( &pServices );
	CThumbCache pCache;
	CSize szThumb( 0, 0 );
	
	if ( pCache.Load( m_sFilePath, &szThumb, nIndex, &pImage ) )
	{
		// Got a cached copy
	}
	else if ( Settings.Uploads.DynamicPreviews && pImage.LoadFromFile( m_sFilePath, FALSE, TRUE ) && pImage.EnsureRGB() )
	{
		theApp.Message( MSG_DEFAULT, IDS_UPLOAD_PREVIEW_DYNAMIC, (LPCTSTR)m_sFileName, (LPCTSTR)m_sAddress );
		
		int nSize = szThumb.cy * pImage.m_nWidth / pImage.m_nHeight;
		
		if ( nSize > szThumb.cx )
		{
			nSize = szThumb.cx * pImage.m_nHeight / pImage.m_nWidth;
			pImage.Resample( szThumb.cx, nSize );
		}
		else
		{
			pImage.Resample( nSize, szThumb.cy );
		}
		
		pCache.Store( m_sFilePath, &szThumb, nIndex, &pImage );
	}
	else
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_PREVIEW_EMPTY, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		SendResponse( IDR_HTML_FILENOTFOUND );
		return TRUE;
	}
	
	if ( ! bCached )
	{
		if ( pFile = Library.LookupFile( nIndex, TRUE ) )
		{
			pFile->m_bCachedPreview = TRUE;
			Library.Unlock( TRUE );
		}
	}
	
	BYTE* pBuffer = NULL;
	DWORD nLength = 0;
	
	int nQuality = Settings.Uploads.PreviewQuality;
	
	if ( LPCTSTR pszQuality = _tcsistr( m_sRequest, _T("&quality=") ) )
	{
		_stscanf( pszQuality + 9, _T("%i"), &nQuality );
		nQuality = max( 1, min( 100, nQuality ) );
	}
	
	if ( ! pImage.SaveToMemory( _T(".jpg"), nQuality, &pBuffer, &nLength ) )
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_PREVIEW_EMPTY, (LPCTSTR)m_sAddress, (LPCTSTR)m_sFileName );
		SendResponse( IDR_HTML_FILENOTFOUND );
		return TRUE;
	}
	
	pServices.Cleanup();
	
	m_pOutput->Print( "HTTP/1.1 200 OK\r\n" );
	SendDefaultHeaders();
	
	CString strHeader;
	
	if ( m_bSHA1 )
	{
		strHeader.Format( _T("X-Previewed-URN: %s\r\n"),
			(LPCTSTR)CSHA::HashToString( &m_pSHA1, TRUE ) );
	}
	else if ( m_bTiger )
	{
		strHeader.Format( _T("X-Previewed-URN: %s\r\n"),
			(LPCTSTR)CTigerNode::HashToString( &m_pTiger, TRUE ) );
	}
	else if ( m_bED2K )
	{
		strHeader.Format( _T("X-Previewed-URN: %s\r\n"),
			(LPCTSTR)CED2K::HashToString( &m_pED2K, TRUE ) );
	}
	
	m_pOutput->Print( strHeader );
	
	m_pOutput->Print( "Content-Type: image/jpeg\r\n" );
	
	strHeader.Format( _T("Content-Length: %lu\r\n"), nLength );
	m_pOutput->Print( strHeader );
	
	m_pOutput->Print( "\r\n" );
	
	if ( ! m_bHead )
	{
		m_pOutput->Add( pBuffer, nLength );
	}
	
	delete [] pBuffer;
	
	StartSending( upsPreview );
	
	theApp.Message( MSG_DEFAULT, IDS_UPLOAD_PREVIEW_SEND, (LPCTSTR)m_sFileName,
		(LPCTSTR)m_sAddress );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP request host browse

BOOL CUploadTransferHTTP::RequestHostBrowse()
{
	CBuffer pBuffer;
	
	int nExisting = Uploads.GetCount( this, upsBrowse );
	
	if ( nExisting >= (int)Settings.Uploads.PreviewTransfers )
	{
		theApp.Message( MSG_ERROR, IDS_UPLOAD_BROWSE_BUSY, (LPCTSTR)m_sAddress );
		m_pOutput->Print( "HTTP/1.1 503 Busy\r\n" );
		SendDefaultHeaders();
		StartSending( upsResponse );
		return TRUE;
	}
	
	if ( m_bHostBrowse < 2 )
	{
		if ( Settings.Community.ServeFiles )
		{
			CLocalSearch pSearch( NULL, &pBuffer, PROTOCOL_G1 );
			pSearch.Execute( 0 );
		}
	}
	else
	{
		if ( Settings.Community.ServeProfile && MyProfile.IsValid() )
		{
			CG2Packet* pProfile = CG2Packet::New( G2_PACKET_PROFILE_DELIVERY, TRUE );
			CString strXML = MyProfile.GetXML()->ToString( TRUE );
			pProfile->WritePacket( "XML", pProfile->GetStringLen( strXML ) );
			pProfile->WriteString( strXML, FALSE );
			pProfile->ToBuffer( &pBuffer );
			pProfile->Release();
		}
		
		if ( Settings.Community.ServeFiles )
		{
			CLocalSearch pSearch( NULL, &pBuffer, PROTOCOL_G2 );
			pSearch.Execute( 0 );
			pSearch.WriteVirtualTree();
		}
		
		if ( Settings.Community.ServeProfile && MyProfile.IsValid() )
		{
			if ( CG2Packet* pAvatar = MyProfile.CreateAvatar() )
			{
				pAvatar->ToBuffer( &pBuffer );
				pAvatar->Release();
			}
		}
	}
	
	m_pOutput->Print( "HTTP/1.1 200 OK\r\n" );
	SendDefaultHeaders();
	
	if ( m_bHostBrowse < 2 )
	{
		m_pOutput->Print( "Content-Type: application/x-gnutella-packets\r\n" );
	}
	else
	{
		m_pOutput->Print( "Content-Type: application/x-gnutella2\r\n" );
	}
	
	m_bDeflate = m_bDeflate && pBuffer.Deflate( TRUE );
	
	if ( m_bDeflate ) m_pOutput->Print( "Content-Encoding: deflate\r\n" );
	
	CString strLength;
	strLength.Format( _T("Content-Length: %lu\r\n\r\n"), pBuffer.m_nLength );
	m_pOutput->Print( strLength );
	
	if ( ! m_bHead ) m_pOutput->AddBuffer( &pBuffer );
	
	StartSending( upsBrowse );
	
	theApp.Message( MSG_SYSTEM, IDS_UPLOAD_BROWSE, (LPCTSTR)m_sAddress, (LPCTSTR)m_sUserAgent );
	
	CTransfer::OnWrite();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CUploadTransferHTTP formatted response

void CUploadTransferHTTP::SendResponse(UINT nResourceID, BOOL bFileHeaders)
{
	CString strBody, strResponse;
	
	HMODULE hModule = GetModuleHandle( NULL );
	HRSRC hRes = FindResource( hModule, MAKEINTRESOURCE( nResourceID ), MAKEINTRESOURCE( 23 ) );
	
	if ( hRes != NULL )
	{
		DWORD nSize			= SizeofResource( hModule, hRes );
		HGLOBAL hMemory		= LoadResource( hModule, hRes );
		LPTSTR pszOutput	= strBody.GetBuffer( nSize + 1 );
		LPCSTR pszInput		= (LPCSTR)LockResource( hMemory );
		
		while ( nSize-- ) *pszOutput++ = *pszInput++;
		*pszOutput++ = 0;
		
		strBody.ReleaseBuffer();
	}
	
	int nBreak	= strBody.Find( _T("\r\n") );
	strResponse	= strBody.Left( nBreak + 2 );
	strBody		= strBody.Mid( nBreak + 2 );
	
	while ( TRUE )
	{
		int nStart = strBody.Find( _T("<%") );
		if ( nStart < 0 ) break;
		
		int nEnd = strBody.Find( _T("%>") );
		if ( nEnd < nStart ) break;

		CString strReplace = strBody.Mid( nStart + 2, nEnd - nStart - 2 );

		strReplace.TrimLeft();
		strReplace.TrimRight();
		
		if ( strReplace.CompareNoCase( _T("Name") ) == 0 )
			strReplace = m_sFileName;
		else if ( strReplace.CompareNoCase( _T("SHA1") ) == 0 )
			strReplace = CSHA::HashToString( &m_pSHA1 );
		else if ( strReplace.CompareNoCase( _T("URN") ) == 0 )
			strReplace = CSHA::HashToString( &m_pSHA1, TRUE );
		else if ( strReplace.CompareNoCase( _T("Version") ) == 0 )
			strReplace = theApp.m_sVersion;
		else if ( strReplace.CompareNoCase( _T("Neighbours") ) == 0 )
			GetNeighbourList( strReplace );
		else if ( strReplace.CompareNoCase( _T("ListenIP") ) == 0 )
		{
			if ( Network.IsListening() )
			{
				strReplace.Format( _T("%s:%i"),
					(LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ),
					htons( Network.m_pHost.sin_port ) );
			}
			else strReplace.Empty();
		}
		
		strBody = strBody.Left( nStart ) + strReplace + strBody.Mid( nEnd + 2 );
	}
	
	m_pOutput->Print( _T("HTTP/1.1 ") + strResponse );
	SendDefaultHeaders();
	if ( bFileHeaders ) SendFileHeaders();
	m_pOutput->Print( "Content-Type: text/html\r\n" );
	
#ifdef _UNICODE
	int nBody = WideCharToMultiByte( CP_UTF8, 0, strBody, strBody.GetLength(), NULL, 0, NULL, NULL );
	LPSTR pszBody = new CHAR[ nBody ];
	WideCharToMultiByte( CP_UTF8, 0, strBody, strBody.GetLength(), pszBody, nBody, NULL, NULL );
#else
	int nBody = strBody.GetLength();
	LPCSTR pszBody = (LPCSTR)strBody;
#endif
	
	strResponse.Format( _T("Content-Length: %lu\r\n\r\n"), nBody );
	m_pOutput->Print( strResponse );
	
	if ( ! m_bHead ) m_pOutput->Add( pszBody, nBody );
	
#ifdef _UNICODE
	delete [] pszBody;
#endif
	
	StartSending( upsResponse );
}

void CUploadTransferHTTP::GetNeighbourList(CString& strOutput)
{
	static LPCTSTR pszModes[4][3] =
	{
		{ _T("Handshake"), _T("Handshake"), _T("Handshake") },
		{ _T("G1 Peer"), _T("G1 Ultrapeer"), _T("G1 Leaf") },
		{ _T("G2 Peer"), _T("G2 Hub"), _T("G2 Leaf") },
		{ _T("eDonkey2000"), _T("eDonkey2000"), _T("eDonkey2000") }
	};
	
	strOutput.Empty();
	
	CSingleLock pLock( &Network.m_pSection );
	if ( ! pLock.Lock( 100 ) ) return;
		
	DWORD tNow = GetTickCount();
		
	for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
	{
		CNeighbour* pNeighbour = Neighbours.GetNext( pos );
		
		if ( pNeighbour->m_nState == nrsConnected )
		{
			CString strNode;
			
			DWORD nTime = ( tNow - pNeighbour->m_tConnected ) / 1000;
			
			strNode.Format( _T("<tr><td class=\"fi\"><a href=\"gnutella:host:%s:%lu\">%s:%lu</a></td><td class=\"fi\" align=\"center\">%i:%.2i:%.2i</td><td class=\"fi\">%s</td><td class=\"fi\">%s</td><td class=\"fi\"><a href=\"http://%s:%lu/\">Browse</a></td></tr>\r\n"),
				(LPCTSTR)pNeighbour->m_sAddress, htons( pNeighbour->m_pHost.sin_port ),
				(LPCTSTR)pNeighbour->m_sAddress, htons( pNeighbour->m_pHost.sin_port ),
				nTime / 3600, ( nTime % 3600 ) / 60, nTime % 60,
				pszModes[ pNeighbour->m_nProtocol ][ pNeighbour->m_nNodeType ],
				(LPCTSTR)pNeighbour->m_sUserAgent,
				(LPCTSTR)pNeighbour->m_sAddress, htons( pNeighbour->m_pHost.sin_port ) );
			
			strOutput += strNode;
		}
	}
}

⌨️ 快捷键说明

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