A http-Web-server in C

Discussion in 'C' started by lionaneesh, May 30, 2010.

  1. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    A simple code of Http-Web-Server in C done by a beginner level programmer. Please suggest if you liked it and lets make it better !! Hows that!!!

    The Code



    Code:
    #include<stdio.h>
    #include<string.h>
    #include<arpa/inet.h>
    #include<netdb.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<fcntl.h>
    #include<sys/stat.h>
    #include<stdlib.h>
    
    #define port "80"                
    #define webroot "/home/aneesh/aniroot"            // Directory to put in your files you want to host.. This is the pathname the software uses to 
                                    //    read files from
    
    
    int get_file_size(int fd)
    {
        struct stat stat_struct;
        if(fstat(fd, &stat_struct) == -1)
            return(1);
        return (int)stat_struct.st_size;
    }
    
    void send_new(int fd,char *msg)
    {
        int len = strlen(msg);
        if(send(fd,msg,len,0) == -1)
        {
            printf("Error in send\n");
        }
    }
    
    int recv_new(int fd,char *buffer)        // This function recieves the buffer untill a "End of line" byte is recieved
    {
        #define EOL "\r\n"
        #define EOL_SIZE 2
    
        char *p = buffer;            // we'll be using a pointer to the buffer than to mess with buffer directly
        int eol_matched=0;            // this is used to see that the recieved byte matched the buffer byte or not 
    
        while(recv(fd,p,1,0)!=0)        // start recv bytes 1 by 1
        {
            if( *p == EOL[eol_matched])    // if the byte matched the first eol byte that is '\r'
            {    
                ++eol_matched;        
    
                if(eol_matched==EOL_SIZE)    // if both the bytes matches the EOL
                {
                    *(p+1-EOL_SIZE) = '\0';    // End the string
                    return(strlen(buffer));    // return the bytes recieved 
                }
            }
            else
            {
                eol_matched=0;            
            }
            p++;                    // increment the pointer to recv next byte
        }
        return(0);
    }
                
    int connection(int fd)
    {
        char request[500],resource[500],*ptr;        
        int fd1,length;
    
        if(recv_new(fd,request) == 0)
        {
            printf("Recieve failed\n");
        }
    
        // Checking for a valid browser request
    
        ptr = strstr(request," HTTP/");
        if(ptr == NULL)
        {
            printf("NOT HTTP!!\n");
        }
        else
        {
            *ptr=0;
            ptr=NULL;
        
            
    
    
    
            if( strncmp(request,"GET ",4) == 0)
            {
                ptr=request+4;
            }
            if(strncmp(request,"HEAD ",5) == 0)
                ptr=request+5;
    
            if(ptr==NULL)
            {
                printf("Unknown Request !!! \n");
            }
            else
            {
                if( ptr[strlen(ptr) - 1] == '/' )
                {
                    strcat(ptr,"index.html");
                }
                strcpy(resource,webroot);
                strcat(resource,ptr);
                fd1 = open(resource,O_RDONLY,0);
                printf("Opening \"%s\"\n",resource);
                if(fd1 == -1)
                {
                    printf("404 File not found Error\n");
                    send_new(fd,"HTTP/1.0 404 Not Found\r\n");
                    send_new(fd,"Server : Aneesh/Private\r\n\r\n");
                    send_new(fd,"<html><head><title>404 not found error!! :( </head></title>");
                    send_new(fd,"<body><h1>Url not found</h1><br><p>Sorry user the url you were searching for was not found on this server!!</p><br><br><br><h1>Aneesh's Server</h1></body></html>");
                }
                else
                {
                    printf("200 OK!!!\n");
                    send_new(fd,"HTTP/1.0 200 OK\r\n");
                    send_new(fd,"Server : Aneesh/Private\r\n\r\n");
                    if( ptr == request+4 ) // if it is a get request
                    {
                        if( (length = get_file_size(fd1)) == -1 )
                            printf("Error getting size \n");
                        if( (ptr = (char *)malloc(length) ) == NULL )
                            printf("Error allocating memory!!\n");
                        read(fd1,ptr,length);
                
                        if(send(fd,ptr,length,0) == -1)
                        {
                            printf("Send err!!\n");
                        }
                        free(ptr);
                    }
                }
                close(fd);
            }
        }
        shutdown(fd,SHUT_RDWR);
    }            
    int main()
    {
        int sockfd,newfd;
        int err;
        struct addrinfo *res,*p,hints;
        struct sockaddr_storage their_addr;
        socklen_t addr_size;
        int yes=1;
        char ip[INET6_ADDRSTRLEN];
    
        memset(&hints,0,sizeof(hints));
        hints.ai_family=AF_UNSPEC;
        hints.ai_flags=AI_PASSIVE;
        hints.ai_socktype=SOCK_STREAM;
    
        printf("Server is open for listening on port 80\n");
    
        if( (err = getaddrinfo(NULL,port,&hints,&res) ) == -1)
        {
            printf("Err in getaddrinfo : %s\n",gai_strerror(err));
            return(1);
        }
    
        for(p=res;p!=NULL;p=p->ai_next)
        {        
            if( ( sockfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol) ) == -1)
            {
                printf("Socket error !!!\n");
                continue;
            }
            if( setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
            {
                printf("Setsockopt err!!\n");
                return(1);
            }
    
            if( bind(sockfd,p->ai_addr,p->ai_addrlen) == -1)
            {
                printf("Binding err\n");
                close(sockfd);            
                continue;
            }
            
            break;
        }
    
        if( listen(sockfd,15) == -1)
        {
            printf("Error in listen\n");
            return(1);
        }
        
        while(1)
        {
        
            char y;    
            addr_size = sizeof(their_addr);
            if( ( newfd = accept(sockfd, (struct sockaddr *)&their_addr,&addr_size) ) == -1)
            {
                printf("Error in accept!\n");
                return(1);
            }
            for(p=res;p!=NULL;p=p->ai_next)
            {
                void *addr;
                
                if(p->ai_family == AF_INET)
                {
                    struct sockaddr_in *ip;
                    ip = (struct sockaddr_in *)p->ai_addr;
                    addr = &(ip->sin_addr);
                }
                if(p->ai_family == AF_INET6)
                {
                    struct sockaddr_in6 *ip;
                    ip = (struct sockaddr_in6 *)p->ai_addr;
                    addr = &(ip->sin6_addr);
                }
                
                inet_ntop(p->ai_family,addr,ip,sizeof(ip));
                printf("Got connection from %s\n",ip);
            }
            connection(newfd);
        }
    
        freeaddrinfo(res);
        close(newfd);
        close(sockfd);
        return(0);
    }

    Supported OS



    I have made it on Ubuntu 9.10 ... and i think it will run on all linux system .... Windows is not supported

    Compiler instructions



    As this is a web server so it will host on port 80 to run this you need administrative rights i.e sudo rights ..

    commands :-

    compile : gcc "name" -o "o_name"
    run : sudo ./name

    Will comment my source completely for better understanding shortly ..
    Thank you for reading my source..
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Not bad stuff for and 8 month old programmer but I have changed your some wordings in the article
     
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  4. DevPro

    DevPro New Member

    Joined:
    May 31, 2010
    Messages:
    12
    Likes Received:
    0
    Trophy Points:
    0
    Mh pretty good work. I didn't know that it would be possible to create a webserver with so few code in C. I actually work on a similar software in C# and its much much much more code. My suggestion would be that you should use mutli threading to support concurrent connections.
     
  5. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    Yeah sure Sir .. Still learning that stuff They are not so easy for a self learner can you suggest me some good tutorials on selectors Except the BEEJ's One...
     
  6. IT Fan

    IT Fan New Member

    Joined:
    May 27, 2010
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    0
    Not bad!! Go ahead! You must be a very smart guy.
     
  7. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    Thanks a ton ... Sir
     
  8. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  9. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    A message to all the Viewers of this article :-

    This source is now a Opensource project and being developed further...
    If anybody want to trace the project or anybody who wanna join us programming it and adding new features
    Visit the Official Project Page :-
    https://sourceforge.net/projects/ani-server/
     
  10. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Great move buddy and once you release your first version do let me know and we can look into making a donation under the Support Open Source campaign
     
  11. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    I have already released buddy!!!
     
  12. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    That's great and so see if you have all the criteria for the donation ready.
     
  13. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    YEah.... I have it ready!!!!
     
  14. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    I don't see where you can list Go4Expert for its donation
     
  15. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    I'll add it manually as you post your donation!!
     
  16. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Where do you plan to add it??
     
  17. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    In the projects homepage and in the Project's description!!
     
  18. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Drop me an email with all the details.
     
  19. lionaneesh

    lionaneesh Active Member

    Joined:
    Mar 21, 2010
    Messages:
    848
    Likes Received:
    224
    Trophy Points:
    43
    Occupation:
    Student
    Location:
    India
    Details regarding what!!!
     
  20. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    About your project release and other information I want here.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice