Zirconi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

目前状态仅仅是“能运行”。仅作为记录。

  1 #include <unistd.h>
  2 #include <fcntl.h>
  3 #include <sys/socket.h>
  4 #include <sys/mman.h>
  5 #include <sys/stat.h>
  6 #include <netinet/in.h>
  7 #include <arpa/inet.h>
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <string.h>
 11 #include <errno.h>
 12 #include <signal.h>
 13 
 14 #include "rio/rio.h"
 15 
 16 #define SA struct sockaddr
 17 #define ERROR(msg) do{perror(msg);exit(-1);}while(0)
 18 #define PORT 8080
 19 #define MAXSIZE 8192
 20 
 21 void process(int fd);
 22 void process_request_body(rio_t *request);
 23 void client_error(int fd, int no,const char *msg);
 24 int  process_uri(const char *uri, char *filename, char *filetype);
 25 
 26 int main(int argc, char **argv)
 27 {
 28     int listenfd, connfd, err;
 29     struct sockaddr_in servaddr;
 30 
 31     signal(SIGPIPE, SIG_IGN);
 32 
 33     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 34         ERROR("SOCKET");
 35 
 36     memset(&servaddr, 0, sizeof(servaddr));
 37     servaddr.sin_family = AF_INET;
 38     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 39     servaddr.sin_port = htons(PORT);
 40 
 41     if((err = bind(listenfd, (SA *)&servaddr, sizeof(servaddr))) < 0)
 42         ERROR("BIND");
 43 
 44     if((err  = listen(listenfd, 256)) < 0)
 45         ERROR("LISTEN");
 46 
 47     for(;;)
 48     {
 49         if((connfd = accept(listenfd, NULL, NULL)) < 0)
 50             ERROR("ACCEPT");
 51         process(connfd);
 52     }
 53     exit(0);
 54 }
 55 
 56 void process(int fd)
 57 {
 58     char content[MAXSIZE], temp[MAXSIZE], method[MAXSIZE], uri[MAXSIZE], protocol[MAXSIZE];
 59     char filename[MAXSIZE], filetype[MAXSIZE];
 60     int err, ffd;
 61     rio_t request;
 62     char *handle;
 63     struct stat sbuf;
 64 
 65     rio_readinitb(&request, fd);
 66 
 67     if((err = rio_readlineb(&request, temp, MAXSIZE)) < 0)
 68         ERROR("READLINE");
 69 
 70     sscanf(temp, "%s %s %s", method, uri, protocol);
 71     process_request_body(&request);
 72     if(strcasecmp(method, "GET"))
 73     {
 74         client_error(request.rio_fd, 403, "not suppose");
 75         return;
 76     }
 77 
 78     if((err = process_uri(uri, filename, filetype)) < 0)
 79     {
 80         client_error(fd, 403, "Not Found");
 81         return;
 82     }
 83     ffd = open(filename, O_RDONLY, 0);
 84     fstat(ffd, &sbuf);
 85     handle = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, ffd, 0);
 86     close(ffd);
 87     
 88     sprintf(content, "HTTP/1.1 200 OK\r\n");
 89     sprintf(content, "%sContent-type: %s\r\n", content, filetype);
 90     sprintf(content, "%sContent-length: %lu\r\n\r\n", content, sbuf.st_size);
 91 
 92     printf("%s", content);
 93 
 94     rio_writen(fd, content, strlen(content));
 95 
 96     rio_writen(fd, handle, sbuf.st_size);
 97     munmap(handle, sbuf.st_size);
 98     close(fd);
 99     return;
100 }
101 
102 void process_request_body(rio_t *request)
103 {
104     char buf[MAXSIZE];
105     rio_readlineb(request, buf, MAXSIZE);
106     while(strcmp(buf, "\r\n"))
107     {
108         rio_readlineb(request, buf, MAXSIZE);
109     }
110     return;
111 }
112 
113 void client_error(int fd, int no,const char *msg)
114 {
115     char buf[MAXSIZE];
116     sprintf(buf, "HTTP/1.1 %d %s\r\n", no, msg);
117     sprintf(buf, "%sContent-length: %d\r\n\r\n", buf, 0);
118     rio_writen(fd, buf, strlen(buf));
119     close(fd);
120 }
121 
122 int process_uri(const char *uri, char *filename, char *filetype)
123 {
124     char buf[MAXSIZE];
125     struct stat sbuf;
126     int err;
127 
128     strcpy(buf, ".");
129     strcat(buf, uri);
130 
131     if(buf[strlen(buf) - 1] == '/')
132         strcat(buf, "index.html");
133 
134     printf("____%s____\n", buf);
135 
136     if((err = stat(buf, &sbuf)) < 0)
137         return -1;     
138 
139     strcpy(filename, buf);
140 
141     printf("%s\n", filename);
142 
143     if((S_ISREG(sbuf.st_mode)) && (S_IRUSR & sbuf.st_mode))
144     {
145         if(strstr(filename, "html"))
146             strcpy(filetype, "text/html");
147         else if(strstr(filename, "jpg"))
148             strcpy(filetype, "image/jpeg");
149         else if(strstr(filetype, "gif"))
150             strcpy(filetype, "image/gif");
151         else if(strstr(filename, "png"))
152             strcpy(filetype, "image/png");
153         else
154             strcpy(filetype, "text/plain");
155     }
156     printf("%s\n", filetype);
157     return 0;
158 }

 

posted on 2013-05-02 12:55  Zirconi  阅读(457)  评论(0编辑  收藏  举报