基于HTTP协议的web服务器项目

项目简介:
基于 HTTP 协议实现一个多线程服务器,客户端通过浏览器发送请求,服务器接收并分析客户端的请求方法和资源,从而执行相应的逻辑处理,最终将客户请求的资源以 HTML 页面的形式呈现,并能进行差错处理。
项目思路:
首先实现两个主机不同进程间的通信,当服务器收到请求后,要进行分析请求方法,当方法确定后应该拿到请求的资源,接下来要根据资源是否存在执行相应的逻辑处理。GET 方法:如果没有参数,进入非 cgi 模式运行;否则,进入 cgi 模式运行;只要是 POST 方法就一定要支持 cgi:直接进入
cgi 模式运行。
项目特点:
1、支持客户端/服务器模式,客户端能够使用 GET、POST 方法请求资源;
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径;
3、灵活:HTTP 允许传输任意类型的数据对象,正在传输的类型由 Content-Type 加以标记。

项目所包含目录:
sql_connect
wwwroot
lib

http.c代码

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4 #include<fcntl.h>
  5 #include<stdlib.h>
  6 #include<ctype.h>
  7 #include<sys/stat.h>
  8 #include<sys/socket.h>
  9 #include<netinet/in.h>
 10 #include<arpa/inet.h>
 11 #include<sys/sendfile.h>
 12 #include<pthread.h>
 13 
 14 #define MAX 1024
 15 #define HOME_PAGE "index.html"
 16 #define PAGE_404 "wwwroot/404.html"
 17 
 18 static void usage(const char *proc)
 19 {
 20     printf("Usage:%s [port]\n",proc);
 21 }
 22 
 23 static int startup(int port)
 24 {
 25     int sock = socket(AF_INET,SOCK_STREAM,0);
 26     if(sock < 0){
 27         perror("socket");
 28         exit(2);
 29     }
 30 
 31     int opt = 1;
 32     setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
 33 
 34     struct sockaddr_in local;
 35     local.sin_family = AF_INET;
 36     local.sin_addr.s_addr = htonl(INADDR_ANY);
 37     local.sin_port = htons(port);
 38 
 39     if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0){
 40         perror("bind");
 41         exit(3);
 42     }
 43 
 44     if(listen(sock,5) < 0){
 45         perror("listen");
 46         exit(4);
 47     }
 48 
 49     return sock;
 50 }
 51 
 52 static int getLine(int sock,char line[],int size)
 53 {
 54     //\r,\r\n,\n -> \n
 55     char c = 'a';
 56     int i = 0;
 57     while(c != '\n' && i < size - 1){
 58         ssize_t s = recv(sock,&c,1,0);
 59         if(c == '\r'){
 60             recv(sock,&c,1,MSG_PEEK);
 61             if(c== '\n'){
 62                 recv(sock,&c,1,0);
 63             }else{
 64                 c = '\n';
 65             }
 66         }
 67         line[i++] = c;
 68     }
 69     line[i] = '\0';
 70     return i;
 71 }
 72 
 73 static void clearHeader(int sock)
 74 {
 75     char line[MAX];
 76     do{
 77         getLine(sock,line,sizeof(line));
 78     }while(strcmp("\n",line));
 79 }
 80 
 81 void show_404(int sock)
 82 {
 83     char line[MAX];
 84     struct stat st;
 85     sprintf(line,"HTTP/1.0 404 NOT FOUND\r\n");
 86     send(sock,line,strlen(line),0);
 87     sprintf(line,"Content-Type:text/html:charset=ISO-8859-1\r\n");
 88     send(sock,line,strlen(line),0);
 89     sprintf(line,"\r\n");
 90     send(sock,line,strlen(line),0);
 91     int fd = open(PAGE_404,O_RDONLY);
 92     stat(PAGE_404,&st);
 93     sendfile(sock,fd,NULL,st.st_size);
 94     close(fd);
 95 }
 96 
 97 static void echoErrMsg(int sock,int status_code)
 98 {
 99     switch(status_code){
100         case 301:
101             break;
102         case 302:
103             break;
104         case 307:
105             break;
106         case 400:
107             break;
108         case 403:
109             break;
110         case 404:
111             show_404(sock);
112             break;
113         case 500:
114             break;
115         case 503:
116             break;
117         default:
118             break;
119     }
120 }
121 
122 int exe_cgi(int sock,char *method,char *path,char *query_string)
123 {
124     char line[MAX];
125     int content_length = -1;
126     char method_env[MAX/32];
127     char query_string_env[MAX];
128     char content_length_env[MAX/8];
129 
130     if(strcasecmp(method,"GET") == 0){
131         clearHeader(sock);
132     }else{ //POST
133         do{
134             getLine(sock,line,sizeof(line));
135             if(strncasecmp(line,"Content-Length: ",16) == 0){
136                 content_length = atoi(line + 16);
137             }
138         }while(strcmp(line,"\n"));
139         if(content_length == -1){
140             return 400;
141         }
142     }
143 
144     int input[2];
145     int output[2]; 
146 
147     pipe(input);
148     pipe(output);
149 
150     pid_t id = fork();
151     if(id < 0){
152         return 500;
153     }
154     else if(id == 0){ //child
155         close(input[1]);
156        
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值