Cache generated only after a particular site is accessed by atleast 5 different users.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include<fstream>
using namespace std;
FILE *fp,*lp;
struct cachecount
{
char request[100];
int usersocks[20];
int usernum;
}tempcache;
int main(int argc , char* argv[])
{
fp = fopen("cache.txt","w");
char newhostname[100] = {0};
char newpathname[100] = {0};
int j = 0;
int m ;
pid_t pid;
struct sockaddr_in address_in , server_addr , client_addr;
struct hostent* host;
int sockfd , newsockfd , status;
if(argc<2)
{
printf("Enter Port Number\n");
exit(0);
}
printf("Port Accepted \n");
bzero((char *)&server_addr , sizeof(server_addr));
bzero((char *)&client_addr , sizeof(client_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[1]));
server_addr.sin_addr.s_addr = INADDR_ANY;
printf("Intializing Socket....\n");
sockfd = socket (AF_INET , SOCK_STREAM , IPPROTO_TCP);
if(sockfd < 0)
{
printf("Intialization Failed...\n");
exit(0);
}
printf("Intialization Successful....\n");
status = bind(sockfd, (struct sockaddr*)&server_addr , sizeof(server_addr));
if(status < 0)
{
printf("Error on Binding...");
exit(0);
}
listen(sockfd , 60);
printf("Listening.....\n");
socklen_t clilength = sizeof(client_addr);
accepting:
newsockfd = accept(sockfd , (struct sockaddr*)&client_addr , &clilength);
if(newsockfd < 0)
{
printf("Cannot Accept Connection....\n");
exit(0);
}
printf("Forking......\n");
pid = fork();
if(pid == 0)
{
struct sockaddr_in hostaddr;
int flag = 0 , forksock, newforksock , n , port = 0 , i , j ;
char buffer[10000] , part1[400], part2[400], part3[10];
char hostname[100] , pathname[100];
char* temp = NULL;
bzero((char *)buffer,10000);
recv(newsockfd , buffer , 10000 , 0);
sscanf(buffer,"%s %s %s",part1,part2,part3);
// Check if the request is in right format or else terminate it.
if(strncmp(part1,"GET",3) == 0)
{
if(strncmp(part2,"http://",7) == 0)
{
if((strncmp(part3,"HTTP/1.1",8) == 0) || (strncmp(part3,"HTTP/1.0",8) == 0))
{
for( i = 0 , j = 7 ; j < strlen(part2) ; i++ , j++) // Gets our hostname
{
if(part2[j] == '/')
break;
hostname[i] = part2[j];
}
hostname[i] = '\0';
host = gethostbyname(hostname);
for( i = 0 , j ; part2[j] != ' ' ; i++ ,j++) // Gets our pathname
{
pathname[i] = part2[j] ;
}
port = 80 ; // default
printf("Details Of Accepted HTTP Request\n");
printf("Hostname : %s\n",hostname);
printf("Pathname : %s \n",pathname);
printf("Port : 80 \n");
bzero((char *)&hostaddr , sizeof(hostaddr));
hostaddr.sin_port = htons(port);
hostaddr.sin_family = AF_INET ;
bcopy((char*)host->h_addr,(char*)&hostaddr.sin_addr.s_addr,host->h_length);
forksock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
newforksock = connect(forksock , (struct sockaddr*)&hostaddr , sizeof(struct sockaddr));
if(newforksock < 0)
{
printf("Cannot Connect...Exiting\n");
exit(0);
}
sprintf(buffer ,"Connected to %s IP - %s \n",part2,inet_ntoa(hostaddr.sin_addr));
printf("\n%s\n",buffer);
bzero((char *)buffer , sizeof(buffer));
if(!(strlen(pathname) > 1))
sprintf(buffer,"GET / %s \r\nHost: %s\r\nConnection : close\r\n\r\n",part3,hostname);
else
sprintf(buffer,"GET %s %s\r\nHost: %s\r\nConnection : close\r\n\r\n",pathname,part3,hostname);
n = send(forksock , buffer , strlen(buffer), 0);
printf("\n%s\n",buffer);
for(m = 0 ; m<strlen(pathname) ; m++)
{
if(pathname[m] == '/')
{
newpathname[m] = '-';
}
else
newpathname[m] = pathname[m];
}
strcpy(newhostname,hostname);
strcat(newhostname,newpathname);
strcat(newhostname,".txt");
int newflag = -1,y;
ifstream opened("cache.ca",ios::binary);
opened.clear();
for(int x=0;!opened.eof();x++)
{
opened.read((char*)&tempcache,sizeof(tempcache));
if(strcmp(newhostname,tempcache.request)==0)
{ //new flag values ---> 1 = cache this time; 2 = cache exists; 3 = No cache but has entry ... -1 = no cache, no entry
if(tempcache.usernum == 4)
{
for(y=0;y<tempcache.usernum;y++)
{
if(newsockfd == tempcache.usersocks[y])
{
break;
}
}
if(y == 4)
{
newflag = 1;
}
}
else if (tempcache.usernum >= 5)
{
newflag = 2;
}
else
{
newflag = 3;
}
break;
}
}
opened.close();
if(newflag == -1)
{
fstream saved("cache.ca",ios::in|ios::out|ios::binary|ios::app);
strcpy(tempcache.request,newhostname);
tempcache.usernum = 1;
tempcache.usersocks[tempcache.usernum - 1] = newsockfd;
saved.write((char*)&tempcache,sizeof(tempcache));
saved.close();
}
else
{
fstream saved1("cache.ca",ios::in|ios::out|ios::binary);
saved1.clear();
for(int z=0;!saved1.eof();z++)
{
saved1.read((char*)&tempcache,sizeof(tempcache));
if(strcmp(tempcache.request,newhostname)==0)
{
break;
}
}
int r = saved1.tellg();
saved1.seekg(r - sizeof(tempcache));
int h;
for(h=0;h<tempcache.usernum;h++)
{
if(newsockfd == tempcache.usersocks[h])
{
break;
}
}
if(h == tempcache.usernum)
{
tempcache.usersocks[h] = newsockfd;
tempcache.usernum++;
}
saved1.write((char*)&tempcache,sizeof(tempcache));
saved1.close();
}
fp = fopen(newhostname,"r");
if(fp == NULL || newflag == -1 || newflag == 1 || newflag == 3)
{
printf("Cache Doesn't Exists...Using Internet");
}
else
{
printf("Cache Found...");
bzero((char *)buffer,sizeof(buffer));
while(fgets(buffer,10000,fp))
{
send(newsockfd , buffer , strlen(buffer) , 0);
}
goto cache;
}
if(n < 0)
{
printf("Error\n");
exit(0);
}
// creating text file as cache with hostname's name
if(newflag == 1)
{
fp = fopen(newhostname,"w");
printf("textfile made"); }
do
{
bzero((char *)buffer , 500);
n = recv(forksock , buffer , 500, 0);
if(n < 0)
{
printf("Error\n");
exit(0);
}
else
{
if (newflag == 1)
{ fprintf(fp,buffer); }
send(newsockfd,buffer,strlen(buffer),0);
}
}while(n>0);
}
}
}
else
{
send(newsockfd , "400 : BAD REQUEST",18,0);
}
close(newsockfd);
}
else
goto accepting;
cache:
fclose(fp);
close(sockfd);
return 0;
}