From d6e59d18d34ddecb171f8c7d61ec81d37eeaa4ac Mon Sep 17 00:00:00 2001 From: Saleh Ahmed Khan <s.khan20@student.unimelb.edu.au> Date: Wed, 18 Apr 2018 19:56:36 +1000 Subject: [PATCH] Code cleaned up, better separation of functions --- .gitignore | 1 + .vscode/settings.json | 7 +++- get.c | 86 +++++++++++++++++++++++++++++++++---------- get.h | 10 +++-- server.c | 43 +++++----------------- 5 files changed, 91 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index b23ffb6..a4c86dd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ test/* .vscode/c_cpp_properties.json .vscode/settings.json home/file.txt +server diff --git a/.vscode/settings.json b/.vscode/settings.json index 82a41b8..b150ea6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,11 @@ "iostream": "c", "get.h": "c", "system_error": "c", - "ostream": "c" + "ostream": "c", + "initializer_list": "c", + "type_traits": "c", + "xstring": "c", + "xutility": "c", + "stdio.h": "c" } } \ No newline at end of file diff --git a/get.c b/get.c index c9137a4..c9e9bd0 100644 --- a/get.c +++ b/get.c @@ -1,41 +1,89 @@ +#define FOUND_RESPONSE "HTTP/1.0 200 OK\r\n" /* add \n*/ +#define NOT_FOUND_RESPONSE "HTTP/1.0 404\r\n\r\n" + #include "get.h" #include <stdio.h> #include <string.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <sys/sendfile.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> -#define FOUND 0 -#define NOT_FOUND -1 +#define FOUND 1 +#define NOT_FOUND 0 -void get(char* req, char* root, FILE** content) { - // Extract just the file path from the request message into the char array 'path'. - const char* path_start = strstr(req, "GET") + 4; - const char* path_end = strstr(req, "HTTP")-1; +void parse_request_and_send_response(char* root, char* buffer, int newsockfd) { + const char* path_start = strstr(buffer, "GET") + 4; + const char* path_end = strstr(buffer, "HTTP")-1; char path[path_end - path_start]; - // int l = (path_end-path_start); - // printf("%c", l); strncpy(path, path_start, path_end - path_start); path[sizeof(path)] = '\0'; // null terminator char full_path[sizeof(path) + sizeof(root)]; strcpy(full_path, root); - strcat(full_path, path); - printf("%s\n _____ \n", full_path); - if (find_file(full_path) == FOUND) open_file(content, full_path); - else *content = NULL; + strcat(full_path, path); + /* If the file is found, repond with the 200 header and the file */ + if (file_found(full_path)) respond_OK_and_send_file(full_path, newsockfd); + /* otherwise, respond with a 404 NOT FOUND response */ + else respond_NOTFOUND(newsockfd); } -int find_file(char* path_to_file) { - FILE *fp; - fp = fopen(path_to_file, "r"); +int file_found(char* path_to_file) { + /* Try to open the file at given path, check + if a non-NULL FILE pointer is returned */ + FILE* fp = fopen(path_to_file, "r"); if (fp != NULL) { fclose(fp); - printf("FOUND\n"); return FOUND; } else { - printf("NOT FOUND\n"); return NOT_FOUND; } } -void open_file(FILE** file, char* path_to_file) { - *file = fopen(path_to_file, "r"); +void respond_OK_and_send_file(char* full_path, int newsockfd) { + /* First open the file, get the information for + the header (size, mime type) and send the file */ + int fd = open(full_path, O_RDONLY); + size_t size = get_size(fd); + char response[128]; + make_response_header(response, full_path, size); + write(newsockfd, response, strlen(response)); + sendfile(newsockfd, fd, NULL, size); + close(fd); +} + +void respond_NOTFOUND(int newsockfd) { + /* Send a 404 NOT FOUND response to the client */ + write(newsockfd, NOT_FOUND_RESPONSE, strlen(NOT_FOUND_RESPONSE)); +} + +size_t get_size(int fd) { + struct stat st; + fstat(fd, &st); + return st.st_size; +} + +void get_mime_type(char* path, char* mime) { + if (strstr(path, ".jpg") != NULL) { + strcpy(mime, "image/jpeg"); + } else if (strstr(path, ".html") != NULL) { + strcpy(mime, "text/html"); + } else if (strstr(path, ".css") != NULL) { + strcpy(mime, "text/css"); + } else if (strstr(path, ".js") != NULL) { + strcpy(mime, "text/javascript"); + } else { + strcpy(mime, "unknown"); + } +} + +void make_response_header(char* response, char* path, size_t size) { + char mime[64]; + get_mime_type(path, mime); + sprintf(response, "%sContent-Length: %zu\r\nContent-Type: %s\r\n\r\n", FOUND_RESPONSE, size, mime); } \ No newline at end of file diff --git a/get.h b/get.h index 9fa75ea..8e62fe0 100644 --- a/get.h +++ b/get.h @@ -5,8 +5,12 @@ #include <stdio.h> /* Prototypes for the functions */ -void get(char* req, char* root, FILE** content); // means everything incl header -int find_file(char* path_to_file); -void open_file(FILE** file, char* path_to_file); +void parse_request_and_send_response(char* root, char* buffer, int newsockfd); +int file_found(char* path_to_file); +void respond_OK_and_send_file(char* full_path, int newsockfd); +void respond_NOTFOUND(int newsockfd); +void get_mime_type(char* path, char* mime); +void make_response_header(char* response, char* full_path, size_t size); +size_t get_size(int fd); #endif \ No newline at end of file diff --git a/server.c b/server.c index a71fbd3..dc2e82a 100644 --- a/server.c +++ b/server.c @@ -4,11 +4,13 @@ #define FOUND_RESPONSE "HTTP/1.0 200 OK\r\n" /* add \n*/ #define NOT_FOUND_RESPONSE "HTTP/1.0 404\r\n\r\n" +#define FOUND 0 #define BUF 100000 #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> @@ -27,7 +29,7 @@ int main(int argc, char *argv[]) socklen_t clilen; int n; - if (argc < 2) { + if (argc < 2) { // change this fprintf(stderr,"ERROR, no port provided\n"); exit(1); } @@ -41,9 +43,7 @@ int main(int argc, char *argv[]) bzero((char *) &serv_addr, sizeof(serv_addr)); - portno = atoi(argv[1]); - /* Create address we're going to listen on (given port number) - converted to network byte order & any IP address for this machine */ @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); // store in machine-neutral format - /* Bind address to the socket */ + /* Bind address to the socket */ if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { perror("ERROR on binding"); exit(1); @@ -66,7 +66,6 @@ int main(int argc, char *argv[]) be accepted. Get back a new file descriptor to communicate on. */ newsockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen); - if (newsockfd < 0) { perror("ERROR on accept"); exit(1); @@ -77,38 +76,16 @@ int main(int argc, char *argv[]) then process */ n = read(newsockfd,buffer,BUF-1); - /* *************** using the get.c functionality here: */ + /* ******************************************************************************** */ + /* ******************************************************************************** */ + /* ******************************************************************************** */ char* root = argv[2]; // Extract just the file path from the request message into the char array 'path'. - const char* path_start = strstr(buffer, "GET") + 4; - const char* path_end = strstr(buffer, "HTTP")-1; - char path[path_end - path_start]; - strncpy(path, path_start, path_end - path_start); - path[sizeof(path)] = '\0'; // null terminator - char full_path[sizeof(path) + sizeof(root)]; - strcpy(full_path, root); - strcat(full_path, path); - strcpy(full_path, strchr(strchr(full_path, '/')+1, '/')+1); - printf("%s\n (_(_(_)_)_) \n", full_path); - if (find_file(full_path) == 0) { // 0 =found - - int fd = open(full_path, O_RDONLY); - struct stat st; - fstat(fd, &st); - size_t size = st.st_size; - - char response[256]; - sprintf(response, "%sContent-Length: %zu\r\n\r\n", FOUND_RESPONSE, size);// - printf("(%zu) Hellooo\n%s", size, response); - write(newsockfd, response, strlen(response)); - sendfile(newsockfd, fd, NULL, size); - } else{ - n = write(newsockfd, NOT_FOUND_RESPONSE, strlen(NOT_FOUND_RESPONSE)); - } + parse_request_and_send_response(root, buffer, newsockfd); - printf("Here is the message: %s\n",buffer); - printf("Here is the path calculated: %s + %s = %s\n", root, path, full_path); + // printf("Here is the message: %s\n",buffer); + // printf("Here is the path calculated: %s + %s = %s\n", root, path, full_path); if (n < 0) { perror("ERROR writing to socket"); -- GitLab