利用xinetd实现简单web服务器(镜像站)
来源:互联网 发布:佳词网络科技集团 诈骗 编辑:程序博客网 时间:2024/06/01 07:51
浏览效果:
linux服务器安装xinetd后,在/etc/xinetd.d/目录下创建xhttpd文件,并输入内容:
service xhttpd{ socket_type = stream protocol = tcp wait = no user = gongluck server = /home/gongluck/桌面/xhttpd server_args = /home/gongluck/桌面/xhttpdir disable = no flags = IPv4}然后在/etc/services文件的最后添加自己使用的端口和进程的名字:
xhttpd 9527/tcp # xhttpd servicexhttpd 9527/udp # xhttpd servic重启服务:
sudo service xinetd restartxhttpd程序的代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <ctype.h>#include <dirent.h>#define LEN 4096char* get_filetype(const char* file);void send_error(int status,char* title);void send_header(int status,char* title, char* filetype);void decode(char* to, char* from);void encode(char* to, char* from);int main(int argc,const char* argv[]){ if(argc < 2) send_error(500,"server error : argc < 2"); //if(access(argv[1],R_OK | F_OK) != 0) if(chdir(argv[1]) < 0) send_error(500,"server error : chdir error"); char line[LEN],type[LEN],path[LEN],protocol[LEN]; if(fgets(line,sizeof(line),stdin) == NULL) send_error(500,"server error : type path protocol"); if(sscanf(line,"%[^ ] %[^ ] %[^ ]",type,path,protocol) != 3) send_error(400,"bad request"); if(strcasecmp(type,"GET") != 0) send_error(400,"method not allow"); if(path[0] != '/') send_error(404,"file not found"); while(fgets(line,sizeof(line),stdin) != NULL) { if(strcmp(line,"\n") == 0 || strcmp(line,"\r\n") == 0) break; } char file[LEN]; struct stat st; file[0] = '.'; decode(file+1,path); //printf("%s\n",&path[1]); //printf("%s\n",file); if(stat(file,&st) < 0) { printf("file : %s\r\n",file); send_error(500,"server error : stat"); } if(S_ISDIR(st.st_mode)) { send_header(200,"OK","text/html;charset=utf-8"); printf("<html>" "<head><title>Index of %s</title></head>" "<body bgcolor=\"#cc99cc\">" "<h4>Index of %s</h4>" "<pre>" ,file,file); struct dirent** dl; int nf = scandir(file,&dl,NULL,alphasort); if(nf < 0) perror("scandir"); else { struct stat fst; char stfile[LEN]; for(int i=0;i<nf; ++i) { strcpy(stfile,file); strcat(stfile,"/"); strcat(stfile,dl[i]->d_name); if(lstat(stfile,&fst) < 0) printf("<a href=\"%s%s/\">%-32.32s/</a>",file+1,dl[i]->d_name,dl[i]->d_name); else if(S_ISDIR(fst.st_mode)) printf("<a href=\"%s%s/\">%-32.32s/</a> \t\t%14lld",file+1,dl[i]->d_name,dl[i]->d_name,(long long)fst.st_size); else printf("<a href=\"%s%s\">%-32.32s</a> \t\t%14lld",file+1,dl[i]->d_name,dl[i]->d_name,(long long)fst.st_size); printf("<br/>"); } } printf("</pre>" "</body>" "</html>"); } else { //普通文件 FILE* fp = fopen(file,"r"); if(fp == NULL) send_error(500,"server error : open file"); send_header(200,"send header",get_filetype(file)); int ch;//这里必须用int判断EOF,我真是菜鸡。 while((ch = getc(fp)) != EOF) { putchar(ch); } fflush(stdout); fclose(fp); fp = NULL; }// printf("test success !\n"); return 0;}int hex2d(char hex){ if(hex >= '0' && hex <= '9') return hex-'0'; else if(hex >= 'a' && hex <= 'f') return hex-'a'+10; else if(hex >= 'A' && hex <= 'F') return hex-'A'+10; else return hex;}void decode(char* to, char* from){ if(to == NULL || from == NULL) return; while(*from != '\0') { if(from[0] == '%' && isxdigit(from[1]) && isxdigit(from[2])) { *to = hex2d(from[1])*16 + hex2d(from[2]); from += 3; } else { *to = *from; ++from; } ++to; } *to = '\0';}void encode(char* to, char* from){ if(to == NULL && from == NULL) return; while(*from != '\0') { if(isalnum(*from) || strchr("/._-~",*from) != NULL) { *to = *from; ++to; ++from; } else { sprintf(to,"%%%02x",*from); to += 3; from += 3; } } *to = '\0';}char* get_filetype(const char* file){ if(file == NULL) return NULL; char* dot = strrchr(file,'.'); if(*dot == '\0') return "text/plain; charset=utf-8"; else if(strcmp(dot,".html") == 0) return "text/html; charset=utf-8"; else if(strcmp(dot, ".jpg") == 0) return "image/jpeg"; else if(strcmp(dot, ".gif") == 0) return "image/gif"; else if(strcmp(dot, ".png") == 0) return "image/png"; else if(strcmp(dot, ".wav") == 0) return "audio/wav"; else if(strcmp(dot, ".avi") == 0) return "video/x-msvideo"; else if(strcmp(dot, ".mov") == 0) return "video/quicktime"; else if(strcmp(dot, ".mp3") == 0) return "audio/mpeg"; else return "text/plain; charset=utf-8";}void send_header(int status, char* title, char* filetype){ if(title == NULL || filetype == NULL) { title = "ERROR"; filetype = "text/plain; charset=utf-8"; } printf("HTTP/1.1 %d %s\r\n",status,title); printf("Content-Type:%s\r\n",filetype); printf("\r\n");}void send_error(int status,char* title){ if(title == NULL) title = "ERROR"; send_header(status,title,"text/html; charset=utf-8"); printf("<html>\n" "<head><title>%d %s</title></head>\n" "<body bgcolor=\"#cc99cc\">\n" "<h4>error!</h4>\n" "<hr>\n" "<address>\n" "<a href=\"http://blog.csdn.net/gongluck93/\">gongluck</a>\n" "</address>\n" "</body>\n" "</html>", status,title); fflush(stdout); exit(1);}由于xinetd会帮助我们与浏览器建立好连接,并且将stdin重定向到浏览器的发送端,stdout重定向到浏览器的接收端。所以xhttpd程序只需要从标准输入中读取浏览器的请求数据,把响应数据写入标准输出中即可。
这里只是用http协议的很简单的一部分:
GET /请求的文件名 HTTP/1.1
HTTP/1.1 状态码 描述Content-Type:回传文件类型\r\n回传文件数据
阅读全文
0 0
- 利用xinetd实现简单web服务器(镜像站)
- 基于xinetd的web服务器
- 利用http协议实现一个简单的web服务器
- xinetd 服务器
- 简单web服务器实现(C语言)
- 简单Web服务器(Java实现)
- WEB服务器:利用python CGI实现简单的微信后台服务器
- 利用python2.7自带的简单的web服务器SimpleHTTPServer实现web页面的访问
- 利用socket编写简单的web 服务器
- C#实现简单WEB服务器
- C#实现简单WEB服务器
- 简单的web服务器实现
- c#实现简单Web服务器
- 实现简单的web服务器
- 实现简单的Web服务器
- Python 实现简单 Web 服务器
- 简单的web服务器实现
- 利用http协议实现小型Web服务器
- BZOJ 1821 部落划分(二分+并查集)
- 字母图形
- Linux中常用操作命令
- bzoj 1216: [HNOI2003]操作系统
- HDU 1561 The more, The Better
- 利用xinetd实现简单web服务器(镜像站)
- 从零开始的"E"世界(J2SE)
- Hadoop 2.6.5 Windows环境下安装
- 回文数字 观察数字:12321,123321都有一个共同的特征,无论从左到右读还是从右向左读;都是相同的。这样的数字叫做: 回文数字。 本题要求你找到一些5位或6位的十进制数字。满足要求: 该数字
- Python数据结构
- 100 单调性及极值复习 型一:极值点判断;型二:不等式证明
- 自然语言处理课程自学笔记(一)之python正则表达式
- Zookeeper(五)Watcher机制
- [noip2015]神奇的幻方 题解