void process_cgi(SWS_REQUEST* req_ptr){ struct stat st; char *question_mark; char absolute_path[PATH_MAX_SIZE]; char arg_str[PATH_MAX_SIZE]; if (req_ptr->method != METHOD_GET){ clientError(501, "Not Implemented", req_ptr); } memset(absolute_path, 0, PATH_MAX_SIZE); memset(arg_str, 0, PATH_MAX_SIZE); if ( (question_mark = strchr(req_ptr->path, '?')) != NULL ){ *question_mark = '\0'; snprintf(absolute_path,PATH_MAX_SIZE, "%s/%s", dir, req_ptr->path); snprintf(arg_str, PATH_MAX_SIZE, "%s", &question_mark[1]); }else{ snprintf(absolute_path,PATH_MAX_SIZE, "%s/%s", dir, req_ptr->path); } printf("cgi-file absolute_path : %s\n", absolute_path); printf("cgi-file argument list : %s\n", arg_str[0] == '\0'?"No Argument":arg_str); if (stat(absolute_path, &st) < 0){ perror("stat"); clientError(404, "Not Found", req_ptr); } switch(st.st_mode&S_IFMT){ case S_IFREG: if (st.st_mode&(S_IXUSR | S_IXGRP | S_IXOTH)){ exe_cgi(req_ptr, absolute_path, arg_str); }else{ clientError(500, "Internal Server Error", req_ptr); } break; default: clientError(500, "Internal Server Error", req_ptr); break; } }
void *accept_request(void *arg) { printf("debug:get a connect\n"); pthread_detach(pthread_self()); int client=(int)arg; char path[1024]; int cgi=0; char*query_string=NULL;//指向url的指针 char buf[1024]; char method[100]; char url[2048]; memset(method,'\0',sizeof(method)); memset(url,'\0',sizeof(url)); memset(buf,'\0',sizeof(buf)); memset(path,'\0',sizeof(path)); //#ifdef DEBUG // while(get_line(client,buf,sizeof(buf))>0) // { // printf("%s"); // } //#endif if(get_line(client,buf,sizeof(buf)-1)<0)//得到了一个链接,但是读取一行失败 { return_error_client(); close(client); return (void *)-1; } printf("debug:%s\n",buf); //读取成功,得到了请求行存储在buf中 //请求行格式是 GET / HTTP/1.1 int i=0;//buf下标 int j=0;//method下标 while(!isspace(buf[i]) && i<sizeof(buf)-1 && j<sizeof(method)-1)//提取到方法 { method[j]=buf[i]; i++; j++; } if(strcasecmp(method,"GET") && strcasecmp(method,"POST"))//判断是不是GET或POST方法 { return_error_client(); close(client); return (void *)-1; } if(!strcasecmp(method,"POST")) { cgi=1; } while(isspace(buf[i])&&i<sizeof(buf))//跳过空格 { i++; } j=0;//此时j为url的下标 while(!isspace(buf[i]) && j<sizeof(url)-1 && i<sizeof(buf))//将buf中存储的url信息放在url数组中 { url[j]=buf[i]; i++; j++; } if(strcasecmp(method,"GET")==0)//判断在GET方法下是不是传递了参数 { query_string=url; while(*query_string!='?' && *query_string!='\0') { query_string++; } if(*query_string=='?')//遇到了?说明传递了参数,必须要通过cgi来处理 { *query_string='\0'; query_string++; cgi=1; } } sprintf(path,"htdocs%s",url);//将路径存储在path中 if(path[strlen(path)-1]=='/')//处理根目录路径的情况 { strcat(path,MAIN_PAGE);//将index.html追加到后面 } struct stat st; int ret=stat(path,&st); if(ret<0)//所要请求路径资源不存在 { return_error_client(); close(client); return (void*)-1; } else//存在 { if(S_ISDIR(st.st_mode))//请求的路径是目录 { strcat(path,"/"); strcat(path,MAIN_PAGE); } else if((st.st_mode & S_IXUSR)||(st.st_mode & S_IXGRP)||(st.st_mode & S_IXOTH))//具有可执行权限,通过CGI方式执行 { // printf("path:%s\n",path); // printf("method:%s\n",method); // printf("query_string:%s\n",query_string); cgi=1; } if(cgi) { exe_cgi(client,path,method,query_string); } else { echo_html(client,path,st.st_size); } } close(client); return (void*)0; }
static void* accept_request(void *arg) //static { int sock = (int)arg; char buf[SIZE]; int len = sizeof(buf)/sizeof(*buf); char method[SIZE/10]; char url[SIZE]; char path[SIZE]; int ret = -1; int i = 0; int j = 0; char *query_string = NULL; //aim at val(can shu) int cgi = 0; #ifdef _DEBUG_ // do // { // ret = get_line(sock, buf, len); // printf("%s", buf); // fflush(stdout); // }while(ret > 0 && (strcmp(buf, "\n") != 0) ); #endif memset(buf, '\0', sizeof(buf)); memset(method, '\0', sizeof(method)); memset(url, '\0', sizeof(url)); memset(path, '\0', sizeof(buf)); //Request Line ret = get_line(sock, buf, len); if(ret <= 0) { echo_errno(sock); return (void*)1; } i = 0; //method index j = 0; //buf index while((i < (sizeof(method)/sizeof(*method) - 1)) && (j < sizeof(buf)/sizeof(*buf) - 1) && (!isspace(buf[j]) ) ) { method[i] = buf[j]; ++i; ++j; } method[i] = '\0'; if((strcasecmp(method, "GET") != 0) && (strcasecmp(method, "POST")) ) { //echo_errno(sock); return (void*)2; } //URL while(isspace(buf[j])) //Remove Space { ++j; } i = 0; while( ( i < sizeof(url)/sizeof(*url)-1 ) && (j < sizeof(buf)/sizeof(*buf)) && (!isspace(buf[j])) ) { url[i] = buf[j]; ++i; ++j; } url[i] = '\0'; if( strcasecmp(method, "POST") == 0 ) { cgi = 1; sprintf(path, "%s", url+1); } if( strcasecmp(method, "GET") == 0 ) { query_string = url; while( *query_string != '\0' && *query_string != '?' ) { query_string++; } if(*query_string == '?') { cgi = 1; *query_string = '\0'; ++query_string; } } if( strcasecmp(method, "GET") == 0 ) { sprintf(path, "htdoc%s", url); if( path[strlen(path)-1] == '/' ) { strcat(path, "index.html"); } } struct stat st; if( stat(path, &st) < 0 ) { //echo_errno(); //404 return (void*)3; } else //case : DIR { if( S_ISDIR(st.st_mode) ) { strcat(path, "index.html"); } else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) //bin(binary file) { cgi = 1; } else {} //noting to do } printf("!@!#%@^ %s !@%@^%\n", buf); if(cgi) // u+x file { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!cgi\n"); exe_cgi(sock, method, path, query_string); //cgi mode } else //.jpg .html ... { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!www\n"); clear_header(sock); //! important! echo_www(sock, path, st.st_size); } close(sock); return 0; }