//Request handler void http_request(char* readbuf, HTTPResponse* response) { char buf[1024]; char method[255]; char url[255]; char path[512]; char info[255]; int readbuf_ind = 0; int buf_ind = 0; //init HTTPResponse struct response->write_byte = 0; response->file_size = 0; response->file =NULL; response->header_size = 0; strcpy(response->method,""); strcpy(response->path,""); //init HTTPResponse struct readbuf_ind += http_getline(buf, sizeof(buf), readbuf+readbuf_ind); buf_ind += http_getrequest(method, sizeof(method), buf+buf_ind); strcpy(response->method, method); if (strcasecmp(method, "GET") && strcasecmp(method, "POST") && strcasecmp(method, "HEAD")) { strcpy(response->method,"Unimplemented"); return; } buf_ind += http_getrequest(url, sizeof(url), buf+buf_ind); sprintf(path, "%s%s",WWW, url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (!strcasecmp(method, "GET") || !strcasecmp(method, "HEAD")) strcpy(response->path, path); buf_ind += http_getrequest(info, sizeof(info), buf+buf_ind); if(strcasecmp(info, "HTTP/1.1")) { strcpy(response->method,"Unsupported"); return; } }
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; }