Thread: C http proxy remote server issues

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    25

    C http proxy remote server issues

    I'm having an issue with my attempt at a single threaded proxy server. It appears I have established a proper connection with the remote server specified by the client (ex: "http://server.ip.addr:8083/www.google.com" connects to google)

    The issue is I don't seem to be getting anything from the website, which results in my browser getting stuck on loading, and nothing happening, or so it seems...

    Here's what I've written so far, I'd greatly any solutions and feedback.

    [ProxyV2.c]
    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <err.h>
    #include <string.h>
    
    
    /********************************************************           
        *         HTTP Web Proxy coded in C                       *   
        *                                                      *   
        * Authors: Alexander Hollis, Isaias Delgado               *   
        *                                                      *   
        * Purpose:  Demonstration of a HTTP Proxy in C            *   
        *                                                      *   
        * Usage:                                               *   
        *      Refer to included manual for proper usage.      *   
        ********************************************************/
    
    
    
    
        
    
    
    
    
    
    
    
    
    
    
    
    
    int main() {
        
        char response[] = "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/html; charset=UTF-8\r\n\r\n"
        "<doctype !html>\r\n";
        
        char error[] = "HTTP/1.1 404 Not Found\r\n"
        "Content-Type: text/html; charset=UTF-8\r\n\r\n"
        "<doctype !html><html><head><title>HTML Generator Sample Page</title>"
        "</head><body><h2>404: Page Not Found</h2><p>The page you requested was not able to be located, please check your address!</p>"
        "</body></html>\r\n\n";
        
        char buffer[256], *token;
        char tokens [256][25];
        int one = 1, client_fd;
        struct sockaddr_in svr_addr, cli_addr, out_addr;
        socklen_t sin_len = sizeof(cli_addr);
        
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        int remote = socket(AF_INET, SOCK_STREAM, 0);
        
        if (sock < 0)
        err(1, "can't open socket");
    
    
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
        setsockopt(remote, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
        
        int port = 8083;
        svr_addr.sin_family = AF_INET;
        svr_addr.sin_addr.s_addr = INADDR_ANY;
        svr_addr.sin_port = htons(port);
        
        out_addr.sin_family = AF_INET;
        out_addr.sin_addr.s_addr = INADDR_ANY;
        out_addr.sin_port = htons(80);
    
    
        if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
            close(sock);
            err(1, "Can't bind");
        }
    
    
        listen(sock, 5);
        int bytesread, byteswritten;
        
        char *url;
        
        struct hostent *h;
        
        int remote_fd;
        
        char page[2000];
        char *html;
        
        char get[] = "GET /index.html HTTP/1.1\r\n\r\n";
        
        while(1) {
            
            bytesread =0; 
            byteswritten=0;
            
            
            
            client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
            
            read(client_fd, buffer, 256);
            //write(client_fd, error, sizeof(error));
            //send(client_fd, &error, sizeof(error)-1, 0);
            
            int x=0;
            for(token = strtok(buffer, " "); token!=NULL; token = strtok(NULL, " ") )
            {
                strcpy(tokens[x],token);
                x++;
            }
            url = tokens[1] +1;
            printf("url: %s\n", url);
            if(strcmp(url, "index.html") != 0) {
            h = gethostbyname(url);
            bcopy ( h->h_addr, &(out_addr.sin_addr.s_addr), h->h_length);
            remote_fd = connect(remote, (struct sockaddr *) &out_addr,(socklen_t)sizeof(out_addr));
            printf("remote_fd = %d\n",remote_fd);
            
            send(remote_fd, &get, sizeof(get)-1,0);
            bytesread = read(remote_fd, &page, 2000);
            
            html = (char *)malloc(sizeof(char) * bytesread);
            int k=0;
            for(k=0; k< bytesread; k++) {
            html[k] = page[k];
            printf("%c",html[k]);
            }
            printf("\n");
            
            printf("page[3]=%c\n",page[3]);
            //write(client_fd, response, sizeof(response)-1);
            write(client_fd, html, sizeof(html));
            }
            
            
        
        
        
        
        
        }
    }

    Thank You for reading!

    ~Alex

  2. #2
    Registered User
    Join Date
    Sep 2011
    Posts
    25

    Updated Code:

    I've gotten it to now connect to external websites, but they keep sending back a 404 page, or bad request.

    I'm using the get request "GET /index.html HTTP/1.0\r\n\r\n"

    Here's the new code:

    [ProxyV2.c]

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <err.h>
    #include <string.h>
    
    
    /********************************************************           
        * Multithreaded HTTP Web Proxy coded in C               *   
        *                                                      *   
        * Authors: Alexander Hollis, Isaias Delgado               *   
        *                                                      *   
        * Purpose:  Demonstration of a Multi-Thread Proxy in C *   
        *                                                      *   
        * Usage:                                               *   
        *      Refer to included manual for proper usage.      *   
        ********************************************************/
    
    
    
    
        
    
    
    
    
    
    
    
    
    
    
    
    
    int main() {
        
        char response[] = "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/html; charset=UTF-8\r\n\r\n"
        "<doctype !html>\r\n";
        
        char error[] = "HTTP/1.1 404 Not Found\r\n"
        "Content-Type: text/html; charset=UTF-8\r\n\r\n"
        "<doctype !html><html><head><title>HTML Generator Sample Page</title>"
        "</head><body><h2>404: Page Not Found</h2><p>The page you requested was not able to be located, please check your address!</p>"
        "</body></html>\r\n\n";
        
        char buffer[256], *token;
        char tokens [256][25];
        int one = 1, client_fd;
        struct sockaddr_in svr_addr, cli_addr, out_addr;
        socklen_t sin_len = sizeof(cli_addr);
        
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        int remote;
        
        if (sock < 0)
        err(1, "can't open socket");
    
    
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
        //setsockopt(remote, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
        
        int port = 8083;
        svr_addr.sin_family = AF_INET;
        svr_addr.sin_addr.s_addr = INADDR_ANY;
        svr_addr.sin_port = htons(port);
        
        out_addr.sin_family = AF_INET;
        out_addr.sin_addr.s_addr = INADDR_ANY;
        out_addr.sin_port = htons(80);
    
    
        if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
            close(sock);
            err(1, "Can't bind");
        }
    
    
        listen(sock, 5);
        int bytesread, byteswritten;
        
        char *url;
        
        //struct hostent *h;
        
        struct addrinfo hints, *res, *p;
        
        int remote_fd;
        
        char page[2000];
        char *html;
        int err;
        char get[] = "GET /index.html HTTP/1.0\r\n\r\n";
        
        while(1) {
            
            bytesread =0; 
            byteswritten=0;
            
            memset(&hints, 0, sizeof(hints));
            hints.ai_socktype = SOCK_STREAM;
            hints.ai_family = AF_INET;
            
            client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
            
            read(client_fd, buffer, 256);
            //write(client_fd, error, sizeof(error));
            //send(client_fd, &error, sizeof(error)-1, 0);
            
            int x=0;
            for(token = strtok(buffer, " "); token!=NULL; token = strtok(NULL, " ") )
            {
                strcpy(tokens[x],token);
                x++;
            }
            url = tokens[1] +1;
            
            //strcat(get,url);
            //strcat(get,"/index.html HTTP/1.0\n\n");
            
            //printf("GET: %s\n",get);
            
            if(strcmp(url, "index.html") != 0) {
            //h = gethostbyname(url);
            
            
            if((err = getaddrinfo(url, "http", &hints, &res)) != 0) printf("Error finding address, addrinfo returned %d.\n",err);
            
            //out_addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
            //bcopy ( (char *)res->ai_addr, (char *)&(out_addr.sin_addr.s_addr), res->ai_addrlen);
            
            for(p = res; p!= NULL; p = p->ai_next) {
            
                if((remote_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
                
                    perror("socket");
                    continue;
                
                }
                
                if(connect(remote_fd, p->ai_addr, p->ai_addrlen) == -1) {
            
                    close(remote);
                    perror("connect");
                    continue;
            }
            
            break;
            }
            
            while (1) {
            printf("url: %s\n", url);
            
            
            
            
            
            
            
            
            
            
            
            
            
            //if(remote_fd = connect(remote, (struct sockaddr *) &out_addr, sizeof(out_addr)) < 0) printf("Connection Failed!\n");
            //printf("remote_fd = %d\n",remote_fd);
            if(send(remote_fd, get, sizeof(get),0) < 0) printf("Send Failed!\n");
            bytesread = recv(remote_fd, page, 2000,0);
            if(bytesread > 0) printf("Receiving Data from Host...\n\n\n");
            puts(page);
            
            /*html = (char *)malloc(sizeof(char) * bytesread);
            int k=0;
            for(k=0; k< bytesread; k++) {
            html[k] = page[k];
            printf("%c",html[k]);
            }
            printf("\n");
            
            printf("page[3]=%c\n",page[3]);
            */
            
            //clearwrite(client_fd, response, sizeof(response)-1);
            write(client_fd, page, sizeof(page));
            break;
            }
            
            
        
        
        
        
        
        }
    }
    }

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    https://www.wireshark.org/
    An invaluable tool for debugging network programs.
    Just use it to compare the normal traffic with the proxied traffic to figure out what your proxy failed to do.

    FWIW, implementing a reliable transparent proxy is a good first step, before you try to modify the behaviour.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. I am writing a (http) proxy server in windows, it doesn't work I expect?
    By nabat1 in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-05-2013, 03:55 PM
  2. How to make a conection to a http proxy with sockets
    By Zeokat in forum C# Programming
    Replies: 5
    Last Post: 01-01-2009, 06:15 PM
  3. Small HTTP proxy
    By zacs7 in forum Networking/Device Communication
    Replies: 8
    Last Post: 09-11-2007, 03:53 AM
  4. Download File through HTTP Proxy
    By cyberCLoWn in forum Windows Programming
    Replies: 6
    Last Post: 06-19-2007, 01:40 AM
  5. http proxy - receive problem
    By laphoo in forum Linux Programming
    Replies: 7
    Last Post: 05-17-2004, 04:37 PM

Tags for this Thread