aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--P3/4061_Project3_Threaded_webserver.pdfbin0 -> 209419 bytes
-rw-r--r--P3/Makefile9
-rw-r--r--P3/server.c157
-rw-r--r--P3/testing.zipbin0 -> 10453006 bytes
-rw-r--r--P3/util.h81
-rw-r--r--P3/util.obin0 -> 10168 bytes
-rw-r--r--P3/util.o:Zone.Identifier4
-rw-r--r--P3/web_server_solbin0 -> 28808 bytes
8 files changed, 251 insertions, 0 deletions
diff --git a/P3/4061_Project3_Threaded_webserver.pdf b/P3/4061_Project3_Threaded_webserver.pdf
new file mode 100644
index 0000000..82a08aa
--- /dev/null
+++ b/P3/4061_Project3_Threaded_webserver.pdf
Binary files differ
diff --git a/P3/Makefile b/P3/Makefile
new file mode 100644
index 0000000..921a089
--- /dev/null
+++ b/P3/Makefile
@@ -0,0 +1,9 @@
+CC = gcc
+CFLAGS = -D_REENTRANT
+LDFLAGS = -lpthread -pthread
+
+web_server: server.c
+ ${CC} -Wall -o web_server server.c util.o ${LDFLAGS}
+
+clean:
+ rm web_server webserver_log
diff --git a/P3/server.c b/P3/server.c
new file mode 100644
index 0000000..eab6e94
--- /dev/null
+++ b/P3/server.c
@@ -0,0 +1,157 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include "util.h"
+#include <stdbool.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define MAX_THREADS 100
+#define MAX_queue_len 100
+#define MAX_CE 100
+#define INVALID -1
+#define BUFF_SIZE 1024
+
+/*
+ THE CODE STRUCTURE GIVEN BELOW IS JUST A SUGGESTION. FEEL FREE TO MODIFY AS NEEDED
+*/
+
+// structs:
+typedef struct request_queue {
+ int fd;
+ char *request;
+} request_t;
+
+typedef struct cache_entry {
+ int len;
+ char *request;
+ char *content;
+} cache_entry_t;
+
+/* ******************** Dynamic Pool Code [Extra Credit A] **********************/
+// Extra Credit: This function implements the policy to change the worker thread pool dynamically
+// depending on the number of requests
+void * dynamic_pool_size_update(void *arg) {
+ while(1) {
+ // Run at regular intervals
+ // Increase / decrease dynamically based on your policy
+ }
+}
+/**********************************************************************************/
+
+/* ************************ Cache Code [Extra Credit B] **************************/
+
+// Function to check whether the given request is present in cache
+int getCacheIndex(char *request){
+ /// return the index if the request is present in the cache
+}
+
+// Function to add the request and its file content into the cache
+void addIntoCache(char *mybuf, char *memory , int memory_size){
+ // It should add the request at an index according to the cache replacement policy
+ // Make sure to allocate/free memory when adding or replacing cache entries
+}
+
+// clear the memory allocated to the cache
+void deleteCache(){
+ // De-allocate/free the cache memory
+}
+
+// Function to initialize the cache
+void initCache(){
+ // Allocating memory and initializing the cache array
+}
+
+/**********************************************************************************/
+
+/* ************************************ Utilities ********************************/
+// Function to get the content type from the request
+char* getContentType(char * mybuf) {
+ // Should return the content type based on the file type in the request
+ // (See Section 5 in Project description for more details)
+}
+
+// Function to open and read the file from the disk into the memory
+// Add necessary arguments as needed
+int readFromDisk(/*necessary arguments*/) {
+ // Open and read the contents of file given the request
+}
+
+/**********************************************************************************/
+
+// Function to receive the request from the client and add to the queue
+void * dispatch(void *arg) {
+
+ while (1) {
+
+ // Accept client connection
+
+ // Get request from the client
+
+ // Add the request into the queue
+
+ }
+ return NULL;
+}
+
+/**********************************************************************************/
+
+// Function to retrieve the request from the queue, process it and then return a result to the client
+void * worker(void *arg) {
+
+ while (1) {
+
+ // Get the request from the queue
+
+ // Get the data from the disk or the cache (extra credit B)
+
+ // Log the request into the file and terminal
+
+ // return the result
+ }
+ return NULL;
+}
+
+/**********************************************************************************/
+
+int main(int argc, char **argv) {
+
+ // Error check on number of arguments
+ if(argc != 8){
+ printf("usage: %s port path num_dispatcher num_workers dynamic_flag queue_length cache_size\n", argv[0]);
+ return -1;
+ }
+
+ // Get the input args
+
+ // Perform error checks on the input arguments
+
+ // Change SIGINT action for grace termination
+
+ // Open log file
+
+ // Change the current working directory to server root directory
+
+ // Initialize cache (extra credit B)
+
+ // Start the server
+
+ // Create dispatcher and worker threads (all threads should be detachable)
+
+ // Create dynamic pool manager thread (extra credit A)
+
+ // Terminate server gracefully
+ // Print the number of pending requests in the request queue
+ // close log file
+ // Remove cache (extra credit B)
+
+ return 0;
+}
diff --git a/P3/testing.zip b/P3/testing.zip
new file mode 100644
index 0000000..a170fbc
--- /dev/null
+++ b/P3/testing.zip
Binary files differ
diff --git a/P3/util.h b/P3/util.h
new file mode 100644
index 0000000..276ff89
--- /dev/null
+++ b/P3/util.h
@@ -0,0 +1,81 @@
+#ifndef _UTIL_H
+#define _UTIL_H
+
+
+/**********************************************
+ * init
+ - port is the number of the port you want the server to be
+ started on
+ - initializes the connection acception/handling system
+ - YOU MUST CALL THIS EXACTLY ONCE (not once per thread,
+ but exactly one time, in the main thread of your program)
+ BEFORE USING ANY OF THE FUNCTIONS BELOW
+ - if init encounters any errors, it will call exit().
+************************************************/
+void init(int port);
+
+/**********************************************
+ * accept_connection - takes no parameters
+ - returns a file descriptor for further request processing.
+ DO NOT use the file descriptor on your own -- use
+ get_request() instead.
+ - if the return value is negative, the request should be ignored.
+***********************************************/
+int accept_connection(void);
+
+/**********************************************
+ * get_request
+ - parameters:
+ - fd is the file descriptor obtained by accept_connection()
+ from where you wish to get a request
+ - filename is the location of a character buffer in which
+ this function should store the requested filename. (Buffer
+ should be of size 1024 bytes.)
+ - returns 0 on success, nonzero on failure. You must account
+ for failures because some connections might send faulty
+ requests. This is a recoverable error - you must not exit
+ inside the thread that called get_request. After an error, you
+ must NOT use a return_request or return_error function for that
+ specific 'connection'.
+************************************************/
+int get_request(int fd, char *filename);
+
+/**********************************************
+ * return_result
+ - returns the contents of a file to the requesting client and cleans
+ up the connection to the client
+ - parameters:
+ - fd is the file descriptor obtained by accept_connection()
+ to where you wish to return the result of a request
+ - content_type is a pointer to a string that indicates the
+ type of content being returned. possible types include
+ "text/html", "text/plain", "image/gif", "image/jpeg" cor-
+ responding to .html, .txt, .gif, .jpg files.
+ - buf is a pointer to a memory location where the requested
+ file has been read into memory (the heap). return_result
+ will use this memory location to return the result to the
+ user. (remember to use -D_REENTRANT for CFLAGS.) you may
+ safely deallocate the memory after the call to
+ return_result (if it will not be cached).
+ - numbytes is the number of bytes the file takes up in buf
+ - returns 0 on success, nonzero on failure.
+************************************************/
+int return_result(int fd, char *content_type, char *buf, int numbytes);
+
+/**********************************************
+ * return_error
+ - returns an error message in response to a bad request and cleans
+ up the connection to the client
+ - parameters:
+ - fd is the file descriptor obtained by accept_connection()
+ to where you wish to return the error
+ - buf is a pointer to the location of the error text
+ - returns 0 on success, nonzero on failure.
+************************************************/
+int return_error(int fd, char *buf);
+
+
+
+
+#endif /* _UTIL_H */
+
diff --git a/P3/util.o b/P3/util.o
new file mode 100644
index 0000000..3e27414
--- /dev/null
+++ b/P3/util.o
Binary files differ
diff --git a/P3/util.o:Zone.Identifier b/P3/util.o:Zone.Identifier
new file mode 100644
index 0000000..020c4e2
--- /dev/null
+++ b/P3/util.o:Zone.Identifier
@@ -0,0 +1,4 @@
+[ZoneTransfer]
+ZoneId=3
+ReferrerUrl=https://canvas.umn.edu/
+HostUrl=https://cdn.inst-fs-iad-prod.inscloudgate.net/690a17de-d930-4115-adf8-28b3140d10a7/util.o?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6ImNkbiJ9.eyJyZXNvdXJjZSI6Ii82OTBhMTdkZS1kOTMwLTQxMTUtYWRmOC0yOGIzMTQwZDEwYTcvdXRpbC5vIiwidGVuYW50IjoiY2FudmFzIiwidXNlcl9pZCI6IjQzNTYwMDAwMDAwNTU4MTAwIiwiaWF0IjoxNjA1Mjg3NTE3LCJleHAiOjE2MDUzNzM5MTd9.UIWQAlrqTVkVMvukY1HZz-_hrdWwhHFvc2Hixy2QyeAeXCnbIJ0bCQjhOgOds305Qz_-5cI0zJgoRots1ooLMg&download=1&content_type=application%2Fx-object
diff --git a/P3/web_server_sol b/P3/web_server_sol
new file mode 100644
index 0000000..cf7e206
--- /dev/null
+++ b/P3/web_server_sol
Binary files differ