HTTP协议的解析

今天完成了所有的开发工作,很高兴,我的服务器软件中支持断点续传,流媒体播放,CGI网关编程接口,虚拟目录设置,GET和POST请求.
   回头想想这近两个月的开发过程很有意思.应该总结一下,以便以后再用.
   Http又叫超文本传输协议,是我们目前应用最为广范的应用层协议.它结构合理,不保持连接状态.
   http的会话方式为客户机/服务器模式,客户机首先与服务器建立连接,这是一条TCP连接,端口号默认为80,然后生成请求信息,这个请求格式应遵循HTTP协议规范.服务器端解析到来的请求,分析客户的意图,生成对应的返回信息,发送到对方,断开连接,完成本次会话.
  Http中主要有两种请求方式,一是GET也是最常用的,二是POST请求,适用于大数据量的传输.
GET请求主要是请求文档,各种格式的文件,还有就是调用服务器端CGI应用程序,传送少量的参数信息,可以理解成GET的主要功能是获取而不是给予.与此相对应的是POST则是相反.是对本地数据的提交.
下面举一个例子,来看一下GET的请求格式:
GET /index.htm HTTP/1.1
Host: localhost
Accept: */*User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)
Pragma: no-cache
Cache-Control: no-cache
Connection: close
 
这是一个获取服务器端index.html这个文件的请求.
下面的是一些相关的本次请求的客户机信息.比如HOST是指主机IP,Referer是指从那里进行定位过来的等
等.要想开发服务器端软件就要解决HTTP协议中客户机请求的解析.如何解析这个请求呢,下面就是答案:
首先为了开发方便,我设计了一个数据类型
struct HttpHeader
{

 string  method;  
 string  protocol; 
 float  httpver;      
 string      useragent;  
 string      date;         
 string      path;  
 string      connection;  
 string      ifmodifiedsince; 
 string      lastmodified;   
 string      eTag;          
 int   contenttype; /* Content-Type: */
 int   rangeflag;    
 DWORD  rangestart;   
 DWORD  rangeend;   
 DWORD  rangetotal; 
 long  contentlength;  
 string      accept ;
 string      host  ; 
 string      acceptlanguage ;
 string      acceptencoding;
 string      referer;
};
这个数据类型中基本上包括了HTTP协议中的常用的字段信息,我们的想法是写一个解析程序,让客户机的请求按其前面的字段顺次写到我们这个数据类型中,便于下一步的工作.解析函数如下.
void process(char *requestBuf)
{
 //requestBuf为一数据区,里面放了客户机全部的请求信息.
   HttpHeader *header = new HttpHeader();
      
 char getURL[1024];
 char method[200];
 char protocol[200];
 if(sscanf(requestBuf, "%s %s %s", method, getURL, protocol)!=3)
 {
     delete header;
     return responseError400,header,pClient);
  
 }

 urlDecode(getURL, getURL);
 header->path = strdup(getURL);
 header->method = method ;
 header->protocol = protocol ;
/  
 string post = ""  ;
    if(strcmp(header->method.c_str(),"POST") == 0)
 {
  
  int length = strlen( requestBuf ) ;
  int tcount =  length ;
  length -- ;
  
  while(requestBuf[length]!='-')
  {
   length -- ;
  }
  length += 10 ;
  
  while(length <= tcount)
  {
   post+= requestBuf[length++];
  }
    
  cout<<"POST:"<<post.c_str()<<endl;
  
 }

 char *ENDOFLINE = "/r/n";
    if(strchr(requestBuf, '/r/n') == NULL)
  ENDOFLINE += 1;
    char *s = strtok(requestBuf, ENDOFLINE);
 
 
 while(s)
 {
  if (strnicmp(s, "User-Agent: ", 12) == 0)
   header->useragent=strdup(s+12);
  else if (strnicmp(s, "Connection: ", 12) == 0)
   header->connection = strdup(s+12);
  else if (strnicmp(s, "If-Modified-Since: ", 19) == 0)
   header->ifmodifiedsince = strdup(s+19);
  else if (strnicmp(s, "Content-Length: ", 16) == 0)
   header->contentlength = strtoul(s+16, NULL, 10);
  else if (strnicmp(s, "Referer: ", 9) == 0)
   header->referer = strdup(s+9);
        else if (strnicmp(s, "Host: ", 6) == 0)
   header->host = strdup(s+6);
  else if (strnicmp(s, "Accept: ", 8) == 0)
   header->accept = strdup(s+8);
  else if (strnicmp(s, "Accept-Language: ",17) == 0)
   header->acceptlanguage = strdup(s+17);
  else if (strnicmp(s, "Accept-Encoding: ",17) == 0)
   header->acceptencoding = strdup(s+17);
        else if (strnicmp(s, "Range: ", 7) == 0)
   header->rangeflag = getRange(header,s + 7);
     s = strtok(NULL, ENDOFLINE);
 }
   
}
 
  }
这就是全部的解析源代码.具体来讲是首先从数据区中第一行检测形如GET/POST /XXXX Http1.1这种格式,其中GET/POST是我们要找的方法,加入到header的method中,/XXXX为客户机请求的具体信息.Http1.1为协议类型,有时会为HTTP1.0等,是一种协议版本的管理,我们可以不管.然后就不断调用strtok()函数,因为其请求格式固定为Name: XXXX,所以我们可以用while循环体中的那些方法完成对字段的解析.
  解析完后我们就把HTTP的客户请求变成了我们能控制的形式,以便下一步的开发.
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值