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