Files
wnmj/Servers/服务器组件/网站网关服务器/ParseData.cpp
2026-02-13 14:34:15 +08:00

294 lines
5.3 KiB
C++

#include "Stdafx.h"
#include "ParseData.h"
#define PACKET_SIZE 4096
#define BUFFER_OVERFLOW 8192
#define REQUEST_METHOD_POST 0
#define REQUEST_METHOD_GET 1
inline int HexToInt( char ch )
{
if( ch >= '0' && ch <= '9' )
return( ch - '0' );
if( ( ch >= 'a' && ch <= 'f') || ( ch >= 'A' && ch <= 'F' ) )
return tolower( ch ) - 'a' + 10;
return 0;
}
CParseData::CParseData(void)
{
m_nStatus = STATUS_REQUEST;
// default request method is POST
m_nRequestMethod = REQUEST_METHOD_POST;
m_QueryParams = "";
m_FormVars = "";
m_strBuffer = "";
}
CParseData::~CParseData(void)
{
}
bool CParseData::ParseRequests(LPBYTE pData, int nLen)
{
//m_strBuffer = DecodeData(pData, nLen);
m_strBuffer = pData;
CString strTemp;
int nIndex;
while(!m_strBuffer.IsEmpty())
{
nIndex = m_strBuffer.Find("\r\n");
if (nIndex != -1)
{
strTemp = m_strBuffer.Left(nIndex);
m_strBuffer = m_strBuffer.Mid(nIndex + 2);
m_strLines.AddTail(strTemp);
}
else
{
if (m_strBuffer.GetLength() > BUFFER_OVERFLOW)
{
CTraceService::TraceString(_T("Buffer overflow: DOS attack?"), TraceLevel_Normal);
return false;
}
else
{
m_strLines.AddTail(m_strBuffer);
}
break;
}
}
return true;
}
void CParseData::ProcessRequests()
{
CString strMethod, strURL, strVersion;
CString strBuff;
while(!m_strLines.IsEmpty())
{
strBuff = m_strLines.RemoveHead();
// post data ?
if (strBuff.IsEmpty())
{
m_nStatus = STATUS_BODY;
continue;
}
switch(m_nStatus)
{
case STATUS_REQUEST:
{
int nIndex = strBuff.Find(' ');
if (nIndex != -1)
{
strMethod = strBuff.Left(nIndex);
// strip URL + version
strBuff = strBuff.Mid(nIndex + 1);
strBuff.TrimLeft();
strBuff.TrimRight();
nIndex = strBuff.Find(' ');
if(nIndex != -1)
{
// Change any %x's to the appropriate char
strURL = URLDecode(strBuff.Left(nIndex));
strBuff.TrimRight();
// get HTTP version number
strVersion = strBuff.Mid(nIndex + 1);
}
else
{
// simple request
strURL = URLDecode(strBuff);
}
}
// add url to header collection
m_Headers.Add("url", strURL);
// check for arguments
nIndex = strURL.Find('?');
if (nIndex != -1)
{
// save query params
m_QueryParams = strURL.Mid(nIndex+1);
// strip from file name....
strURL = strURL.Left(nIndex);
}
// add scriptname to header collection
m_Headers.Add("script_name", strURL);
m_Headers.Add("path_info", strURL);
m_nStatus = STATUS_HEADER;
// log method
//g_EventService.ShowEventNotify(strMethod + " " + strURL);
break;
}
case STATUS_HEADER:
{
int nIndex = strBuff.Find(':');
if(nIndex != -1)
{
CString strName = strBuff.Left(nIndex);
CString strValue = strBuff.Mid(nIndex + 1);
strBuff.Format("HEADER: Name: %s, Value: %s", strName, strValue);
TRACE1("%s\n", strBuff);
// add item to header collection
m_Headers.Add(strName, strValue);
}
break;
}
case STATUS_BODY:
{
m_FormVars += strBuff;
m_FormVars += "&";
break;
}
}
if (strMethod.IsEmpty())
continue;
}
strMethod.MakeUpper();
if (strMethod == "GET")
{
m_nRequestMethod = REQUEST_METHOD_GET;
}
else
{
m_nRequestMethod = REQUEST_METHOD_POST;
}
}
void CParseData::RenderHeaders(CString& strHeaders)
{
CString strKey, strValue;
// Iterate through the entire map
for(int i=0; i<m_Headers.GetSize(); i++)
{
strKey = m_Headers.GetKeyAt(i);
strValue = m_Headers.GetValueAt(i);
strHeaders += strKey;
strHeaders += ": ";
strHeaders += strValue;
strHeaders += "\r\n";
}
strHeaders += "\r\n";
}
BOOL CParseData::GetServerVariable(LPTSTR lpszVariable, CString &strValue)
{
CString strKey;
// Iterate through the entire map
for(int i=0; i<m_Headers.GetSize(); i++)
{
strKey = m_Headers.GetKeyAt(i);
if (strKey.CompareNoCase(lpszVariable) == 0)
{
strValue = m_Headers.GetValueAt(i);
return TRUE;
}
}
// not found
return FALSE;
}
BOOL CParseData::GetQueryString(LPTSTR lpszVariable, CString &strValue)
{
CString strKey;
// Iterate through the entire map
for(int i=0; i<m_QueryStringVars.GetSize(); i++)
{
strKey = m_QueryStringVars.GetKeyAt(i);
if (strKey.CompareNoCase(lpszVariable) == 0)
{
strValue = m_QueryStringVars.GetValueAt(i);
return TRUE;
}
}
return FALSE;
}
void CParseData::ParseQueryString(LPCTSTR lpszParams)
{
CString strSub;
int nCount=0;
while(AfxExtractSubString(strSub, lpszParams, nCount++, '&'))
{
int nPos = strSub.Find('=');
if (nPos != -1)
{
CString strKey = strSub.Left(nPos);
m_QueryStringVars.Add(strKey, strSub.Mid(nPos+1));
}
}
}
void CParseData::SplitString(LPCTSTR lpszString, TCHAR chSep, CStringArray& aryString)
{
CString strSub;
int nCount=0;
while(AfxExtractSubString(strSub, lpszString, nCount++, chSep))
{
aryString.Add(strSub);
}
}
CString CParseData::DecodeData(LPBYTE cbData, int nLen)
{
CString strOut;
LPBYTE pOutBuf = (LPBYTE)strOut.GetBuffer(nLen);
if ( pOutBuf )
{
LPBYTE pOutTmp = pOutBuf;
while(*cbData)
{
if ( '%'==*cbData )
{
*pOutTmp++ = char( HexToInt( *(++cbData) ) << 4 | HexToInt( *(++cbData) ) );
}
else if ( '+'==*cbData ) *pOutTmp++ = ' ';
else *pOutTmp++ = *cbData;
cbData++;
}
*pOutTmp = '\0';
strOut.ReleaseBuffer();
}
return strOut;
}