void http_thread_work(void *arg) { struct http_job *job = arg; struct stat st; if (stat(job->filepath, &st) == -1){ http_not_found(job->fd); return; } if (S_ISDIR(st.st_mode)){ http_show_dir(job->fd, job->filepath); } if (S_ISREG(st.st_mode)){ http_send_file(job->fd, job->filepath); } if (strcasecmp(walkerconf[THREADNUMBER].value, "0")!=0) close(job->fd); free(job); return ; }
//GET&HEAD Response handler void http_GETHEAD_response(char* writebuf, int writebuf_size, HTTPResponse* response) { FILE *resource = NULL; resource = fopen(response->path, "r"); if (resource == NULL) http_not_found(writebuf, writebuf_size, response); else { http_header(writebuf, writebuf_size, resource, response); if(!strcasecmp(response->method, "GET")) http_content(writebuf, writebuf_size, response); } }
int http_analyze(int cfd, threadpool_t *tpool) { char method[20],version[20], url[MAXURL], query[MAXQUERY], line[MAXLINE], *pos; int ret=0, iscgi=0; if ((ret = http_getline(cfd, line, MAXLINE))==0){ struct sockaddr_in saddr; socklen_t len; getsockname(cfd, (struct sockaddr*)&saddr, &len); char buf[100]; sprintf (buf, "%s ip:%s create an error connection", __FUNCTION__, inet_ntoa(saddr.sin_addr)); errlog(buf); return -1; } sscanf(line, "%s %s %s", method, url, version); if (strncasecmp(method, "GET", 3) !=0 && strncasecmp(method, "POST", 4) !=0){ http_not_support(cfd); return 0; } pos = url; while(*pos != '?' && *pos != '\0') pos++; if (*pos == '?'){ iscgi=1; *pos='\0'; pos++; strncpy(query, pos, strlen(pos)+1); } struct sockaddr_in addr; socklen_t socklen; getsockname(cfd, (struct sockaddr*)&addr, &socklen); time_t t = time(NULL); char* tmpbuf = (char*)malloc(50); sprintf (tmpbuf, "%s----", ctime(&t)); sprintf (tmpbuf, "%sIP:%s", tmpbuf, inet_ntoa(addr.sin_addr)); db_store(walker_db, (const char*)tmpbuf, (const char*)url, DB_INSERT); free(tmpbuf); if (strncasecmp(method, "GET", 3)==0){ char *filepath; filepath = (char *)malloc(strlen(walkerconf[ROOT].value)+strlen(url)+1); strcpy(filepath, walkerconf[ROOT].value); strcat(filepath, url); while((ret = http_getline(cfd, line, MAXLINE))>0); struct stat st; if (stat(filepath, &st) == -1){ http_not_found(cfd); return 0; } if (access(filepath, R_OK)){ http_error(cfd); return 0; } if ((S_ISDIR(st.st_mode) || S_ISREG(st.st_mode)) && !iscgi){ struct http_job* job = http_make_job(cfd, filepath); //threadpool_add(tpool, http_thread_work, (void*)job, 0); http_thread_work((void*)job); return 0; }else if (S_ISREG(st.st_mode) && iscgi){ }else{ http_error(cfd); return 0; } }else if (strncasecmp(method, "POST", 4) == 0){ int pi[2], pid, content_length; char *p; char *filepath; filepath = (char *)malloc(strlen(walkerconf[ROOT].value)+strlen(url)+1); strcpy(filepath, walkerconf[ROOT].value); strcat(filepath, url); content_length=-1; while((ret=http_getline(cfd, line, MAXLINE)) !=0){ if (strncasecmp(line, "Content-Length:", 15) == 0){ p = &line[15]; p += strspn(p, " \t"); content_length = atoi(p); } } if (content_length != -1){ recv(cfd, postdata, content_length, 0); } socketpair(AF_UNIX, SOCK_STREAM, 0, pi); pid = fork(); if (pid==0){ dup2(pi[0], 0); dup2(pi[1], 1); close(pi[0]); close(pi[1]); char meth_env[255]; char length_env[255]; sprintf (meth_env, "REQUEST_METHOD=%s", method); putenv(meth_env); sprintf (length_env, "CONTENT_LENGTH=%d", content_length); putenv(length_env); execl("/usr/bin/php-cgi", "php-cgi", filepath, NULL); exit(0); }else{ char recvdata[MAXLINE], packet[MAXLINE]; write(pi[0], postdata, content_length); if ((ret = read(pi[0], recvdata, MAXLINE))>0){ recvdata[ret]='\0'; //sprintf(packet, "%sContent-Type: text/html\r\n", packet); sprintf(packet, "HTTP/1.1 200 OK\r\n"); sprintf(packet, "%sContent-Length: %d\r\n\r\n", packet, ret); sprintf(packet, "%s%s", packet, recvdata); send(cfd, packet, MAXLINE, 0); //send(cfd, recvdata, MAXLINE, 0); } close(pi[0]); close(pi[1]); free(filepath); waitpid(pid, NULL, 0); } } return 0; }