📄 chttpreq.cpp
字号:
/*******************************************************************
* cHttpreq.cpp
* DESCRIPTION:
*
* AUTHOR:
*
* HISTORY:
*
* DATE:2002-8-22
*
*******************************************************************/
#include "cHttpreq.h"
#include <iostream>
#include <cstdio>
#include "logout.h"
RW_DEFINE_LOG("cHttpreq")
using namespace std;
using namespace yyc;
/**
* 将16进制字符转化未十进制数字
*
* @param c
*
* @return
*/
int cHttpreq::hextoi(char c)
{
int retv=0;
if(c>=48&&c<58)
retv=c-48;
else if(c>='a'&&c<='f')
retv=c-97+10;
else if(c>='A'&&c<='F')
retv=c-65+10;
else
retv=0;
return retv;
}
/**
* 浏览器请求的编码数据的解码
* 浏览器将中文和一些特殊字符进行编码后在以字符串形式发送
* 编码方式为:%(HEX),即将字节转化为十六进制的字符串,前面加一个%号
*
* @param str 要解码的字符串
* 解码后的数据将改写此字符串的内容
*
* @return 解码后字符串的引用
*/
char *cHttpreq::decode_char(char *str)
{
return decode_char(str,strlen(str));
}
char * cHttpreq::decode_char(char *str,int len)
{
const char *ptr;
int pos;
unsigned char c;
ptr=(const char *)str;
pos=0;
for(int i=0;i<len;i++)
{
if(ptr[i]=='%')
{
if(i<(len-2))
{
c=(unsigned char)(hextoi(ptr[i+1])*16+hextoi(ptr[i+2]));
str[pos++]=c;
i+=2;
}
}
else if(ptr[i]=='+')
str[pos++]=' ';
else
{
c=ptr[i];
str[pos++]=c;
}
}
if(pos<len) str[pos]=0;
return str;
}
/**
* 显示HTTPREQ对象的内容
*/
void cHttpreq::dump()
{
RW_LOG_DEBUG("HTTPREQ dump: METHOD=%s,URL=%s\n",m_strMethod,m_strUrl);
if(!m_req_paras.empty())
{
map<string,string>::iterator it=m_req_paras.begin();
for(;it!=m_req_paras.end();it++)
{
if(!(*it).second.empty())
{
RW_LOG_DEBUG("\t%s=%s\n",(*it).first.c_str(),(*it).second.c_str());
}
else
{
RW_LOG_DEBUG("\t%s=NULL\n",(*it).first.c_str());
}
}//?for(;it!=req_paras.end();it++)
}//?if(!req_paras.empty())
}
/**
* 处理HTTP请求数据
*
* @param buf 数据指针
* @param len 数据长度
*
* @return <0发生错误
* >=0成功
*/
int cHttpreq::do_reqdata(char *buf,int len)
{
int iLen,retv=0;
char *ptr,*ptr1,*ptr2;
if(NULL==buf||len<=0) return -1;
if(strncmp(buf,"GET",3)==0||strncmp(buf,"POST",4)==0)
{
ptr=buf;
ptr1=strchr(ptr,'\n');
while(ptr1!=NULL&&ptr1<(buf+len))
{
*ptr1='\0';
if(ptr1>buf&&(*(ptr1-1)=='\r')) *(ptr1-1)='\0';
if(strlen(ptr)<1)
{
//遇到空行,HTTP头结束
if(strcmp(m_strMethod,"POST")==0)
{
m_buf.reset(ptr1+1,len-(ptr1+1-buf));
m_iRecvlen=m_buf.len();
}
else
m_iRecvlen=m_iReqlen;//请求数据接收完
break;
}//?if(strlen(ptr)<1)
else
{
if(ptr==buf)
{
//处理第一行数据
ptr2=strchr(ptr,' ');
if(ptr2!=NULL)
{
*ptr2='\0';
strncpy(m_strMethod,ptr,5);
ptr=ptr2+1;
ptr2=strchr(ptr,' ');
if(ptr2!=NULL)
{
*ptr2='\0';
ptr2=strchr(ptr,'?');
if(ptr2!=NULL)
{
*ptr2='\0';
strncpy(m_strUrl,ptr,254);
m_buf.reset(ptr2+1,strlen(ptr2+1));
}
else
{
strncpy(m_strUrl,ptr,254);
}
}
}
}
else
{
//处理其它行数据
if(strncmp(ptr,"Content-Length",14)==0)
m_iReqlen=atoi(ptr+15);
}
}//?if(strlen(ptr)<1) else
ptr=ptr1+1;
ptr1=strchr(ptr,'\n');
}
}
else
{
if(strcmp(m_strMethod,"POST")==0)
{
m_buf.append(buf,len);
m_iRecvlen+=len;
}
else
return -1;
}
//参数解析,参数存放在m_str变量缓冲区中
if(m_strMethod[0]==0)
retv=-1;
else
{
if (strcmp(m_strMethod,"POST")==0) {
RW_LOG_DEBUG("POST req:have receive %d bytes of %d bytes!\n",m_iRecvlen,m_iReqlen);
}
ptr=m_buf.get();iLen=m_buf.len();
if(ptr!=NULL&&iLen>0)
{
ptr1=strchr(ptr,'&');
while(ptr1!=NULL&&ptr1<(m_buf.get()+iLen))
{
*ptr1='\0';
decode_char(ptr);
ptr2=strchr(ptr,'=');
if(ptr2!=NULL)
{
*ptr2='\0';
m_req_paras[ptr]=(ptr2+1);
}
ptr=ptr1+1;
ptr1=strchr(ptr,'&');
}
//最后一个参数处理
if(m_iRecvlen>=m_iReqlen)
{
//数据已经接收完毕
decode_char(ptr,iLen-(ptr-m_buf.get()));
ptr2=strchr(ptr,'=');
if(ptr2<(m_buf.get()+iLen))
{
*ptr2='\0';
string s(ptr2+1,iLen-(ptr2+1-m_buf.get()));
m_req_paras[ptr]=s;
}
}
else
{
//数据未接收完毕
m_buf.erase(0,ptr-1-m_buf.get());
}
}//?if(ptr!=NULL&&iLen>0)
}//?if(req_method[0]==0)
//参数解析结束
return retv;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -