A Very Simple HTTP Server writen in C
This is a part of the semester assignment. I felt like sharing it because I couldnt find any simple code like this on internet..
I have just edited the code to meet my requirements, originally it was made by my friend.. This code simply creates a web server with root in the current working directory and default port as 10000..
Can handle a maximum of 1000 clients.. fork() is used to handle each clients. Not a very efficient way if the number of clients increase but its a basic example to how you how to implement a simple HTTP Server.
/* AUTHOR: Abhijeet Rastogi (http://www.google.com/profiles/abhijeet.1989) This is a very simple HTTP server. Default port is 10000 and ROOT for the server is your current working directory.. You can provide command line arguments like:- $./a.aout -p [port] -r [path] for ex. $./a.out -p 50000 -r /home/ to start a server at port 50000 with root directory as "/home" $./a.out -r /home/shadyabhi starts the server at port 10000 with ROOT as /home/shadyabhi */#include<stdio.h>#include<string.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/socket.h>#include<arpa/inet.h>#include<netdb.h>#include<signal.h>#include<fcntl.h>#define CONNMAX 1000#define BYTES 1024char*ROOT;int listenfd, clients[CONNMAX];void error(char*);void startServer(char*);void respond(int);int main(int argc,char* argv[]){struct sockaddr_in clientaddr;socklen_t addrlen;char c; //Default Values PATH = ~/ and PORT=10000char PORT[6]; ROOT = getenv("PWD"); strcpy(PORT,"10000");int slot=0;//Parsing the command line argumentswhile((c = getopt (argc, argv,"p:r:"))!=-1) switch(c) { case'r': ROOT = malloc(strlen(optarg)); strcpy(ROOT,optarg); break; case'p': strcpy(PORT,optarg); break; case'?': fprintf(stderr,"Wrong arguments given!!!\n"); exit(1); default: exit(1); } printf("Server started at port no. %s%s%s with root directory as %s%s%s\n","\033[92m",PORT,"\033[0m","\033[92m",ROOT,"\033[0m");// Setting all elements to -1: signifies there is no client connectedint i;for(i=0; i<CONNMAX; i++) clients[i]=-1; startServer(PORT);// ACCEPT connectionswhile(1){ addrlen =sizeof(clientaddr); clients[slot]= accept (listenfd,(struct sockaddr *)&clientaddr,&addrlen); if(clients[slot]<0) error ("accept() error"); else { if( fork()==0) { respond(slot); exit(0); } } while(clients[slot]!=-1) slot =(slot+1)%CONNMAX;}return0;}//start servervoid startServer(char*port){struct addrinfo hints,*res,*p;// getaddrinfo for host memset (&hints,0,sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE;if(getaddrinfo( NULL, port,&hints,&res)!=0){ perror ("getaddrinfo() error"); exit(1);}// socket and bindfor(p = res; p!=NULL; p=p->ai_next){ listenfd = socket (p->ai_family, p->ai_socktype,0); if(listenfd ==-1)continue; if(bind(listenfd, p->ai_addr, p->ai_addrlen)==0)break;}if(p==NULL){ perror ("socket() or bind()"); exit(1);} freeaddrinfo(res);// listen for incoming connectionsif( listen (listenfd,1000000)!=0){ perror("listen() error"); exit(1);}}//client connectionvoid respond(int n){char mesg[99999],*reqline[3], data_to_send[BYTES], path[99999];int rcvd, fd, bytes_read; memset((void*)mesg,(int)'\0',99999); rcvd=recv(clients[n], mesg,99999,0);if(rcvd<0)// receive error fprintf(stderr,("recv() error\n"));elseif(rcvd==0)// receive socket closed fprintf(stderr,"Client disconnected upexpectedly.\n");else// message received{ printf("%s", mesg); reqline[0]= strtok (mesg," \t\n"); if( strncmp(reqline[0],"GET\0",4)==0) { reqline[1]= strtok (NULL," \t"); reqline[2]= strtok (NULL," \t\n"); if( strncmp( reqline[2],"HTTP/1.0",8)!=0&& strncmp( reqline[2],"HTTP/1.1",8)!=0) { write(clients[n],"HTTP/1.0 400 Bad Request\n",25); } else { if( strncmp(reqline[1],"/\0",2)==0) reqline[1]="/index.html"; //Because if no file is specified, index.html will be opened by default (like it happens in APACHE... strcpy(path, ROOT); strcpy(&path[strlen(ROOT)], reqline[1]); printf("file: %s\n", path); if((fd=open(path, O_RDONLY))!=-1)//FILE FOUND { send(clients[n],"HTTP/1.0 200 OK\n\n",17,0); while((bytes_read=read(fd, data_to_send, BYTES))>0) write (clients[n], data_to_send, bytes_read); } else write(clients[n],"HTTP/1.0 404 Not Found\n",23);//FILE NOT FOUND } }}//Closing SOCKET shutdown (clients[n], SHUT_RDWR); //All further send and recieve operations are DISABLED... close(clients[n]); clients[n]=-1;}