Objective: Create a proxy server that can be connected by a single client and wo
ID: 3675308 • Letter: O
Question
Objective: Create a proxy server that can be connected by a single client and would only allow http requests. The proxy server should be able to cache up to five recent webpages and should block webpages that has been blacklisted. The proxy server should be able filter webpages with inappropriate language content and also maintain a log file. Requirements: 1. Create a C-based client-server architecture using sockets 2. The proxy server should be able to accept and service single client’s http requests 3. The proxy server should run on cse01.cse.unt.edu machine and the client should run on cse02.cse.unt.edu machine 4. The server should be able to cache at least five recent requested webpages, if available 5. The sever should be able to block websites listed in the blacklist 6. The blacklisted webpages should be blocked between a start time and an end time 7. The proxy server should be able to scan all the returned webpages from the webserver with an inappropriate language list and take appropriate action 8. The proxy server should keep log of the webpage accesses, blocked pages, and inappropriate language blocks. Procedure: 1. Create a C-based server that can accept single client’s request using sockets 2. The created proxy server should also be able to connect to the client requested website through port 80 3. Make sure the proxy server runs on cse01.cse.unt.edu and the format is as follows pserver where pserver is the proxy server executable and port_number is the port number on which the proxy server listens 4. Create a C-based client that can connect the proxy server using sockets 5. Make sure the client runs on cse02.cse.unt.edu and connects the proxy server. The user can request the web page address using the below format client url: where client is the client executable, port_number is the port number on which the client connects the server and url is the requested url. 6. The proxy server makes connection to the requested web server through port 80 7. The proxy server checks for the response from the web server 8. If the HTTP response is 200, the returned web page from the web server is cached in the proxy server. The proxy server stores the webpage in a file and assigns a filename based on the time of visit. The filename format is YYYYMMDDhhmmss. Where YYYY is the year, MM is the month, DD is the day, hh is the hour in 24-hour format, mm is the minutes, and ss is the seconds when the website was visited 9. A list file (list.txt) is created which stores the URL of the webpage and the associated cached web page filename 10. The list file stores five recent URLs. The cached websites that are not listed in the list file should be deleted 11. Once the returned web page is cached, the web page is forwarded to the client 12. If the HTTP response is not 200, do not cache the web page instead forward the HTTP response to the client 13. When the client requests a webpage that is in the list.txt file the cached page is returned 14. A log entry is created in the log file (log.txt) with status code OK200 when the page requested is returned from the webserver or with status code CACHE when the webpage is returned from the cache. A log is also created if it was a bad request or page not found with status code BADRQ. 15. Once caching is implemented, create a blacklist file (blacklist.txt). The blacklist file should contain the websites that are blocked with a start time and an end time (format: YYYYMMDDhhmmss) 16. Block the websites according to the blacklist file and respond to the client by saying website blocked 17. A log entry is created with status code BLOCK when the page is blocked based on the blacklist file 18. Create an inappropriate language file (lang.txt) and every page that is requested needs to be scanned with the words stored in the lang.txt file. There is no limit on the words that can be used to filter the webpages 19. If the requested page has inappropriate language the pages are not returned and not stored in the cache and a log is created in a log file with status code INAPP 20. Test web caching, blocking, inappropriate language blocking by accessing multiple webpages 21. A sample list.txt and blacklist.txt files are available on Blackboard for reference 22. An example log file (log.txt) and an example inappropriate language file (lang.txt) is given on Blackboard for reference.
Explanation / Answer
Socket Server
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s ", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Client Server
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf(" Usage: %s <ip of server> ",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf(" Error : Could not create socket ");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf(" inet_pton error occured ");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf(" Error : Connect Failed ");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf(" Error : Fputs error ");
}
}
if(n < 0)
{
printf(" Read error ");
}
return 0;
}
The call to the function ‘socket()’ creates an UN-named socket inside the kernel and returns an integer known as socket descriptor.
This function takes domain/family as its first argument. For Internet family of IPv4 addresses we use AF_INET.
The second argument ‘SOCK_STREAM’ specifies that the transport layer protocol that we want should be reliable ie it should have acknowledgement techniques. For example : TCP
The third argument is generally left zero to let the kernel decide the default protocol to use for this connection. For connection oriented reliable connections, the default protocol used is TCP.
The call to the function ‘bind()’ assigns the details specified in the structure ‘serv_addr’ to the socket created in the step above. The details include, the family/domain, the interface to listen on(in case the system has multiple interfaces to network) and the port on which the server will wait for the client requests to come.
The call to the function ‘listen()’ with second argument as ’10’ specifies maximum number of client connections that server will queue for this listening socket.
After the call to listen(), this socket becomes a fully functional listening socket.
In the call to accept(), the server is put to sleep and when for an incoming client request, the three way TCP handshake* is complete, the function accept () wakes up and returns the socket descriptor representing the client socket.
The call to accept() is run in an infinite loop so that the server is always running and the delay or sleep of 1 sec ensures that this server does not eat up all of your CPU processing.
As soon as server gets a request from client, it prepares the date and time and writes on the client socket through the descriptor returned by accept().
The request has succeeded. The information returned with the response is dependent on the method used in the request, for example:
GET an entity corresponding to the requested resource is sent in the response;
HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
TRACE an entity containing the request message as received by the end server.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.