// 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; } } }