//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;
  }
}
Exemple #2
0
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;
}