标签:web
#pragma once #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/sendfile.h> #include<fcntl.h> #include<netinet/in.h> #include<arpa/inet.h> #include<assert.h> #include<pthread.h> #include<errno.h> #define _DET_PAGE_ index.html #define _SIZE_ 1024 static void printLog(const char* const str,const char* const fun,int line); void usage(const char* const proc); int startup(char* ip,int port); int get_line(int sock,char* buf,int size); void clear_head(int sock); void echo_html(int sock,char* path,ssize_t size); void accept_request(int sock); void* handle_client(void* arg); #include"http.h" static void printLog(const char* const str,const char* const fun,int line) { printf("%s:%s:%d\n",str,fun,line); } void usage(const char* const proc) { assert(proc); printLog(proc,__FUNCTION__,__LINE__); } int startup(char* ip,int port) { int sock=socket(AF_INET,SOCK_STREAM,0); if(sock<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } int opt=1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); struct sockaddr_in local; local.sin_family=AF_INET; local.sin_port=htons(port); local.sin_addr.s_addr=inet_addr(ip); if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } if(listen(sock,5)<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } return sock; } int get_line(int sock,char* buf,int size) { assert(buf); int i=0; ssize_t _s=-1; char ch=‘\0‘; while(i<size-1) { _s=recv(sock,&ch,1,0); if(_s>0) { if(ch==‘\r‘) { if(_s=recv(sock,&ch,1,MSG_PEEK)) { if(_s>0&&ch==‘\n‘) recv(sock,&ch,1,0); } } buf[i++]=ch; } else { break; } } buf[i]=‘\0‘; return i; } void clear_head(int sock) { char buf[_SIZE_]; buf[0]=‘\0‘; ssize_t _s=-1; while(_s>0&&strcmp(buf,"\n")!=0) { get_line(sock,buf,sizeof(buf)); } } void echo_html(int sock,char* path,ssize_t size) { int fd=open(path,O_RDONLY); if(fd<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } char* status_line="HTTP/1.1 200 ok/r/n/r/n"; send(sock,status_line,strlen(status_line)); if(sendfile(sock,fd,NULL,size)<0) { close(fd); return; } close(fd); } void accept_request(int sock) { char buf[_SIZE_]; #ifdef _DEBUG1_ int ret=-1; int i=0,j=0; char method[_SIZE_/2]; char url[_SIZE_]; char path[_SIZE_]; memset(method,‘\0‘,sizeof(method)); memset(buf,‘\0‘,sizeof(buf)); memset(path,‘\0‘,sizeof(path)); memset(url,‘\0‘,sizeof(url)); //while(ret=get_line(sock,buf,sizeof(buf)>0)) //{ // if(ret==0) // { // printLog(strerror(errno),__FUNCTION__,__LINE__); // break; // } // printf("%s",buf); //} if(get_line(sock,buf,sizeof(buf))==0) { printLog("errno",__FUNCTION__,__LINE__); return; } i=j=0; while(!isspace(buf[i])&&i<sizeof(buf)&&j<sizeof(method)-1) { method[j++]=buf[i++];//get method } method[j]=‘\0‘; j=0; while(isspace(buf[i])) { ++i; } while(!isspace(buf[i])&&i<sizeof(buf)&&j<sizeof(url)-1) { url[j++]=buf[i++]; } int cgi=0; if(strncasecmp(method,"POST")!=0&&strncasecmp(method,"GET")!=0) { printLog("errno",__FUNCTION__,__LINE__); return; } if(strncasecmp(method,"POST")) { cgi=1; } if(strncasecmp(method,"GET")) { char* query_string=url; while(*query_string!=‘\0‘&&*query_string!=‘?‘) { if(*query_string==‘?‘) { *query_string=‘\0‘; cgi=1; } ++query_string; } sprintf(path,"ntdos%s",url);//sprintf if(path[strlen(path)-1]==‘/‘) { strcat(path,_DET_PAGE_); } struct stat st; if(stat(path,&st)<0)//not exist { printLog("errno",__FUNCTION__,__LINE__); return; } else if(S_ISDIR(st.st_mode))//dir { strcpy(path,"htdocs/"); strcat(path,_DEF_PAGE_); } else if((st.st_mode&S_IXUSR)||(st.st_mode&S_IXGPR)||(st.st_mode&S_IXOTH)) { cgi=1; } if(cgi) { execute_cgi(sock,path,method,query_string); } else { clear_head(sock); echo_html(sock,path,st.st_size); } } #endif close(sock); } void* handle_client(void* arg) { int sock=(int)arg; accept_request(sock); return NULL; } //main.c #include"http.h" int main(int argc,char* argv[]) { if(argc!=3) { usage(argv[0]); return 1; } char* ip=argv[1]; int port=atoi(argv[2]); int listen_sock=startup(ip,port); struct sockaddr_in client; socklen_t len=sizeof(client); fflush(stdout); while(1) { int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len); if(new_sock<0) { printf("no client"); fflush(stdout); continue; } pthread_t id; pthread_create(&id,NULL,handle_client,(void*)new_sock); pthread_detach(id);//set detach return val:0/errno } return 0; }
本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1785983
标签:web
原文地址:http://10541556.blog.51cto.com/10531556/1785983