Skip to content

Developed a web server in c++ which is capable of serving a dynamic web application.

Notifications You must be signed in to change notification settings

MSAJAL07/Web-applications-framework-in-CPP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Web-applications-framework-in-C-

• Developed a web server in c++ which is capable of serving a dynamic web application.

• Easy to use request header. Easy to create/send the response header for dynamic pages and for static pages it can create a response header, set appropriate HTTP code and message.

• It is also capable of handling sessions and cookies.

#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>


#include<iostream>
#include <thread> 
#include <unordered_map>
#include <map>
#include <sstream>
#include<algorithm>
using namespace std;


char * stringToChar(string str)
{
char *p=(char *)malloc((str.length()+1)*sizeof(char)); 
	p[str.length()]='\0';
    int i; 
    for (i = 0; i < str.length(); i++) { 
        p[i] = str[i]; 
    } 
return p;
}

typedef struct {
 string ext;
 string mediatype;
} extn;

extn extensions[] ={
 {"gif", "image/gif" },
 {"txt", "text/plain" },
 {"jpg", "image/jpg" },
 {"jpeg","image/jpeg"},
 {"png", "image/png" },
 {"ico", "image/ico" },
 {"zip", "image/zip" },
 {"gz",  "image/gz"  },
 {"js",  "text/javascript"},
 {"css",  "text/css"},
{"svg",  "image/svg+xml"},
 {"woff",  "font/woff"},
 {"woff2",  "font/woff2"},
 {"ttf",  "ttf/font"},
 {"tar", "image/tar" },
 {"htm", "text/html" },
 {"html","text/html" },
 {"php", "text/html" },
 {"pdf","application/pdf"},
 {"json","application/json"},
 {"zip","application/octet-stream"},
 {"rar","application/octet-stream"},
 {"0","0"} };

class ServiceResolver;
class HttpResponse;
class HttpRequest;
typedef struct {
ServiceResolver * serviceResolver=NULL;
int socket;
}IDTK;





//**************************************************************************************************************

class Service
{
public:
virtual void processGetService(HttpRequest * req,HttpResponse * res)=0;
virtual void processPostService(HttpRequest * req,HttpResponse * res)=0;
};

class GetService : public Service
{
public:
void processPostService(HttpRequest * req, HttpResponse * res)
{
cout<<"Post request not allowed\n";
}
};

class PostService : public Service
{
public:
void processGetService(HttpRequest * req, HttpResponse * res)
{
cout<<"Get request not allowed\n";
}
};

class ServiceResolver
{
public:
virtual Service * getService(string str)=0;
};



//**************************************************************************************************************





class HttpRequest
{
private:
string url;
string type;
unordered_map<string,string> mp;
map <string,string> cookies;


public:
HttpRequest(string req)
{
//cout<<"\n\ndkjdsfhksdhfk-------\n\n"<<req<<'\n';
stringstream s(req);
string tmp;
getline(s,tmp,'\n');
cout<<"***"<<tmp<<'\n';
stringstream ss(tmp);
getline(ss,type,' ');
getline(ss,tmp,' ');
cout<<"type"<<"="<<type<<'\n';
if(tmp == "/") url ="/index.html";
else
{
size_t found=tmp.find('?');
if (found != string::npos)
{
url = tmp.substr(0,found);
tmp = tmp.substr(found+1);
//cout<<"tmp="<<tmp<<'\n';
stringstream sss(tmp);
string key,val="";
while( getline(sss,key,'='))
{
getline(sss,val,'&');
mp.insert(make_pair(key,val));
cout<<key<<"== "<<val<<'\n';
}
}
else
url = tmp;
}
cout<<"url="<<url<<'\n';
string cookie;
while(s)
{
getline(s,tmp,'\n');
if(tmp.size()>1)
{
cookie=tmp;
}
}
cout<<cookie<<'\n';
stringstream sss(cookie);
getline(sss,tmp,' ');
if(tmp == "Cookie:")
{
string key,val="";
while( getline(sss,key,'='))
{
getline(sss,val,' ');
if(val[val.size()-1] == ';') val = val.substr(0,val.size()-1);
cookies.insert(make_pair(key,val));
cout<<key<<"== "<<val<<'\n';
}
}
//constructor ends
}


string getUrl()
{
return url;
}

string getType()
{
return type;
}

string getPerameter(string key)
{
 unordered_map<string,string>::iterator itr = mp.find(key);
 if(itr != mp.end()) return itr->second;
 else return "";
}


string getCookie(string key)
{
 map<string,string>::iterator itr = cookies.find(key);
 if(itr != cookies.end()) return itr->second;
 else return "";
}


//class ends
};


class HttpResponse
{
int socket;
IDTK *idtk;
HttpRequest * req;
int status;
string header;
string contentType;
string cookie;
string message;
void createHeader(int status, string message, string contentType, string cookie)
{
this->header = "HTTP/1.1 "+to_string(status)+" "+message+"\r\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\r\nAccess-Control-Allow-Origin: http://localhost:4200 \r\n"+contentType+"\r\n"+cookie+"\r\n\r\n";
}
void createHeader()
{
header = "HTTP/1.1 "+to_string(status)+" "+message+"\r\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\r\nAccess-Control-Allow-Origin: http://localhost:4200 \r\n"+contentType+"\r\n"+cookie+"\r\n\r\n";
}


string getContentType(string url)
{
reverse(url.begin(), url.end());
int i =url.find('.');
if (i != string::npos)
{
string ext=url.substr(0,i);
reverse(ext.begin(), ext.end());
cout<<"********************************   "<<ext<<'\n'; 
for (i = 0; extensions[i].ext !="0"; i++)
{
if(ext == extensions[i].ext)
{
return extensions[i].mediatype;
}
}
}
return "text/plain";
//function ends
}




void sendFile(string url)
{
char * file_name=stringToChar("public"+url);
//cout<<"URL --- "<<file_name<<'\n';
//cout<<"fileName --- "<<rq.getUrl()<<'\n';
cout<<"fileName --- "<<file_name<<'\n';
FILE *f = fopen(file_name,"rb");
if(f==NULL)
{
cout<<"File not found Error\n";
char error[1024];
sprintf(error,"<html><head><title>404 Not Found</head></title><body><p>404 Not Found: The requested resource could not be found!</p></body></html>");
sendHeader(404);
send(socket,error,strlen(error), 0);
}
else
{
cout<<"File  found \n";
int byteCount;
char buffer[1024]={'0'};
setContentType(getContentType(url));
sendHeader(200);
//char header[1024];
//sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type:%s\r\n\r\n",stringToChar());
//send(socket,header,strlen(header), 0);
cout<<"File  found sdadad \n";
 while( (byteCount= fread(buffer, 1,1024, f))>0 ){
        send(socket,buffer,byteCount, 0);
    }

}
cout<<"File  found ddd\n";
close(socket);
//function ends
}



public :
HttpResponse(IDTK * idtk ,HttpRequest * req)
{
this->socket = idtk->socket;
this->status = 0;
this->idtk = idtk;
this-> req = req;
}

void setStatus(int status)
{
this->status = status;
if(status == 200) message = "Ok";
if(status == 404) message = "Not Found";
}
void setContentType(string str)
{
this->contentType="Content-Type : " +str;
}
void setCookie(string str)
{
this->cookie = this->cookie+"Set-Cookie: "+str+"\r\n";
}
void sendHeader(int status)
{
setStatus(status);
createHeader();
cout<<"\n\n\n"<<this->header<<"\n\n\n";
char * head = stringToChar(this->header);
send(this->socket,head,strlen(head),0);
}

void process(string url)
{
cout<<"chal1\n";
string ext;
//cout<<"chal2\n";
//string url = hr.getUrl();
//cout<<"chal\n";

reverse(url.begin(), url.end());

int i =url.find('.');
if (i != string::npos)
{
ext=url.substr(0,i);
reverse(ext.begin(), ext.end());
}
reverse(url.begin(), url.end());
cout<<"chal "<<ext<<" "<<url<<'\n';
if( ext=="ss" && idtk->serviceResolver != NULL)
{
cout<<"chal11\n";
ServiceResolver * serviceResolver = idtk->serviceResolver;
Service * service;
service =serviceResolver->getService(url);
//cout<<"chal111\n";
if (service != NULL)
{
if( req->getType() == "GET" ) service->processGetService(req,this);
else service->processPostService(req,this);
}
else
sendFile(url);
}
else
sendFile(url);
// process ends
}





void out(string str)
{
char * content = stringToChar(str);
send(this->socket,content,strlen(content),0);
}
void flush()
{
close(this->socket);
}

//class ends
};

class RequestProcessor
{
char buffer[30000]={0};
int byteCount=1;
public:
//operator()
void foo(IDTK * idtk) 
{
cout<<"andar aya\n";
byteCount=recv(idtk->socket,buffer,sizeof(buffer),0);
string s=buffer;
cout<<s<<'\n';
if(s.size() ==0) 
{
cout<<"aya\n";
close(idtk->socket);
return;
} 
HttpRequest *hr= new HttpRequest(s);
HttpResponse *res = new HttpResponse(idtk,hr);
res->process(hr->getUrl());

/*
cout<<"chal1\n";
string ext;
cout<<"chal2\n";
string url = hr.getUrl();
cout<<"chal\n";

reverse(url.begin(), url.end());

int i =url.find('.');
if (i != string::npos)
{
ext=url.substr(0,i);
reverse(ext.begin(), ext.end());
}
reverse(url.begin(), url.end());
cout<<"chal "<<ext<<" "<<url<<'\n';
if( ext=="ss" && idtk->serviceResolver != NULL)
{
cout<<"chal11\n";
ServiceResolver * serviceResolver = idtk->serviceResolver;
Service * service;
service =serviceResolver->getService(url);
//cout<<"chal111\n";
if( hr.getType() == "GET" ) service->processGetService(hr,hres);
else service->processPostService(hr,hres);
}
else

hres.sendFile(url);
*/
//operator() ends
// foo ends
}


//class ends
};




class HttpServer
{
private:
int server_dis,new_socket;
struct sockaddr_in address;
int addrlen;
ServiceResolver * serviceResolver=NULL;

public:
 

void setServiceResolver(ServiceResolver * sr)
{
this->serviceResolver = sr;
}

void start(string ip ,int port)
{
this->addrlen = sizeof(address);
if((server_dis = socket(AF_INET,SOCK_STREAM,0)) == 0)
{
cout<<"Unable to create a socket\n";
return;
}

address.sin_family = AF_INET;
address.sin_addr.s_addr = htons(INADDR_ANY);
address.sin_port = htons(port);
memset(address.sin_zero, '\0', sizeof address.sin_zero);
if (bind(server_dis, (struct sockaddr *)&address, sizeof(address))<0)
    {
        perror("In bind");
       return;
    }
if (listen(server_dis, 10) < 0)
    {
        cout<<"In listen\n";
        return;
    }
cout<<"myserver is running on port:"<<port<<'\n';
while(1)
{
        if ((new_socket = accept(server_dis, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
        {
            cout<<"Unable to connect to client\n";
        }
	else
	{
cout<<"*******************************************ayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n";
		IDTK idtk;
		idtk.socket=new_socket;
		idtk.serviceResolver=this->serviceResolver;
		//new thread(RequestProcessor(),&idtk);
		RequestProcessor *r =new RequestProcessor();
		r->foo(&idtk);
	}


}
//start ends
}
//class ends
};
//**************************************************************************************888888888***************************************************************************************
//**************************************************************************************USER CODE****************************************************************************************
class Aa :public Service
{

public :
void processGetService(HttpRequest *req,HttpResponse *res)
{
string user = req->getPerameter("user");
string pass = req->getPerameter("pass");
cout<<"user "<<user<<" PASS "<<pass<<'\n';
if( user == "sajal" && pass == "mishra" )
{
//res.setContentType("text/html");
//res.init();
res->setCookie("yummy_cookie=choco  Max-Age=1000");
res->process("/test1.ss");
}
else
{
res->setContentType("text/html");
//res.init();
res->setCookie("yummy_cookies=choco0000000000  Max-Age=1000");
res->sendHeader(200);
string link ="/register.html";
res->out("<html><head><title>Can not login</title></head><body><center><a href='"+link+"' >Ragister</a></center></body></html>");
res->flush();
}
}

void processPostService(HttpRequest *req,HttpResponse *res)
{
cout<<"post chali\n";
}

};

class Bb : public GetService
{


void processGetService(HttpRequest *req,HttpResponse *res)
{
cout<<"Cookie : "<<req->getCookie("yummy_cookies")<<'\n';
res->process("/index.html");
}
};

class ABC : public ServiceResolver
{
public:
Service * getService(string str)
{
cout<<"getService "<<str<<'\n';
if (str == "/test.ss")
{
Service * s= new Aa();
return s;
}
if(str == "/test1.ss")
{
Service * s= new Bb();
return s;
} 
return NULL;
}


};




int main(int argc, char const *argv[])
{
HttpServer hs;
hs.setServiceResolver(new ABC());
hs.start("localhost",8000);
return 0;
}

About

Developed a web server in c++ which is capable of serving a dynamic web application.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages