#ifndef DBSERVER_H #define DBSERVER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #define PORT_MIN 1024 #define PORT_MAX 65535 #define MAX_BACKLOG 10 #define UNAVALIABLE_RESPONSE \ "HTTP/1.1 503 Service Unavaliable\r\nContent-Length: 0\r\n\r\n" #define OK_RESPONSE "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n" #define ISR_RESPONSE \ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n" #define PROGRAM_USAGE "Usage: dbserver authfile connections [portnum]\n" #define PUBLIC_PATH "/public/" #define PRIVATE_PATH "/private/" // Program exit codes enum ExitCodes { EXIT_OK = 0, EXIT_ERR = 1, EXIT_FILE_ERR = 2, EXIT_PORT_ERR = 3 }; // Server Statistics struct ServerStatistics { int currentConnections; int completedConnections; int authFails; int gets; int puts; int deletes; pthread_mutex_t connectionLock; }; // Connection information needed for threads struct ConnectionInfo { int fd; int connections; char *authKey; struct ConnectionThread *connectionThread; StringStore **stringStores; }; // Information regarding a client request struct RequestParams { char *method; char *path; char *key; char *value; char *authKey; HttpHeader **headers; }; // The server statistic instance, global as needed to be called by SIGHUP struct ServerStatistics *serverStats; /* get_nth_char_position() * ----------------------- * Get the character position of the nth occurrence of that character * * s: the string to search * c: the character to look for * n: the nth occurance to retrieve the position of * * Returns: the position of the nth ocurrance of the given character */ int get_nth_char_position(const char *s, int c, int n); /* get_valid_number() * ------------------ * Checks if a given number is an actual number, then returns it as an int * * rawNumber: the number to check and convert * * Returns: -1 if the number is not valid, the converted string if it is * valid */ int get_valid_number(char *rawNumber); /* get_authkey_from_file() * ----------------------- * Gets the first line from a file * * filePath: the path to the file * * Returns: NULL if the file does not exist or the first line does not * exist, the first line otherwise */ char *get_authkey_from_file(char *filePath); /* get_address_info() * ------------------ * Gets the required addrinfo for the given port * * port: the port to assign to * * Returns: the appropriate addrinfo */ struct addrinfo *get_address_info(int port); /* open_socket() * ------------- * Opens a socket for the given port holding the given connections * * port: the port to open a socket on * connections: the amount of connections to support * * Returns: -1 if failed to connect to socket, 0 if success */ int open_socket(int port); /* serverstats_init() * ----------------------- * Initializes the server statistics * * Returns: the newly initialised server stats */ void serverstats_init(void); /* handle_listen() * --------------- * Opens a socket and deals with connections * * port: the port to open a socket on * connections: the amount of connections to support * authKey: the authorization key for the private db * * Returns: 3 if failed to connect to socket, 0 if success */ int handle_listen(int port, int connections, char *authKey); /* process_response_get() * ----------------------- * Gets the appropriate get response for the request from the client * * key: the key to get the value of from the db * stringStore: the db * * Returns: the appropriate response (200 with value or 404) */ char *process_response_get(char *key, StringStore *stringStore); /* process_response_put() * ----------------------- * Adds the appropriate value to the db and then gets the appropriate * response * * key: the key to update the value of in the db * value: the value to update the key with * stringStore: the db * * Returns: the appropiate response (200 or 500 if failed) */ char *process_response_put(char *key, char *value, StringStore *stringStore); /* process_response_delete() * ----------------------- * Deletes the given key from the db and returns the appropriate response * * key: the key to delete from the db * stringStore: the db * * Returns: the appropriate response (200 or 404) */ char *process_response_delete(char *key, StringStore *stringStore); /* check_auth_key() * ---------------- * Check the given authentication key with the given headers * * headers: the headers that may contain the authorization header * authKey: the auth key to check against the header * * Returns: 1 if the key matches, 0 otherwise */ int check_auth_key(HttpHeader **headers, char *authKey); /* construct_response() * -------------------- * Process the request and construct the needed response * * req: the request parameters * stringStores: the db to update keys * * Returns: the required response */ char *construct_response(struct RequestParams req, StringStore **stringStores); /* get_path_key() * -------------- * Gets the needed path and key from the supplied address * * address: the address given by the HTTP request * path: the pointer to the path variable to update * key: the pointer to the key variable to update */ int get_path_key(char *address, char **path, char **key); /* request_params_init() * --------------------- * Initialise the requestParams struct * * Returns: the initialised requestParams struct */ struct RequestParams request_params_init(void); /* handle_connection_request() * --------------------------- * Handles the clients request * * recv: the connection file to read from * send: the connection file to write to * authKey: the authorization key for the private db * stringStores: the arrays of dbs */ int handle_connection_request( FILE *recv, FILE *send, char *authKey, StringStore **stringStores); /* handle_client_connection() * --------------------------- * Handles the connection through the given fd * * fd: the fd to send and recieve information for the connection on * authKey: the authorization key for the private db * stringStores: the array of dbs */ void handle_client_connection( int fd, char *authKey, StringStore **stringStores); /* handle_connection() * ------------------- * Thread function for handling connections to the server, if there are too * many connections the server will turn away the client * * ciPtr: the pointer to the connection information */ void *handle_connection(void *ciPtr); /* print_server_stats() * -------------------- * Prints the server statistics. used by SIGHUP handler * * s: the signal from the signal handler */ void print_server_stats(int s); /* setup_signal_handler() * ---------------------- * Sets up the signal handler for SIGHUP */ void setup_signal_handler(void); #endif