예제 #1
0
int Open_clientfd_r(char *hostname, int port)
{
    int rc;

    if ((rc = open_clientfd_r(hostname, port)) < 0) {
        unix_error("Open_clientfd_r error");
    }
    return rc;
}
예제 #2
0
파일: proxy.c 프로젝트: LuLuPan/proxylab
/*proxy executation routine*/
int run_proxy(int connfd)
{
    char hostname[MAXLINE];
    char req_buf[MAX_OBJECT_SIZE];
    char resp_buf[MAX_OBJECT_SIZE];
    char uri[MAXLINE]; 
    int port = 80;
    int clientfd;
    rio_t rio;

    memset(hostname, 0, MAXLINE);
    memset(req_buf, 0, MAX_OBJECT_SIZE);
    memset(resp_buf, 0 , MAX_OBJECT_SIZE);

    /* read request */
    if(read_request(connfd, req_buf, uri, hostname, &port) < 0) {
        //printf("close fd: %d, tid: %d\n", connfd, gettid());
        Close(connfd);
        return -1;
    }

    /* open connection to server */
    if((clientfd = open_clientfd_r(hostname, port)) < 0)
    {
        //printf("connfd: %d, clientfd: %d, host: %s, tid: %d\n", connfd, clientfd, hostname, gettid());
        printf("Open_clientfd error\n");
        fprintf(stderr, "Error: connection refused: %s !\n", hostname);
        Close(connfd);
        return -1;
    }

    if(forward_request(&rio, req_buf, clientfd) < 0)
    {
        printf("forward_request error\n");
        fprintf(stderr, "Error: Send request to server failed !\n");
        Close(clientfd);
        Close(connfd);
        return -1;
    }
    
    if(forward_response(&rio, uri, resp_buf, connfd) < 0)
    {
        printf("forward_response\n");
        fprintf(stderr, "Error: Send response to client failed !\n");
        Close(clientfd);
        Close(connfd);
        return -1;
    }
        
    
    Close(clientfd);
    Close(connfd);
    return 0;
}
예제 #3
0
void doit(int fd) 
{
    printf("doit %d\n",fd);
    
    char buf[MAX_OBJECT_SIZE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char hostname[MAXLINE];
    char path[MAXLINE]="\0";
    int req_port=0;
    char host[MAXLINE];
    
    int serverfd,serverlen;
    struct sockaddr_in serveraddr;

    rio_t rio;
    int err=0;
    char reqhdr[MAX_OBJECT_SIZE];


    //cache
    char cache_buf[MAX_OBJECT_SIZE];
    ssize_t size;
    size=0;
    cache_node *cache_hit=NULL;

    /* Read request line and headers */
    Rio_readinitb(&rio, fd);

    if ((err=rio_readlineb(&rio, buf, MAX_OBJECT_SIZE))<0){
        clienterror(fd,"get wrong","400","bad request","bad get");
        return;
    }
    sscanf(buf, "%s %s %s", method, uri, version);
    printf("get[%s]",buf);
    
    if (strcmp(buf,"\0")==0){
        clienterror(fd,"get 0","400","Bad Request","invalid request");
        return;
    }
    if (strcasecmp(method, "GET")) { 
        clienterror(fd, method, "501", "Not Implemented",
                    "Proxy does not implement this method");
        return;
    }

    //parse uri
    if (parse_uri(uri,host,hostname,path,&req_port)<0){
        clienterror(fd,uri,"400","Bad Request","invalid request");
        return;
    }

    printf("uri %s %s %s %s %d\n",uri,host,hostname,path,req_port);

    cache_hit=find_fit(cache_head,uri);
	
    if (cache_hit!=NULL){
        //cache hit
        if (cache_to_client(fd,cache_head,cache_hit)<0){
	    clienterror(fd,"cache","505","read cache error","cache error");}
            return;
    }

    // not hit
    // establish connection with the web server
    serverlen=sizeof(serveraddr);
    serverfd=open_clientfd_r(hostname,req_port);
    printf("server %d\n",serverfd);	

    if (serverfd<=0){
        clienterror(fd,"serverfd","400","bad request","connection error");
        return;
    }	

    //built http request to the server
    sprintf(reqhdr,"GET %s HTTP/1.0\r\n",path);
    strcat(reqhdr,"Host: ");
    strcat(reqhdr,host);
    strcat(reqhdr,"\r\n");
    strcat(reqhdr,user_agent_hdr);
    strcat(reqhdr,accept_hdr);
    strcat(reqhdr,accept_encoding_hdr);

    //send addtional header
    parse_requesthdrs(&rio,reqhdr);
    Rio_writen(serverfd,reqhdr,strlen(reqhdr));

    //read from server
    rio_t server_rio;
    Rio_readinitb(&server_rio,serverfd);
    char read_server[MAX_OBJECT_SIZE];
    ssize_t length = 0;
    cache_node *new_node = NULL;

    while((length=Rio_readnb(&server_rio,read_server,MAX_OBJECT_SIZE))>0){
        printf("length%lu\n",length);
        //printf("%s",read_server);
        //forward to the client
        Rio_writen(fd,read_server,length);
        size+=length;
        if (size<=MAX_OBJECT_SIZE){
            sprintf(cache_buf,"%s",read_server);
        }
    }
    printf("buf size%lu\n",size);
    //Rio_writen(fd,read_server,MAXLINE);
    
    if (size<=MAX_OBJECT_SIZE){
        new_node=build_node(uri,size,cache_buf);
        printf("new node%p %lu\n",new_node,new_node->size);
        server_to_cache(cache_head,new_node);
    }

    Close(serverfd);

    return;
}
예제 #4
0
/*
 * handle HTTP request/response transaction of a thread
 * clinet-----(request)----->server
 *       <------(data)-------
 */
void *doit(void *connfd) {
    int fd = *(int *)connfd;
    int fd_server;
    /* detach thread */
    Pthread_detach(pthread_self());

    rio_t rio;
    char buf[MAXLINE], object_buf[MAX_OBJECT_SIZE];
    char method[MAXLINE], uri[MAXLINE], version[MAXLINE];

    /* uri info */
    char host[MAXLINE];
    int port;
    char filename[MAXLINE];

    /* Read request line and headers */
    Rio_readinitb(&rio, fd);
    Rio_readlineb(&rio, buf, MAXLINE);
    sscanf(buf, "%s %s %s", method, uri, version);

    /* request method is not GET */
    if (strcmp(method, "GET")) {
        printerror(fd, method, "501", "Not Implemented",
            "tianqiw's proxy does not implement this method");
        Close(fd);
        return NULL;
    }

    /* request method is GET
     * look for the object in cache */
    cache_block *block = cache_match(cache_ptr, uri);

    if (block != NULL) {
        /* cache hit */
        Rio_writen(fd, block->object, block->object_size);
    }
    else {
        /* cache miss */
        parse_uri(uri, host, &port, filename);

        /* construct the request header */
        char request_buf[MAXLINE];
        requestHdr(&rio, request_buf, host, filename);

        /* send request to server */
        if ((fd_server = open_clientfd_r(host, port)) < 0) {
            /* server connection error */
            char longmsg[MAXBUF];
            sprintf(longmsg, "Cannot open connection to server at <%s, %d>", host, port);
            printerror(fd, "Connection Failed", "404", "Not Found", longmsg);
            Close(fd);
            return NULL;
        }

        /* reset rio for server use */
        memset(&rio, 0, sizeof(rio_t));
        Rio_readinitb(&rio, fd_server);
        Rio_writen(fd_server, request_buf, strlen(request_buf));

        /* get data from server and send to client */
        size_t object_size = 0;
        size_t buflen;
        int is_exceed = 0;

        while ((buflen = Rio_readlineb(&rio, buf, MAXLINE))) {
            Rio_writen(fd, buf, buflen);

            /* size of the buffer exceeds the max object size
             * discard the buffer */
            if ((object_size + buflen) > MAX_OBJECT_SIZE) {
                is_exceed = 1;
            }
            else {
                memcpy(object_buf + object_size, buf, buflen);
                object_size += buflen;
            }
        }

        /* if not exceed the max object size, insert to cache */
        if (!is_exceed) {
            cache_insert(cache_ptr, uri, object_buf, object_size);
        }

        /* clear the buffer */
        Close(fd_server);
    }

    Close(fd);
    return NULL;
}