📄 uploadtransferhttp.cpp
字号:
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 + -