diff --git a/Main.c b/Main.c index 8c6b662fc93538096dc1044e5fd73738721b715f..63aaa9be1d5825a24e898e4b1f3043fd3119e881 100644 --- a/Main.c +++ b/Main.c @@ -23,6 +23,8 @@ #include <arpa/inet.h> #include <ctype.h> #include <dirent.h> +#include <fcntl.h> +#include <magic.h> #include <netdb.h> #include <pthread.h> #include <stdio.h> @@ -61,7 +63,8 @@ pthread_t* thread_array; void* serve_request(); // Handles processing of a request from a new thread. void join_threads(); // Attempts to join all finished child threads. void send_response(); // Generates and sends http response to requesting client. -char* generate_index(); // Generates server index page. +void generate_index(); // Generates server index page. +char* get_file_type(); // Determines file type of media file. /** @@ -255,8 +258,11 @@ void send_response(struct conn_obj* connection) { char* client_request; char* request_path; char* file_path; + char* response_file_path = NULL; + char* response_file_type = NULL; char* response_buffer_head = calloc(BUFFER_SIZE, sizeof(char*)); char* response_buffer_body = calloc(BUFFER_SIZE, sizeof(char*)); + off_t response_file_size = 0; struct dirent* dir_struct; struct stat stat_buffer; DIR* dir_pointer; @@ -303,7 +309,9 @@ void send_response(struct conn_obj* connection) { if (strcmp(request_path, "") == 0) { // Index requested. Display all possible files. strcat(response_buffer_body, "<body><h1>Server Index</h1>"); - generate_index(response_buffer_body); + generate_index(response_buffer_body, connection); + } else if (strcmp(request_path, "favicon.ico") == 0) { + } else { // Search for matching file. // Media directory is small so just iterate through all files every time. @@ -311,7 +319,7 @@ void send_response(struct conn_obj* connection) { strcat(response_buffer_body, "<body>"); file_found = 0; - while (dir_pointer != NULL) { + while ((dir_pointer != NULL) && (file_found == 0)) { if ((dir_struct = readdir(dir_pointer)) != NULL) { // More files found. Continue. if ((strcmp(dir_struct->d_name, ".") != 0) && (strcmp(dir_struct->d_name, "..") != 0)) { @@ -324,10 +332,13 @@ void send_response(struct conn_obj* connection) { err_msg("Failed to stat file with err %d", return_int); } else { if (strcmp(to_lower_case(dir_struct->d_name), to_lower_case(request_path)) == 0) { - strcat(response_buffer_body, "<h1>"); - strcat(response_buffer_body, dir_struct->d_name); - strcat(response_buffer_body, "</h1>"); + // strcat(response_buffer_body, "<h1>"); + // strcat(response_buffer_body, dir_struct->d_name); + // strcat(response_buffer_body, "</h1>"); file_found = 1; + response_file_path = copy_string(file_path); + response_file_size = stat_buffer.st_size; + printf("File Size: %ld\n", stat_buffer.st_size); } } free(file_path); @@ -344,43 +355,104 @@ void send_response(struct conn_obj* connection) { // Check that file was actually found. if (file_found == 1) { - strcat(response_buffer_body, "</body>"); + file_path = copy_string_with_buffer(media_path, BUFFER_SIZE); + strcat(file_path, "/"); + strcat(file_path, dir_struct->d_name); + + strcat(response_buffer_body, "<h1>File Type</h1><p>"); + response_file_type = get_file_type(response_file_path); + + strcat(response_buffer_body, response_file_type); + strcat(response_buffer_body, "</p></body>"); + + + // Finally set up response header. + strcat(response_buffer_head, "HTTP/1.2 200 Okay\r\n"); + strcat(response_buffer_head, "Server: Cat/1.0.1\r\n"); + strcat(response_buffer_head, "Content-Type: "); + if (response_file_type != NULL) { + strcat(response_buffer_head, response_file_type); + } else { + strcat(response_buffer_head, "text/html"); + } + strcat(response_buffer_head, "\r\n"); + // strcat(response_buffer_head, "Content-Transer-Encoding: binary\r\n"); + strcat(response_buffer_head, "Content-Length: "); + temp_string = calloc(BUFFER_SIZE, sizeof(char)); + sprintf(temp_string, "%ld", response_file_size); + strcat(response_buffer_head, temp_string); + strcat(response_buffer_head, "\r\n"); + // strcat(response_buffer_head, "Connection: close\r\n"); + strcat(response_buffer_head, "\r\n"); + + + printf("%s", response_buffer_head); + + // Send header. + send(*connection->conn_fd, response_buffer_head, (strlen(response_buffer_head) + 1), 0); + + // Send actual content. + // send(*connection->conn_fd, response_buffer_body, (strlen(response_buffer_body) + 1), 0); + + + // int read_size; + // // printf("\n\nPath: %s\n", response_file_path); + // int file_descriptor = open(response_file_path, O_RDONLY); + // void* read_buffer = calloc(1, BUFFER_SIZE); + + // index = 0; + // while ((read_size = read(file_descriptor, read_buffer, BUFFER_SIZE)) != 0) { + // if (read_size < 0) { + // err_msg("Error reading from file."); + // break; + // } + // index++; + // // printf("Reading file...Loop %d Read Size: %d\n", index, read_size); + // write(*connection->conn_fd, read_buffer, read_size); + // // return_int = send(*connection->conn_fd, read_buffer, read_size, 0); + // // printf("Return int: %d\n", return_int); + // } + + + + int read_size = 1; + FILE* send_file = fopen(response_file_path, "rb"); + char* read_buffer; + + while (read_size > 0) { + read_buffer = calloc(1, BUFFER_SIZE); + + read_size = fread(read_buffer, 1, BUFFER_SIZE, send_file); + if (read_size > 0) { + write(*connection->conn_fd, read_buffer, read_size); + } + + if (read_size < BUFFER_SIZE) { + if (feof(send_file)) { + break; + } + } + } } else { strcat(response_buffer_body, "<body><h1>File was not found.</h1>"); strcat(response_buffer_body, "<h2>Did you mean one of these?</h2>"); - generate_index(response_buffer_body); + generate_index(response_buffer_body, connection); } } + printf("\n\n"); - // strcat(response_buffer_body, "<body><h1>This is a response.</h1></body>"); - - // Finally set up response header. - strcat(response_buffer_head, "HTTP/1.2 200 Okay\r\n"); - strcat(response_buffer_head, "Server: Cat/1.0.1"); - strcat(response_buffer_head, "\r\n"); - strcat(response_buffer_head, "Content-Type: text/html\r\n"); - strcat(response_buffer_head, "Content-Length: "); - temp_string = calloc(BUFFER_SIZE, sizeof(char)); - sprintf(temp_string, "%ld", strlen(response_buffer_body)); - strcat(response_buffer_head, temp_string); - strcat(response_buffer_head, "\r\n\r\n"); - - - printf("%s\n", response_buffer_head); - printf("%s\n", response_buffer_body); - // Send header. - send(*connection->conn_fd, response_buffer_head, (strlen(response_buffer_head) + 1), 0); - // Send actual content. - send(*connection->conn_fd, response_buffer_body, (strlen(response_buffer_body) + 1), 0); + close(*connection->conn_fd); } /** * Generate index page of all possible media files to grab. */ -char* generate_index(char* response_buffer_body) { +void generate_index(char* response_buffer_body, struct conn_obj* connection) { int return_int; char* file_path; + char* temp_string; + char* response_buffer_head = calloc(BUFFER_SIZE, sizeof(char*)); struct dirent* dir_struct; struct stat stat_buffer; DIR* dir_pointer = opendir(media_path);; @@ -416,5 +488,42 @@ char* generate_index(char* response_buffer_body) { } strcat(response_buffer_body, "</body>"); - return response_buffer_body; + + // Finally set up response header. + strcat(response_buffer_head, "HTTP/1.2 200 Okay\r\n"); + strcat(response_buffer_head, "Server: Cat/1.0.1\r\n"); + strcat(response_buffer_head, "Content-Type: text/html\r\n"); + // strcat(response_buffer_head, "Content-Transer-Encoding: binary\r\n"); + strcat(response_buffer_head, "Content-Length: "); + temp_string = calloc(BUFFER_SIZE, sizeof(char)); + sprintf(temp_string, "%ld", strlen(response_buffer_body)); + strcat(response_buffer_head, temp_string); + strcat(response_buffer_head, "\r\n"); + strcat(response_buffer_head, "\r\n"); + + // Send header. + send(*connection->conn_fd, response_buffer_head, (strlen(response_buffer_head) + 1), 0); + + // Send actual content. + send(*connection->conn_fd, response_buffer_body, (strlen(response_buffer_body) + 1), 0); +} + + +/** + * Uses the magic library to determine appropriate file type. + */ +char* get_file_type(char* file_path) { + char* return_string = calloc(BUFFER_SIZE, sizeof(char)); + magic_t myt; + + myt = magic_open(MAGIC_ERROR|MAGIC_MIME_TYPE); + magic_load(myt,NULL); + strcpy(return_string, magic_file(myt, file_path)); + // printf("magic output: '%s'\n", return_string); + // printf("File Path: %s\n", file_path); + // printf("magic output: '%s'\n", magic_file(myt, file_path)); + magic_close(myt); + + // free(file_path); + return return_string; }