📄 connection.cpp
字号:
else
{
m_mInput.nPosition = ( m_mInput.nPosition + 1 ) % METER_LENGTH;
m_mInput.pTimes[ m_mInput.nPosition ] = tNow;
m_mInput.pHistory[ m_mInput.nPosition ] = nTotal;
m_mInput.tLastSlot = tNow;
}
}
m_mInput.nTotal += nTotal;
Statistics.Current.Bandwidth.Incoming += nTotal;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CConnection write event handler
BOOL CConnection::OnWrite()
{
if ( m_hSocket == INVALID_SOCKET ) return FALSE;
if ( m_pOutput->m_nLength == 0 ) return TRUE;
DWORD tNow = GetTickCount();
DWORD nLimit = 0xFFFFFFFF;
if ( m_mOutput.pLimit && *m_mOutput.pLimit && ( Settings.Live.BandwidthScale <= 100 || m_mOutput.bUnscaled ) )
{
DWORD tCutoff = tNow - METER_SECOND;
DWORD* pHistory = m_mOutput.pHistory;
DWORD* pTime = m_mOutput.pTimes;
DWORD nUsed = 0;
for ( int nSeek = METER_LENGTH ; nSeek ; nSeek--, pHistory++, pTime++ )
{
if ( *pTime >= tCutoff ) nUsed += *pHistory;
}
nLimit = *m_mOutput.pLimit;
if ( Settings.Live.BandwidthScale < 100 && ! m_mOutput.bUnscaled )
{
nLimit = nLimit * Settings.Live.BandwidthScale / 100;
}
if ( Settings.Uploads.ThrottleMode )
{
nLimit = ( nUsed >= nLimit ) ? 0 : ( nLimit - nUsed );
}
else
{
tCutoff = nLimit * ( tNow - m_mOutput.tLastAdd ) / 1000;
nLimit = ( nUsed >= nLimit ) ? 0 : ( nLimit - nUsed );
nLimit = min( nLimit, tCutoff );
m_mOutput.tLastAdd = tNow;
}
}
BYTE* pBuffer = m_pOutput->m_pBuffer;
DWORD nBuffer = m_pOutput->m_nLength;
while ( nLimit && nBuffer )
{
int nLength = (int)min( nLimit, nBuffer );
nLength = send( m_hSocket, (char*)pBuffer, nLength, 0 );
if ( nLength <= 0 ) break;
pBuffer += nLength;
nBuffer -= nLength;
if ( nLimit != 0xFFFFFFFF ) nLimit -= nLength;
}
DWORD nTotal = ( m_pOutput->m_nLength - nBuffer );
if ( nTotal )
{
m_pOutput->Remove( nTotal );
m_mOutput.tLast = tNow;
if ( tNow - m_mOutput.tLastSlot < METER_MINIMUM )
{
m_mOutput.pHistory[ m_mOutput.nPosition ] += nTotal;
}
else
{
m_mOutput.nPosition = ( m_mOutput.nPosition + 1 ) % METER_LENGTH;
m_mOutput.pTimes[ m_mOutput.nPosition ] = tNow;
m_mOutput.pHistory[ m_mOutput.nPosition ] = nTotal;
m_mOutput.tLastSlot = tNow;
}
m_mOutput.nTotal += nTotal;
Statistics.Current.Bandwidth.Outgoing += nTotal;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CConnection measure
void CConnection::Measure()
{
DWORD tCutoff = GetTickCount() - METER_PERIOD;
DWORD* pInHistory = m_mInput.pHistory;
DWORD* pInTime = m_mInput.pTimes;
DWORD* pOutHistory = m_mOutput.pHistory;
DWORD* pOutTime = m_mOutput.pTimes;
DWORD nInput = 0;
DWORD nOutput = 0;
for ( int tNow = METER_LENGTH ; tNow ; tNow-- )
{
if ( *pInTime >= tCutoff ) nInput += *pInHistory;
if ( *pOutTime >= tCutoff ) nOutput += *pOutHistory;
pInHistory++, pInTime++;
pOutHistory++, pOutTime++;
}
m_mInput.nMeasure = nInput * 1000 / METER_PERIOD;
m_mOutput.nMeasure = nOutput * 1000 / METER_PERIOD;
}
//////////////////////////////////////////////////////////////////////
// CConnection HTML header reading
BOOL CConnection::ReadHeaders()
{
CString strLine;
while ( m_pInput->ReadLine( strLine ) )
{
if ( strLine.GetLength() > 20480 ) strLine = _T("#LINE_TOO_LONG#");
int nPos = strLine.Find( _T(":") );
if ( strLine.IsEmpty() )
{
m_sLastHeader.Empty();
return OnHeadersComplete();
}
else if ( _istspace( strLine.GetAt( 0 ) ) )
{
if ( m_sLastHeader.GetLength() )
{
strLine.TrimLeft();
strLine.TrimRight();
if ( strLine.GetLength() > 0 )
{
if ( ! OnHeaderLine( m_sLastHeader, strLine ) ) return FALSE;
}
}
}
else if ( nPos > 1 && nPos < 64 )
{
m_sLastHeader = strLine.Left( nPos );
CString strValue = strLine.Mid( nPos + 1 );
strValue.TrimLeft();
strValue.TrimRight();
if ( strValue.GetLength() > 0 )
{
if ( ! OnHeaderLine( m_sLastHeader, strValue ) ) return FALSE;
}
}
}
OnWrite();
return TRUE;
}
BOOL CConnection::OnHeaderLine(CString& strHeader, CString& strValue)
{
if ( strHeader.CompareNoCase( _T("User-Agent") ) == 0 )
{
m_sUserAgent = strValue;
return TRUE;
}
else if ( strHeader.CompareNoCase( _T("Remote-IP") ) == 0 )
{
Network.AcquireLocalAddress( strValue );
}
else if ( strHeader.CompareNoCase( _T("X-My-Address") ) == 0 ||
strHeader.CompareNoCase( _T("Listen-IP") ) == 0 ||
strHeader.CompareNoCase( _T("Node") ) == 0 )
{
int nColon = strValue.Find( ':' );
if ( ! m_bInitiated && nColon > 0 )
{
int nPort = GNUTELLA_DEFAULT_PORT;
if ( _stscanf( strValue.Mid( nColon + 1 ), _T("%lu"), &nPort ) == 1 && nPort != 0 )
{
m_pHost.sin_port = htons( nPort );
}
}
}
return TRUE;
}
BOOL CConnection::OnHeadersComplete()
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CConnection header output helpers
BOOL CConnection::SendMyAddress()
{
if ( Network.IsListening() )
{
CString strHeader;
strHeader.Format( _T("Listen-IP: %s:%lu\r\n"),
(LPCTSTR)CString( inet_ntoa( Network.m_pHost.sin_addr ) ),
htons( Network.m_pHost.sin_port ) );
m_pOutput->Print( strHeader );
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CConnection blocked agent filter
BOOL CConnection::IsAgentBlocked()
{
if ( m_sUserAgent.IsEmpty() ) return FALSE;
if ( m_sUserAgent == _T("Fake Shareaza") ) return TRUE;
if ( Settings.Uploads.BlockAgents.IsEmpty() ) return FALSE;
CString strBlocked = Settings.Uploads.BlockAgents;
strBlocked.MakeLower();
CString strAgent = m_sUserAgent;
strAgent.MakeLower();
for ( strBlocked += '|' ; strBlocked.GetLength() ; )
{
CString strBrowser = strBlocked.SpanExcluding( _T("|;,") );
strBlocked = strBlocked.Mid( strBrowser.GetLength() + 1 );
if ( strBrowser.GetLength() > 0 &&
strAgent.Find( strBrowser ) >= 0 ) return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CConnection URL encodings
CString CConnection::URLEncode(LPCTSTR pszInputT)
{
static LPCTSTR pszHex = _T("0123456789ABCDEF");
static LPCSTR pszUnsafe = "<>\"#%{}|\\^~[]+?&@=:,";
CString strOutput;
if ( pszInputT == NULL || *pszInputT == 0 ) return strOutput;
#ifdef _UNICODE
int nUTF8 = WideCharToMultiByte( CP_UTF8, 0, pszInputT, -1, NULL, 0, NULL, NULL );
if ( nUTF8 < 2 ) return strOutput;
LPSTR pszUTF8 = new CHAR[ nUTF8 ];
WideCharToMultiByte( CP_UTF8, 0, pszInputT, -1, pszUTF8, nUTF8, NULL, NULL );
pszUTF8[ nUTF8 - 1 ] = 0;
LPCSTR pszInput = pszUTF8;
#else
LPCSTR pszInput = pszInputT;
#endif
LPTSTR pszOutput = strOutput.GetBuffer( strlen( pszInput ) * 3 + 1 );
for ( ; *pszInput ; pszInput++ )
{
if ( *pszInput <= 32 || *pszInput > 127 ||
strchr( pszUnsafe, *pszInput ) != NULL )
{
*pszOutput++ = _T('%');
*pszOutput++ = pszHex[ ( *pszInput >> 4 ) & 0x0F ];
*pszOutput++ = pszHex[ *pszInput & 0x0F ];
}
else
{
*pszOutput++ = (TCHAR)*pszInput;
}
}
*pszOutput = 0;
strOutput.ReleaseBuffer();
#ifdef _UNICODE
delete [] pszUTF8;
#endif
return strOutput;
}
CString CConnection::URLDecode(LPCTSTR pszInput)
{
TCHAR szHex[3] = { 0, 0, 0 };
CString strOutput;
int nHex;
#ifdef _UNICODE
LPSTR pszBytes = new CHAR[ _tcslen( pszInput ) + 1 ];
LPSTR pszOutput = pszBytes;
#else
LPSTR pszOutput = strOutput.GetBuffer( strlen( pszInput ) );
#endif
for ( ; *pszInput ; pszInput++ )
{
if ( *pszInput == '%' )
{
if ( ! ( szHex[0] = pszInput[1] ) ) break;
if ( ! ( szHex[1] = pszInput[2] ) ) break;
if ( _stscanf( szHex, _T("%x"), &nHex ) != 1 ) break;
if ( nHex < 1 ) break;
*pszOutput++ = nHex;
pszInput += 2;
}
else if ( *pszInput == '+' )
{
*pszOutput++ = ' ';
}
else
{
*pszOutput++ = (CHAR)*pszInput;
}
}
*pszOutput = 0;
#ifdef _UNICODE
int nLength = MultiByteToWideChar( CP_UTF8, 0, pszBytes, -1, NULL, 0 );
MultiByteToWideChar( CP_UTF8, 0, pszBytes, -1, strOutput.GetBuffer( nLength ), nLength );
strOutput.ReleaseBuffer();
delete [] pszBytes;
#else
strOutput.ReleaseBuffer();
#endif
return strOutput;
}
BOOL CConnection::StartsWith(LPCTSTR pszInput, LPCTSTR pszText)
{
return _tcsnicmp( pszInput, pszText, _tcslen( pszText ) ) == 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -