Chinaunix首页 | 论坛 | 博客
  • 博客访问: 63679
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 236
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-05 21:34
文章分类

全部博文(21)

文章存档

2015年(21)

我的朋友

分类: LINUX

2015-08-07 23:56:09


点击(此处)折叠或打开

  1. //start from the very beginning,and to create greatness
  2. //@author: Chuangwei Lin
  3. //@E-mail:979951191@qq.com
  4. //@brief: 服务器SHTTPD请求方法解析
  5. #include "lcw_shttpd.h"
  6. /******************************************************
  7. 函数名: Method_DoGet(struct worker_ctl *wctl)
  8. 参数:
  9. 功能:GET方法
  10. *******************************************************/
  11. static int Method_DoGet(struct worker_ctl *wctl)
  12. {
  13.     DBGPRINT("LCW==>Method_DoGet\n");
  14.     struct conn_response *res = &wctl->conn.con_res;
  15.     struct conn_request *req = &wctl->conn.con_req;
  16.     char path[URI_MAX];
  17.     memset(path, 0, URI_MAX);
  18.     size_t    n;
  19.     unsigned long r1, r2;
  20.     char *fmt = "%a, %d %b %Y %H:%M:%S GMT";//时间格式
  21.     //需要确定的参数
  22.     size_t status = 200;//状态值,已确定
  23.     char *msg = "OK";    //状态信息,已确定
  24.     char date[64] = "";//时间
  25.     char lm[64] = "";    //请求文件最后修改信息
  26.     char etag[64] = "";//etag信息
  27.     big_int_t cl;        //内容长度
  28.     char range[64] = "";//范围    
  29.     struct mine_type *mine = NULL;    
  30.     time_t t = time(NULL);//取得当前时间
  31.     //根据fmt指向字符串的命令将localtime(&t)中的时间信息储存在date中
  32.     (void)strftime(date, sizeof(date),fmt,localtime(&t));
  33.     //最后修改时间
  34.     (void) strftime(lm, sizeof(lm), fmt,localtime(&res->fsate.st_mtime));
  35.     //ETAG 将可变个参数(...)按照"%lx.%lx"格式化成字符串,然后将其复制到etag中
  36.     (void) snprintf(etag, sizeof(etag), "%lx.%lx",(unsigned long)res->fsate.st_mtime,(unsigned long)res->fsate.st_size);    
  37.     //发送的MIME类型
  38.     mine = Mine_Type(req->uri, strlen(req->uri), wctl);
  39.     //内容长度
  40.     cl = (big_int_t) res->fsate.st_size;
  41.     //范围range
  42.     memset(range, 0, sizeof(range));
  43.     n = -1;
  44.     if (req->ch.range.v_vec.len > 0 )//取出请求范围
  45.     {
  46.         printf("request range:%d\n",req->ch.range.v_vec.len);
  47.         //从ptr里读进数据,依照第二个参数的格式将数据写入到后面的参数里
  48.         n = sscanf(req->ch.range.v_vec.ptr,"bytes=%lu-%lu",&r1, &r2);
  49.     }
  50.     printf("n:%d\n",n);
  51.     if(n > 0)
  52.     {
  53.         status = 206;
  54.         lseek(res->fd, r1, SEEK_SET);
  55.         //n==2取前一个
  56.         cl = n == 2 ? r2 - r1 + 1: cl - r1;
  57.         (void) snprintf(range, sizeof(range),"Content-Range: bytes %lu-%lu/%lu\r\n",r1, r1 + cl - 1, (unsigned long) res->fsate.st_size);
  58.         msg = "Partial Content";
  59.     }
  60.     //构建输出的头部
  61.     memset(res->res.ptr, 0, sizeof(wctl->conn.dres));
  62.     snprintf(res->res.ptr,//缓冲区
  63.         sizeof(wctl->conn.dres),//缓冲区长度
  64.         "HTTP/1.1 %d %s\r\n" //状态和状态信息
  65.         "Date: %s\r\n"//日期
  66.         "Last-Modified: %s\r\n"//最后修改时间
  67.         "Etag: \"%s\"\r\n"//Web资源标记号
  68.         "Content-Type: %.*s\r\n"//内容类型
  69.         "Content-Length: %lu\r\n"//内容长度
  70.         //"Connection:close\r\n"
  71.         "Accept-Ranges: bytes\r\n"//发送范围        
  72.         "%s\r\n",//范围起始
  73.         status,msg,date,lm,etag,strlen(mine->mime_type),mine->mime_type,cl,range);
  74.     res->cl = cl;
  75.     res->status = status;
  76.     printf("content length:%d, status:%d\n",res->cl, res->status);
  77.     DBGPRINT("LCW<==Method_DoGet\n");
  78.     return 0;
  79. }
  80. /******************************************************
  81. 未实现的方法
  82. *******************************************************/
  83. static int Method_DoPost(struct worker_ctl *wctl)
  84. {
  85.     return 0;
  86. }
  87. static int Method_DoHead(struct worker_ctl *wctl)
  88. {
  89.     Method_DoGet(wctl);
  90.     close(wctl->conn.con_res.fd);
  91.     wctl->conn.con_res.fd = -1;
  92.     return 0;
  93. }
  94. static int Method_DoPut(struct worker_ctl *wctl)
  95. {
  96.     return 0;
  97. }
  98. static int Method_DoDelete(struct worker_ctl *wctl)
  99. {
  100.     return 0;
  101. }
  102. static int Method_DoCGI(struct worker_ctl *wctl)
  103. {
  104.     return 0;    
  105. }
  106. static int Method_DoList(struct worker_ctl *wctl)
  107. {
  108.     return 0;
  109. }
  110. /******************************************************
  111. 函数名:Method_Do(struct worker_ctl *wctl)
  112. 参数:业务和线程状态结构
  113. 功能:匹配方法
  114. *******************************************************/
  115. void Method_Do(struct worker_ctl *wctl)
  116. {
  117.     DBGPRINT("LCW==>Method_Do\n");
  118.     if(0)//????什么意思 不执行?
  119.         Method_DoCGI(wctl);
  120.     switch(wctl->conn.con_req.method)//匹配请求类型
  121.     {
  122.         case METHOD_PUT://PUT方法
  123.             Method_DoPut(wctl);
  124.             break;
  125.         case METHOD_DELETE://DELETE方法
  126.             Method_DoDelete(wctl);
  127.             break;
  128.         case METHOD_GET://GET方法(这里只实现GET方法)
  129.             Method_DoGet(wctl);
  130.             break;
  131.         case METHOD_POST://POST方法
  132.             Method_DoPost(wctl);
  133.             break;
  134.         case METHOD_HEAD://HEAD方法
  135.             Method_DoHead(wctl);
  136.             break;
  137.         default:
  138.             Method_DoList(wctl);
  139.     }

  140.     DBGPRINT("LCW<==Method_Do\n");
  141. }

阅读(1403) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~