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; }
void* accept_request(void* arg) { pthread_detach(pthread_self()); int sock = (int)arg; char buf[_SIZE_]; char method[_SIZE_]; char url[_SIZE_]; char path[_SIZE_]; memset(buf, '\0', sizeof(buf)); memset(method, '\0', sizeof(method)); memset(url, '\0', sizeof(url)); memset(path, '\0', sizeof(path)); int cgi = 0; int ret = -1; char* query_string = NULL; #ifdef _DEBUG_ do{ ret = get_line(sock, buf, sizeof(buf)); printf("%s", buf); fflush(stdout); } while((ret > 0) && (strcmp(buf, "\n") != 0)); #endif ret = get_line(sock, buf, sizeof(buf)); if(ret < 0) { echo_errno(sock); return (void *)1; } //GET /HTTP/1.1 int i = 0; // method index int j = 0; // buf index while( (i < sizeof(method)-1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { method[i] = buf[j]; i++, j++; } method[i] = '\0'; while( isspace(buf[j]) ) { j++; } if(strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0) { echo_errno(sock); return (void*)2; } if(strcasecmp(method, "POST") == 0) { cgi = 1; } i = 0; // url index while( (i<sizeof(url)-1) && (j < sizeof(buf)) && (!isspace(buf[j]))) { url[i] = buf[j]; i++, j++; } 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++; } } // / /aa/bb/cc sprintf(path, "htdoc%s", url); // htdoc/ if(path[strlen(path) - 1] == '/') { strcat(path, "index.html"); } printf("method: %s\n", method); printf("path: %s\n", path); printf("query_string: %s\n", query_string); struct stat st; if(stat(path, &st) < 0) { echo_errno(sock); return (void*)3; } else { if(S_ISDIR(st.st_mode)) { strcpy(path, "htdoc/index.html"); } else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) { cgi = 1; } else {} if(cgi) { exec_cgi(sock, path, method, query_string); } else { clear_header(sock); echo_html(sock, path, st.st_size); } } close(sock); return (void*)0; }