Exemplo n.º 1
0
// Remove the headers from the input buffer, handing each to OnHeaderLine
BOOL CConnection::ReadHeaders()
{
	// Move the first line from the m_pInput buffer to strLine and do the contents of the while loop
	CString strLine;
	while ( Read( strLine ) )	// ReadLine will return false when there are no more lines
	{
		// If the line is more than 256 KB, change it to the long line error code
		if ( strLine.GetLength() > HTTP_HEADER_MAX_LINE )
			strLine = _T("#LINE_TOO_LONG#");

		// Find the first colon in the line
		int nPos = strLine.Find( _T(":") );

		// The line is empty, it's just a \n character
		if ( strLine.IsEmpty() )
		{
			// Empty the last header member variable (do)
			m_sLastHeader.Empty();

			// Call the OnHeadersComplete method for the most advanced class that inherits from CConnection
			return OnHeadersComplete();
		}
		else if ( _istspace( strLine.GetAt( 0 ) ) )		// Get the first character in the string, and see if its a space
		{
			// The line starts with a space

			// The last header has length
			if ( ! m_sLastHeader.IsEmpty() )
			{
				// Trim whitespace from both ends of the line, and ensure it still has length
				strLine.Trim();
				if ( strLine.IsEmpty() ) continue;

				// Give OnHeaderLine the last header and this line
				if ( ! OnHeaderLine( m_sLastHeader, strLine ) )
					return FALSE;
			}
		}
		else if ( nPos > 1 && nPos < 64 )	// ":a" is 0 and "a:a" is 1, but "aa:a" is greater than 1
		{
			// The colon is at a distance greater than 1 and less than 64

			// The line is like "header:value", copy out both parts
			CString strHeader	= strLine.Left( nPos );
			CString strValue	= strLine.Mid( nPos + 1 );
			m_sLastHeader = strHeader;

			strValue.Trim();
			if ( strValue.IsEmpty() ) continue;

			// Give OnHeaderLine this last header, and its value
			if ( ! OnHeaderLine( strHeader, strValue ) )
				return FALSE;
		}
	}

	// Send the contents of the output buffer to the remote computer
	OnWrite();
	return TRUE;
}
void CFtpClientReqSocket::DataReceived(const BYTE* pucData, UINT uSize)
{	
	if( !IsEntireResponse((const char*)pucData,uSize) ) //先检查是否有一个完整HeaderLine回来了..
		return ;

	CStringA strLine;
	CStringA strNumber;
	CStringA strMultiNumber;
	CStringA strMultiReply;

	LPCSTR pData=(LPCSTR)pucData;
	bool bMultiLine = false;

	while ( uSize>0 )
	{
		LPCSTR pszNl = (LPCSTR)memchr(pData, '\n', uSize);

		if(!pszNl)
			return;
		
		int iLineLen = pszNl - pData;
		ASSERT( iLineLen >= 0 );
		if (iLineLen > 0)
			strLine = CStringA(pData, iLineLen - 1); 

		pData += (strLine.GetLength() + 2);
		uSize -= (strLine.GetLength() + 2);

		if( GetClient() )
		{
			GetClient()->AddPeerLog(new CTraceServerMessage(CString(strLine)));
		}

		BOOL bNumber = ( strLine.GetLength() >= 3 ) &&
			_istdigit( strLine[0] ) && _istdigit( strLine[1] ) && _istdigit( strLine[2] );

		if ( bNumber )
			strNumber = strLine.Left( 3 );

		if ( !bMultiLine && bNumber && strLine[3] == _T('-') )
		{
			// Got first line of multi-line reply
			bMultiLine = TRUE;
			strMultiNumber = strNumber;
			strMultiReply = strLine.Mid( 4 );
		}
		else if ( !bMultiLine && bNumber )
		{
			// Got single-line reply
			if ( !OnHeaderLine( strNumber, strLine.Mid( 4 ).Trim( " \t\r\n" ) ) ) 
				return ;
		}
		else if ( bMultiLine && bNumber && strLine[3] == ' ' &&
			strMultiNumber == strNumber )
		{
			// Got last line of multi-line reply
			bMultiLine = FALSE;
			strMultiReply += "\n";
			strMultiReply += strLine.Mid( 4 );
			if ( ! OnHeaderLine( strNumber, strMultiReply.Trim( " \t\r\n" ) ) )
				return ;
		}
		else if ( bMultiLine )
		{			
			strMultiReply += "\n";
			strMultiReply += strLine;
		}
	}
}