diff --git a/README.md b/README.md index 842553d..95f2336 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,20 @@ This project is implemented using `C` and Parsing of HTTP referred from ``` -`Open http://localhost:port/https://www.cs.princeton.edu/` - -# Note: -- This code can only be run in Linux Machine. Please disable your browser cache. -- To run the proxy without cache Change the name of the file (`proxy_server_with_cache.c to proxy_server_without_cache.c`) MakeFile. +**Note:** +- This code can only be run in Linux or MacOS Machine. Please disable your browser cache. +- To run the proxy without cache, change the name of the file in the Makefile (`proxy_server_with_cache.c` to `proxy_server_without_cache.c`). ## Demo -![](https://github.com/Lovepreet-Singh-LPSK/MultiThreadedProxyServerClient/blob/main/pics/cache.png) +![](https://github.com/uddiGitHub/MultiThreadedProxyServerClient/blob/main/pics/cache.png) + - When website is opened for the first time (`url not found`) then cache will be miss. - Then if you again open that website again then `Data is retrieved from the cache` will be printed. -## Contributing +## Contributors + +| Contributor | GitHub | Contributions | +| :--- | :--- | :--- | +| **Lovepreet Singh** | [Lovepreet-Singh-LPSK](https://github.com/Lovepreet-Singh-LPSK) | Original proxy server implementation (multi-threading, LRU caching, HTTP parsing) | +| **Uddipta Deka** | [uddiGitHub](https://github.com/uddiGitHub) | Implemented Firewall / Access Control feature: `blocklist.txt` loading, hostname blocking via `is_blocked()` check, and `403 Forbidden` response before request forwarding. Applied to both `proxy_server_with_cache.c` and `proxy_server_without_cache.c`. | -[[Back to top]](https://github.com/Lovepreet-Singh-LPSK/MultiThreadedProxyServerClient#index) +## Contributing +[Back to top](#index) -Feel free to add some useful. You can see `How this code can be extended`. Use ideas from there and feel free to fork and CHANGE. +Feel free to add some useful. You can see `How this code can be extended`. Use ideas from there and feel free to fork and CHANGE. -#### Enjoy CODE and pull requests are highly appreciated. +#### Enjoy CODE and pull requests are highly appreciated. \ No newline at end of file diff --git a/blocklist.txt b/blocklist.txt new file mode 100644 index 0000000..4697194 --- /dev/null +++ b/blocklist.txt @@ -0,0 +1,3 @@ +www.cs.princeton.edu +blocked.com +www.google.com \ No newline at end of file diff --git a/proxy b/proxy new file mode 100755 index 0000000..ded28b2 Binary files /dev/null and b/proxy differ diff --git a/proxy.o b/proxy.o new file mode 100644 index 0000000..308cb5d Binary files /dev/null and b/proxy.o differ diff --git a/proxy_parse.o b/proxy_parse.o new file mode 100644 index 0000000..0dbbde1 Binary files /dev/null and b/proxy_parse.o differ diff --git a/proxy_server_with_cache.c b/proxy_server_with_cache.c index 9b7a9da..566aef1 100644 --- a/proxy_server_with_cache.c +++ b/proxy_server_with_cache.c @@ -47,6 +47,40 @@ pthread_mutex_t lock; //lock is used for locking the cache cache_element* head; //pointer to the cache int cache_size; //cache_size denotes the current size of the cache +#define MAX_BLOCKED_HOSTS 100 +char blocked_hosts[MAX_BLOCKED_HOSTS][256]; +int num_blocked_hosts = 0; + +void load_blocklist() { + FILE *file = fopen("blocklist.txt", "r"); + if (file == NULL) { + printf("No blocklist.txt found or unable to open. No hosts will be blocked.\n"); + return; + } + + char line[256]; + while (fgets(line, sizeof(line), file)) { + // Remove newline character + line[strcspn(line, "\r\n")] = 0; + if (strlen(line) > 0 && num_blocked_hosts < MAX_BLOCKED_HOSTS) { + strcpy(blocked_hosts[num_blocked_hosts], line); + num_blocked_hosts++; + } + } + fclose(file); + printf("Loaded %d blocked hosts from blocklist.txt\n", num_blocked_hosts); +} + +int is_blocked(char* host) { + if (host == NULL) return 0; + for (int i = 0; i < num_blocked_hosts; i++) { + if (strcmp(host, blocked_hosts[i]) == 0) { + return 1; + } + } + return 0; +} + int sendErrorMessage(int socket, int status_code) { char str[1024]; @@ -136,7 +170,7 @@ int connectRemoteServer(char* host_addr, int port_num) } -int handle_request(int clientSocket, ParsedRequest *request, char *tempReq) +int handle_request(int clientSocket, struct ParsedRequest *request, char *tempReq) { char *buf = (char*)malloc(sizeof(char)*MAX_BYTES); strcpy(buf, "GET "); @@ -302,7 +336,7 @@ void* thread_fn(void* socketNew) { len = strlen(buffer); //Parsing the request - ParsedRequest* request = ParsedRequest_create(); + struct ParsedRequest* request = ParsedRequest_create(); //ParsedRequest_parse returns 0 on success and -1 on failure.On success it stores parsed request in // the request @@ -318,10 +352,15 @@ void* thread_fn(void* socketNew) if( request->host && request->path && (checkHTTPversion(request->version) == 1) ) { - bytes_send_client = handle_request(socket, request, tempReq); // Handle GET request - if(bytes_send_client == -1) - { - sendErrorMessage(socket, 500); + if (is_blocked(request->host)) { + printf("Blocked request to %s\n", request->host); + sendErrorMessage(socket, 403); + } else { + bytes_send_client = handle_request(socket, request, tempReq); // Handle GET request + if(bytes_send_client == -1) + { + sendErrorMessage(socket, 500); + } } } @@ -381,6 +420,7 @@ int main(int argc, char * argv[]) { } printf("Setting Proxy Server Port : %d\n",port_number); + load_blocklist(); //creating the proxy socket proxy_socketId = socket(AF_INET, SOCK_STREAM, 0); diff --git a/proxy_server_without_cache.c b/proxy_server_without_cache.c index 97242f1..cfdbf0f 100644 --- a/proxy_server_without_cache.c +++ b/proxy_server_without_cache.c @@ -94,7 +94,39 @@ cache_element* head; //pointer to the cache int cache_size=0; //cache_size denotes the current size of the cache +#define MAX_BLOCKED_HOSTS 100 +char blocked_hosts[MAX_BLOCKED_HOSTS][256]; +int num_blocked_hosts = 0; + +void load_blocklist() { + FILE *file = fopen("blocklist.txt", "r"); + if (file == NULL) { + printf("No blocklist.txt found or unable to open. No hosts will be blocked.\n"); + return; + } + char line[256]; + while (fgets(line, sizeof(line), file)) { + // Remove newline character + line[strcspn(line, "\r\n")] = 0; + if (strlen(line) > 0 && num_blocked_hosts < MAX_BLOCKED_HOSTS) { + strcpy(blocked_hosts[num_blocked_hosts], line); + num_blocked_hosts++; + } + } + fclose(file); + printf("Loaded %d blocked hosts from blocklist.txt\n", num_blocked_hosts); +} + +int is_blocked(char* host) { + if (host == NULL) return 0; + for (int i = 0; i < num_blocked_hosts; i++) { + if (strcmp(host, blocked_hosts[i]) == 0) { + return 1; + } + } + return 0; +} int sendErrorMessage(int socket, int status_code) @@ -613,15 +645,19 @@ void* thread_fn(void* socketNew) if( request->host && request->path && (checkHTTPversion(request->version) == 1) ) { + if (is_blocked(request->host)) { + printf("Blocked request to %s\n", request->host); + sendErrorMessage(socket, 403); + } else { + bytes_send_client = handle_request(socket, request, buffer, tempReq); // Handle GET request - bytes_send_client = handle_request(socket, request, buffer, tempReq); // Handle GET request - - if(bytes_send_client == -1) + if(bytes_send_client == -1) - { + { - sendErrorMessage(socket, 500); + sendErrorMessage(socket, 500); + } } @@ -735,6 +771,7 @@ int main(int argc, char * argv[]) { printf("Setting Proxy Server Port : %d\n",port_number); + load_blocklist();