diff --git a/server/socket_server.c b/server/socket_server.c index 26f0e56..d3e33ff 100644 --- a/server/socket_server.c +++ b/server/socket_server.c @@ -84,7 +84,7 @@ struct server_info setup(int port) { * * @return -1 on error, 0 otherwise. */ -static int send_headers(int status_code, int client_socket, int content_length) { +static int send_headers(int status_code, int client_socket, long content_length) { const char *status_code_message = get_message_from_status_code(status_code); if (status_code_message == NULL) { return -1; @@ -107,7 +107,7 @@ static int send_headers(int status_code, int client_socket, int content_length) // Get the number of chars in the port int content_length_length = floor(log10(content_length)) + 1; char *content_length_string = malloc((content_length_length + 1) * sizeof(char)); - sprintf(content_length_string, "%d", content_length); + sprintf(content_length_string, "%ld", content_length); const char *content_length_header_components[] = {HEADER_CONTENT_LENGTH, ": ", content_length_string, "\r\n"}; int content_length_header_length = get_buffer_size(content_length_header_components, 4); header_buffer_size += content_length_header_length; @@ -140,6 +140,29 @@ static int send_headers(int status_code, int client_socket, int content_length) return 0; } +/** + * Send a file over the socket. + * + * @param client_fd The file descriptor to send on. + * @param file The file to read + * + * @return -1 on error, 0 on success. + */ +static int send_file(int client_fd, struct requested_file file) { + char *buffer = malloc(FILE_BUFFER_SIZE * sizeof(char)); + while (fgets(buffer, FILE_BUFFER_SIZE, file.file) != NULL) { + int bytes_read = strlen(buffer); + int send_result = send(client_fd, buffer, bytes_read, 0); + if (send_result == -1) { + free(buffer); + return -1; + } + } + free(buffer); + + return 0; +} + enum socket_result serve_one_request(int sock_fd) { int client_fd = accept(sock_fd, NULL, NULL); if (client_fd == -1) { @@ -147,9 +170,39 @@ enum socket_result serve_one_request(int sock_fd) { } struct http_message message = {}; get_all_remote_parts(client_fd, TYPE_SERVER, &message); - printf("%s\n", message.contents); - char *msg = "HTTP/1.1 501 Not Imlemented Yet ;p\r\n\r\n"; - send(client_fd, msg, strlen(msg), 0); + struct request_line parsed_request_line; + int parse_result = parse_request_line(message.start_line, &parsed_request_line); + if (parse_result == -1) { + send_headers(400, client_fd, -1); + shutdown(client_fd, SHUT_RDWR); + close(client_fd); + return RESULT_PROCESSING_ERROR; + } + struct requested_file file; + int file_result = get_file_from_url(parsed_request_line.uri, &file); + if (file_result == -1) { + int send_result = 0; + if (errno == ENOENT) { + send_result = send_headers(404, client_fd, -1); + } else if (errno == EACCES) { + send_result = send_headers(403, client_fd, -1); + } else { + send_headers(500, client_fd, -1); + shutdown(client_fd, SHUT_RDWR); + close(client_fd); + return RESULT_PROCESSING_ERROR; + } + + if (send_result != 0) { + shutdown(client_fd, SHUT_RDWR); + close(client_fd); + return RESULT_WRITE_ERROR; + } + } else { + send_headers(200, client_fd, file.size); + send_file(client_fd, file); + } + shutdown(client_fd, SHUT_RDWR); close(client_fd); return RESULT_OK; diff --git a/server/socket_server.h b/server/socket_server.h index b88a2d9..1ef050c 100644 --- a/server/socket_server.h +++ b/server/socket_server.h @@ -5,6 +5,7 @@ #define BACKLOG_SIZE 8; #define HTTP_VERSION "HTTP/1.1" +#define FILE_BUFFER_SIZE 1024 enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR}; struct server_info {