servr
来源:互联网 发布:盐城网络买花花店 编辑:程序博客网 时间:2024/05/17 03:14
/* * tiny.c - A simple, iterative HTTP/1.0 Web server that uses the * GET method to serve static and dynamic content. */#include "csapp.h"void doit(int fd);void read_requesthdrs(rio_t *rp);int parse_uri(char *uri, char *filename, char *cgiargs);void serve_static(int fd, char *filename, int filesize);void get_filetype(char *filename, char *filetype);void serve_dynamic(int fd, char *filename, char *cgiargs);void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg);int main(int argc, char *argv[]){ int listenfd, connfd, port, clientlen; struct sockaddr_in clientaddr; /* Check command line args */ if (argc != 2) {fprintf(stderr, "usage: %s <port>\n", argv[0]);exit(1); } port = atoi(argv[1]); listenfd = Open_listenfd(port); while (1) {clientlen = sizeof(clientaddr);connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);doit(connfd);Close(connfd); } return 0; }void doit(int fd){ int is_static; struct stat sbuf; char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE]; char filename[MAXLINE], cgiargs[MAXLINE]; rio_t rio; /* Read request line and headers */ Rio_readinitb(&rio, fd); Rio_readlineb(&rio, buf, MAXLINE); sscanf(buf, "%s %s %s", method, uri, version); if (strcasecmp(method, "GET")) {clienterror(fd, method, "501", "Not Implementd", "Tiny does not implement this method");return; } read_requesthdrs(&rio); /* Parse URI from GET requset */ is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) {clienterror(fd, filename, "404", "Not found", "Tiny could't find this file"); } if (is_static) /* Serve static content */ {if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)){clienterror(fd, filename, "403", "Forbidden","Tiny could't read the file");return;}serve_static(fd, filename, sbuf.st_size); } else /* Serve dynamic content */ {if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)){clienterror(fd, filename, "403", "Forbidden","Tiny could't run the CGI program");return; }serve_dynamic(fd, filename, cgiargs); }}void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg){ char buf[MAXLINE], body[MAXBUF]; /* Build the HTTP response body */ sprintf(body, "<html><title>Tiny Erroe</title>"); sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body); sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg); sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause); sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n", body); /* Print the HTTP response */ sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Content-type: text/html\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Conten-length: %d\r\n\r\n", (int)strlen(body)); Rio_writen(fd, buf, strlen(buf)); Rio_writen(fd, body,strlen(body));}void read_requesthdrs(rio_t *rp){ char buf[MAXLINE]; Rio_readlineb(rp, buf, MAXLINE); while (strcmp(buf,"\r\n")) {Rio_readlineb(rp, buf, MAXLINE);printf("%s", buf); } return;}int parse_uri(char *uri, char *filename, char *cgiargs){ char *ptr; if (!strstr(uri, "cgi-bin")) // Static content {strcpy(cgiargs, "");strcpy(filename, ".");strcat(filename, uri);if (uri[strlen(uri)-1] == '/'){strcat(filename, "test2.html");}return 1; } else // Dyanmic content {ptr = index(uri, '?');if (ptr){strcpy(cgiargs, ptr + 1);*ptr = '\0';}else{strcpy(cgiargs, "");}strcpy(filename, ".");strcat(filename, uri);return 0; }}void serve_static(int fd, char *filename, int filesize){ int srcfd; char *srcp, filetype[MAXLINE], buf[MAXBUF]; /* Send reponse headers to client */ get_filetype(filename, filetype); sprintf(buf, "HTTP/1.0 200 OK\r\n"); sprintf(buf, "%sServer: Tiny Web Server\r\n", buf); sprintf(buf, "%sConten-length: %d\r\n", buf, filesize); sprintf(buf, "%sConten-type: %s\r\n\r\n", buf, filetype); Rio_writen(fd, buf, strlen(buf)); /* Send response boby to client */printf("Send response boby to client++++++++++++++++++\n"); srcfd = Open(filename, O_RDONLY, 0); srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0); Close(srcfd); Rio_writen(fd, srcp, filesize); Munmap(srcp, filesize); printf("server_static end+++++++++++++++++++++++++++++\n");}/* * get_filetype - derive file type from file name */void get_filetype(char *filename, char *filetype){ if (strstr(filename, ".html"))strcpy(filetype, "text/html"); else if (strstr(filename, ".gif"))strcpy(filetype, "image/gif"); else if (strstr(filename, ".jpg"))strcpy(filetype, "image/jpeg"); else strcpy(filetype, "text/plain");}void serve_dynamic(int fd, char *filename, char *cgiargs){ char buf[MAXLINE], *emptylist[] = { NULL }; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Wed Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) // child { // Real server would set all CGI vars heresetenv("QUERY_STRING", cgiargs, 1);Dup2(fd, STDOUT_FILENO);Execve(filename, emptylist, environ); } Wait(NULL); // Parent waits for and reaps child}
0 0
- servr
- thrift servr
- Windows 2003 servr序列号
- SQL Servr 2008空间数据应用
- how to connect SQL servr by sqlcmd comment
- sql servr 操作xml&获取最新的自增主键
- SQL Servr 2008空间数据应用系列一:空间信息基础
- SQL Servr 2008空间数据应用系列二:空间索引(Spatial Index)基础
- SQL Servr 2008空间数据应用系列三:SQL Server 2008空间数据类型
- SQL Servr 2008空间数据应用系列五:数据表中使用空间数据类型
- SQL Servr 2008空间数据应用系列一:空间信息基础
- 在Sql Servr数据库中利用触发器来控制某一列不让用户进行修改的方法
- 文章标题
- C语言(5)------基本数据类型之字符型数据类型
- UAC相关
- Developer Training for Spark and Hadoop
- iOS面试题
- servr
- C语言(6)------基本数据类型之浮点型数据类型
- test
- 【WP】Chrome主题diy
- 在Ubuntu系统中安装Redis数据库服务器(附Redis常用的命令)
- 求两个排好序的数组的中位数 - 二分法
- Android学习1
- Activity四种启动模式
- 在mooc的Python路