Thread: A http proxy program I'm making randomly breaks.....

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    76

    A http proxy program I'm making randomly breaks.....

    I've been making this proxy server program and it sometimes works to the point where if I set it as my proxy on firefox and load a page, I can see it for a second before it gives me a error, or more often, just doesn't load the page. It obviously gets requests from its connected clients and sends them off just fine, it's the part where it receives the webpage and sends it back to the clients piece by piece that I seem to be having trouble with.

    So I was wondering if anyone could look over the bool rk(SOCKET sk,int snum) function in this code and tell me if I'm missing something blatantly obvious or not:

    (300 lines with newly added comments)

    Code:
    
    
    #include <sys/time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream.h>
    #include <sstream>//headers, duh
    using namespace std;
    #include <fstream>
    #include <winsock2.h>
    #include <windows.h>
    //made with winsock as the libary
    //as much as i like and use SDL I never got the networking to work right
    
    string istr(int op)
    {
    stringstream bob;   //int to string
    bob<<op;
    return bob.str();
    }
    
    BOOL InitConnection(SOCKET *wSock, char *SERV)  //just makes it easier to understand code later on if i put this here
    {
        int port = 80;
        struct hostent *host;
        struct sockaddr_in sin;
        int error;
       
        host = gethostbyname(SERV);
        memset( &sin, 0, sizeof sin );
        sin.sin_family = AF_INET;
        sin.sin_addr = *((in_addr *)host->h_addr);    
        sin.sin_port = htons(port);
        error = connect((SOCKET)wSock, (sockaddr*)&sin, sizeof sin);
       
        if(error != 0)
        return false;
       
        return true;
    }
      
    
    void easymsg(string text)
    {
    //cout<<text<<"\n";
    }
    
    bool *fours;
    SOCKET *fc;
    int error,kks;
    char packe[512];
    SOCKET ov;
    int vnum = 1;
    int maxclients;
    
    int sendall(char *packets,int len)//a function to send a packet to all the clients at once
    {
        int sendouts = 0;
        for(int seaa = 0; seaa<maxclients; seaa++)
        {
            if(fours[seaa])
            {
                sendouts++;
                send(fc[seaa],packets,len,0);
            }
        }
        return sendouts;
    }
    
    void ondis(int snum)//this function dictates what to do on a sudden disconect
    {//snum is the number of the sockets pointer on the array of socket arrays
    
    }
    
    
    
    bool rk(SOCKET sk,int snum)   //this function dictates what to do when it recives a packet
    { //sk is the sender's socket pointer and snum is the socket array value
    int ooo = 0;
    ooo = recv(sk,packe,sizeof(packe),0);
    if(ooo > 0){
    packe[ooo] = '\0';
    string packstr = packe;
    if(ooo < 1)
    {
    return true;
    }
    
    
    //yes, this program only supports GET for now, i'll add POST later
    if(packstr.substr(0,3) == "GET")//if the packet sent is a valid HTTP GET request
    { 
                    
                    
          int tid = packstr.find("Host:")+6; 
          string host = packstr.substr(tid,packstr.find("\n",tid)-tid-1);  // the host header's value
          string page = packstr.substr(11+host.length(),packstr.find("HTTP")-11-host.length()); //the page to get
          //this program dosn't preserve any of the headers either
          //only the Host header, and that's only because it's absolutly nessacary
           cout<<"Get request recived:\nHost: "<<host<<"\nPage: "<<page<<"\n\n";
          string von = host;
          struct hostent *pHostEnt; 
          pHostEnt = gethostbyname(host.c_str()); //get the actual IP with a DNS inquery from the host value
          struct sockaddr_in tmpSockAddr;
          memcpy(&tmpSockAddr.sin_addr,pHostEnt->h_addr,pHostEnt->h_length);
          char ip[17];
          strcpy(ip,inet_ntoa(tmpSockAddr.sin_addr)); //a pointer to the actual IP
          
          string response;
          int resp_leng; 
          char buffer[2048]; //2048 bytes is the packet length for now, i experimented with a lot and just chose the value
          struct sockaddr_in serveraddr;
          int sock;// what's the difference between int sock; and SOCKET sock; anyway
          sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
          memset(&serveraddr, 0, sizeof(serveraddr));
          serveraddr.sin_family      = AF_INET;
          serveraddr.sin_addr.s_addr = inet_addr(ip);
          serveraddr.sin_port        = htons(80); 
          cout<<"Connecting.\n";
          connect(sock, (struct sockaddr *)  &serveraddr, sizeof(serveraddr));
          
           
          
        string request = "";
        request+="GET "+page+" HTTP/1.1\r\n";  //make the request from the host and page we clipped before
        request+="Host: "+host+"\r\n";
        request+="\r\n";
        
        
        cout<<"Sending.\n";
          send(sock, request.c_str(), request.length(), 0);  //send off our request
          
        response = "";
        resp_leng= 2048; 
        cout<<"Reciving.\n";
        int stime = time(NULL);
        
    FD_SET Reader;
    
        while ((resp_leng == 2048) && time(NULL) < stime+2) //while we're still receving at full length, with a timeout of 2 seconds per page
        {
              
              FD_ZERO(&Reader);
              FD_SET(sock, &Reader);
              select(0,&Reader,NULL,NULL,NULL);
              
              if(FD_ISSET(sock,&Reader))//if it's got something the recive
              {
              
              resp_leng= recv(sock, (char*)&buffer, 2048, 0);
              if (resp_leng>0)
               {
                response+= string(buffer).substr(0,resp_leng);//add it to our response string, which actaully isn't used in this version
                cout<<"       Getting.  -  "<<resp_leng<<" bytes.\n";
                send(sk,(string(buffer).substr(0,resp_leng)).c_str(),resp_leng,0);//send it to the requesting client as soon as we get it
                }
                
            
            } 
            else
                resp_leng = 0;
        }
        
        cout<<"Done.\n";
        
        
        closesocket(sock);
        closesocket(sk);//close both sockets, for it's a proxy, no stay-alive header here or anything
          
    }
        else
        cout<<"\n\n Non GET request entered. \n\n";  //like i said, no other formats supported atm
                           
    
    
     
    return false;
    }
    return true;
    }//end function 
    
    int ask()
    {
        int temp;
        cin>>temp; //someday.....
        return temp;
    }
    
    void pnt(string out)
    {
        //cout<<out<<"\n";
    }
    
    //the above functions are more important, i mod them
    int PORT,password,psize,maxpax,portslist;
    int main(int argc, char *argv[]) //begining of program, but nothing moddable or important here
    {
    PORT = 80;
    psize = 2048;
    maxclients = 10;
    fours = new bool[maxclients-1];
    fc = new SOCKET[maxclients-1];
    for(int set00 = 0; set00<maxclients; set00++)
    {
    fours[set00] = false;
    }
    for(int nuler = 0; nuler<maxclients; nuler++)
    {
    fc[nuler] = 0;
    }
    WSAData wdat;
    WSAStartup(MAKEWORD(2, 2),&wdat);
    SOCKET server;
    server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    SOCKADDR_IN sinServer;
    memset(&sinServer, 0, sizeof(sinServer));
    sinServer.sin_family = AF_INET;
    sinServer.sin_addr.s_addr = INADDR_ANY; // Where to start server?
    sinServer.sin_port = htons(PORT); // Port
    if(bind(server, (LPSOCKADDR)&sinServer, sizeof(sinServer)) == SOCKET_ERROR){ easymsg("Couldn't bind."); }
    u_long iMode = 1;//non binding
    if(listen(server,maxclients)){ easymsg("Listen failed."); }
    ioctlsocket(server, FIONBIO, &iMode);
    FD_SET Reader;
         while (true){    //main server loop
            FD_ZERO(&Reader);
               FD_SET(server, &Reader);
    for(int set1 = 0; set1<maxclients; set1++)
    {
    if(fours[set1]){ FD_SET(fc[set1], &Reader); }
    }
                         if(error = select(0,&Reader,NULL,NULL,NULL))
                         {
                         //if(error == -1){ cout<<"Select error: "<<WSAGetLastError()<<"\n"; }
                                   if(FD_ISSET(server,&Reader))
                                   {
                                  // cout<<"Server socket 'isset'\n";
                                    bool somethingopen = false;
                                    for(int set2 = 0; set2<maxclients; set2++)
                                    {
                                    if(!fours[set2])
                                    {
                                    somethingopen = true;
                                    }
                                    }
                                            if(somethingopen){
                                                  SOCKET ATemp;
                                                  bool accepted = false;
                                                  if((ATemp = accept(server,NULL,NULL)) != INVALID_SOCKET){
                                                      ioctlsocket(ATemp,FIONBIO,&iMode);
                                                    for(int set3 = 0; set3<maxclients; set3++){
                                                       if((!fours[set3]) && !(accepted)){
                                                       fours[set3] = true;
                                                       fc[set3] = ATemp;
                                                       accepted = true;
                                                       }
                                                    }
                                                       if(!(accepted)){
                                                       ov = ATemp;
                                                       closesocket(ATemp);
                                                       closesocket(ov);
                                                       }
                                                       //cout<<"Accepted a client.\n";
                                                       kks+=1;
                                                       //cout<<kks<<" client connected.\n";
                                                  }
                                        }
                                   }
                                         for(int set4 = 0; set4<maxclients; set4++)
                                {
                                        if(fours[set4]){
                                        if(FD_ISSET(fc[set4],&Reader)){
    
                                         if(rk(fc[set4],set4)){
                                         //cout<<"Closing socket 'array "+istr(set4)+" '. \n";
                                          ondis(set4);
                                         kks-=1;
                                          //cout<<kks<<" clients connected.\n";
                                         fours[set4] = false;
                                          closesocket(fc[set4]);
    
                                                    char disca[256];
                                                    string discastr = "DIS"+istr(set4);
                                                    strcpy(disca,discastr.c_str());
    
                                         for(int set8 = 0; set8<maxclients; set8++)
                                            {
                                                    if(fours[set8])
                                                {
                                                }
                                            }
                                         }
                                        }
                                        }
                         }
                        }
    }
    closesocket(server);//quit
    WSACleanup();
    return 0;
    }
    
    //end
    Last edited by azjherben; 07-02-2010 at 05:45 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It's complaining about the lack of indentation.

    Oh wait, that's just me.

    Code:
    fours = new bool[maxclients-1];
    fc = new SOCKET[maxclients-1];
    for(int set00 = 0; set00<maxclients; set00++)
    {
    fours[set00] = false;
    }
    Here you run off the end of your array.

    I didn't bother to read anymore to find other mistakes.
    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.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    76
    Quote Originally Posted by Salem View Post
    It's complaining about the lack of indentation.

    Oh wait, that's just me.

    Code:
    fours = new bool[maxclients-1];
    fc = new SOCKET[maxclients-1];
    for(int set00 = 0; set00<maxclients; set00++)
    {
    fours[set00] = false;
    }
    Here you run off the end of your array.

    I didn't bother to read anymore to find other mistakes.
    I guess I should take out the -1 from the array's.
    I think my problem is entirely in the rk function, the rest of the program has always worked for me.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 03-05-2009, 11:32 AM
  2. Client-server system with input from separate program
    By robot-ic in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-16-2009, 03:30 PM
  3. Replies: 1
    Last Post: 12-26-2001, 03:00 AM
  4. Replies: 1
    Last Post: 11-23-2001, 10:01 AM