Send files on request

master
Nick Krichevsky 2018-09-09 19:46:31 -04:00
parent ca7c7e9557
commit 0a7300402e
2 changed files with 59 additions and 5 deletions

View File

@ -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;

View File

@ -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 {