Tinyhttpd源码分析

1. 简介:

tinyhttpd是使用c语言开发的超轻量级http服务器,通过代码流程可以了解http服务器的基本处理流程,

并且涉及了网络套接字,线程,父子进程,管道等等知识点;

 

项目地址:http://sourceforge.net/projects/tinyhttpd/

 

2. 流程介绍:

(1) 服务器启动,等待客户端请求到来;

(2) 客户端请求到来,创建新线程处理该请求;

(3) 读取httpHeader中的method,截取url,其中GET方法需要记录url问号之后的参数串;

(4) 根据url构造完整路径,如果是/结尾,则指定为该目录下的index.html;

(5) 获取文件信息,如果找不到文件,返回404,找到文件则判断文件权限;

(6) 如果是GET请求并且没有参数,或者文件不可执行,则直接将文件内容构造http信息返回给客户端;

(7) 如果是GET带参数,POST,文件可执行,则执行CGI;

(8) GET请求略过httpHeader,POST方法需要记录httpHeader中的Content-Length:xx;

(9) 创建管道用于父子进程通信,fork产生子进程;

(10) 子进程设置环境变量,将标准输入和输出与管道相连,并且通过exec执行CGI;

(11) 如果是POST,父进程将读到post内容发送给子进程,并且接收子进程的输出,输出给客户端;

 

3. 管道说明:

 

4. 代码注释:

复制代码
  1 /* J. David's webserver */
  2 /* This is a simple webserver.
  3  * Created November 1999 by J. David Blackstone.
  4  * CSE 4344 (Network concepts), Prof. Zeigler
  5  * University of Texas at Arlington
  6  */
  7 /* This program compiles for Sparc Solaris 2.6.
  8  * To compile for Linux:
  9  *  1) Comment out the #include <pthread.h> line.
 10  *  2) Comment out the line that defines the variable newthread.
 11  *  3) Comment out the two lines that run pthread_create().
 12  *  4) Uncomment the line that runs accept_request().
 13  *  5) Remove -lsocket from the Makefile.
 14  */
 15 #include <stdio.h>
 16 #include <sys/socket.h>
 17 #include <sys/types.h>
 18 #include <netinet/in.h>
 19 #include <arpa/inet.h>
 20 #include <unistd.h>
 21 #include <ctype.h>
 22 #include <strings.h>
 23 #include <string.h>
 24 #include <sys/stat.h>
 25 #include <pthread.h>
 26 #include <sys/wait.h>
 27 #include <stdlib.h>
 28 
 29 #define ISspace(x) isspace((int)(x))
 30 
 31 #define SERVER_STRING "Server: jdbhttpd/0.1.0\r\n"
 32 
 33 void accept_request(int);
 34 void bad_request(int);
 35 void cat(int, FILE *);
 36 void cannot_execute(int);
 37 void error_die(const char *);
 38 void execute_cgi(int, const char *, const char *, const char *);
 39 int get_line(int, char *, int);
 40 void headers(int, const char *);
 41 void not_found(int);
 42 void serve_file(int, const char *);
 43 int startup(u_short *);
 44 void unimplemented(int);
 45 
 46 /**********************************************************************/
 47 /* A request has caused a call to accept() on the server port to
 48  * return.  Process the request appropriately.
 49  * Parameters: the socket connected to the client */
 50 /**********************************************************************/
 51 void accept_request(int client)
 52 {
 53     char buf[1024];
 54     int numchars;
 55     char method[255];
 56     char url[255];
 57     char path[512];
 58     size_t i, j;
 59     struct stat st;
 60     int cgi = 0;      /* becomes true if server decides this is a CGI
 61                * program */
 62     char *query_string = NULL;
 63 
 64     //读取第一行数据
 65     numchars = get_line(client, buf, sizeof(buf));
 66     i = 0; j = 0;
 67     //读取http的头部method字段,读到空白为止
 68     while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 69     {
 70         method[i] = buf[j];
 71         i++; j++;
 72     }
 73     method[i] = '\0';
 74 
 75     //只支持GET和POST请求,其他请求方式返回未实现
 76     if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
 77     {
 78         unimplemented(client);
 79         return;
 80     }
 81     //如果是POST请求,设置cgi标志为1
 82     if (strcasecmp(method, "POST") == 0)
 83         cgi = 1;
 84 
 85     i = 0;
 86     //跳过空白字符
 87     while (ISspace(buf[j]) && (j < sizeof(buf)))
 88         j++;
 89     //读取url字串
 90     while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 91     {
 92         url[i] = buf[j];
 93         i++; j++;
 94     }
 95     url[i] = '\0';
 96     //如果是GET请求,需要从url中解析参数
 97     if (strcasecmp(method, "GET") == 0)
 98     {
 99         query_string = url;
100         //找到?位置
101         while ((*query_string != '?') && (*query_string != '\0'))
102             query_string++;
103         //当前字符为?字符
104         if (*query_string == '
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值