Send files on request
This commit is contained in:
parent
ca7c7e9557
commit
0a7300402e
|
@ -84,7 +84,7 @@ struct server_info setup(int port) {
|
||||||
*
|
*
|
||||||
* @return -1 on error, 0 otherwise.
|
* @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);
|
const char *status_code_message = get_message_from_status_code(status_code);
|
||||||
if (status_code_message == NULL) {
|
if (status_code_message == NULL) {
|
||||||
return -1;
|
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
|
// Get the number of chars in the port
|
||||||
int content_length_length = floor(log10(content_length)) + 1;
|
int content_length_length = floor(log10(content_length)) + 1;
|
||||||
char *content_length_string = malloc((content_length_length + 1) * sizeof(char));
|
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"};
|
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);
|
int content_length_header_length = get_buffer_size(content_length_header_components, 4);
|
||||||
header_buffer_size += content_length_header_length;
|
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;
|
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) {
|
enum socket_result serve_one_request(int sock_fd) {
|
||||||
int client_fd = accept(sock_fd, NULL, NULL);
|
int client_fd = accept(sock_fd, NULL, NULL);
|
||||||
if (client_fd == -1) {
|
if (client_fd == -1) {
|
||||||
|
@ -147,9 +170,39 @@ enum socket_result serve_one_request(int sock_fd) {
|
||||||
}
|
}
|
||||||
struct http_message message = {};
|
struct http_message message = {};
|
||||||
get_all_remote_parts(client_fd, TYPE_SERVER, &message);
|
get_all_remote_parts(client_fd, TYPE_SERVER, &message);
|
||||||
printf("%s\n", message.contents);
|
struct request_line parsed_request_line;
|
||||||
char *msg = "HTTP/1.1 501 Not Imlemented Yet ;p\r\n\r\n";
|
int parse_result = parse_request_line(message.start_line, &parsed_request_line);
|
||||||
send(client_fd, msg, strlen(msg), 0);
|
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);
|
shutdown(client_fd, SHUT_RDWR);
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#define BACKLOG_SIZE 8;
|
#define BACKLOG_SIZE 8;
|
||||||
#define HTTP_VERSION "HTTP/1.1"
|
#define HTTP_VERSION "HTTP/1.1"
|
||||||
|
#define FILE_BUFFER_SIZE 1024
|
||||||
|
|
||||||
enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR};
|
enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR};
|
||||||
struct server_info {
|
struct server_info {
|
||||||
|
|
Loading…
Reference in a new issue