1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    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,283
    Likes Received:
    364
    Trophy Points:
    83
    About your project release and other information I want here.
     

Share This Page