http请求包的基本格式如下:
方法 /资源路径 ?参数1&参数2 HTTP/version
…………..
……………
例如:
GET/jianli.pdf HTTP/1.1
Host:127.0.0.1
Connection:keep-alive
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko)Chrome/11.0.696.57 Safari/534.24
Accept:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Accept-Charset:GBK,utf-8;q=0.7,*;q=0 char *
对于我来说,我关心的只是第一行,也就是方法、资源路径、参数
所以在程序中我定义了一个结构体用来存放这3元组:
struct RequestCotent
{
char*pcType;
char*pcUri;
char**ppcVar;
};
为了能够解析得到这3元组,我在程序中通过ParseData来得到,ParseData的原型如下:
RequestCotent ParseData(char* pBuffer,int iLen);
pBuffer为从客户端接收的数据包,也就是从浏览器的得到的http请求,iLen是该数据包的大小,返回值也就是我们解析后得到的3元组。
下面来看ParseData的实现:
RequestCotent ParseData(char* pBuffer,int iLen)
{
char*pTemp=pBuffer;
unsignediStart=0;
unsignediRead=0;
while(*(pTemp+iStart++)==' ');
--iStart;
pTemp+=iStart;
pBuffer+=iStart;
while(*(pTemp+(++iRead))!=' ');
char*pcTempType=(char*)malloc(iRead+1);
memcpy(pcTempType,pTemp,iRead);//得到方法
pcTempType[iRead]='\0';
RequestCotentrcResult;
rcResult.pcType=pcTempType;
pTemp+=iRead;
iRead=0;
while(*(pTemp+(++iRead))!='/');
pTemp+=iRead;
iRead=0;
while((*(pTemp+(++iRead))!='?')&&(*(pTemp+iRead)!=' '));
char*pcTempUri=(char*)malloc(iRead+1);
memcpy(pcTempUri,pTemp,iRead);//得到路径
pcTempUri[iRead]='\0';
rcResult.pcUri=pcTempUri;
if(*(pTemp+iRead)==' ')
{
rcResult.ppcVar=NULL;
returnrcResult;
}
else
pTemp+=iRead+1;
intiCount=1;
iRead=0;
while(*(pTemp+(++iRead))!=' ')
{
if(*(pTemp+iRead)=='&')
iCount++;
}
rcResult.ppcVar=(char**)malloc(iCount*sizeof(void*));
iCount=0;
iRead=0;
intiTemp=0;
pBuffer=pTemp;
while(*(pTemp+(iRead++))!=' ')//得到参数
{
iTemp++;
if(*(pTemp+iRead)=='&'||*(pTemp+iRead)==' ')
{
char* pcTempContent=(char*)malloc(iTemp+1);
memcpy(pcTempContent,pBuffer,iTemp);
pcTempContent[iTemp]='\0';
rcResult.ppcVar[iCount++]=pcTempContent;
pBuffer=pTemp+iRead+1;
iTemp=-1;
}
}
returnrcResult;
}
这个函数实现了对http请求包头的解析,当然,这个实现的很不合理,里面多处使用了malloc,而没用使用free,所以这要求在后面函数中对这些堆空间进行释放,否则将会造成堆溢出。