Add a ton of validation
parent
6f0d71a07b
commit
90e333a892
|
@ -87,9 +87,15 @@ int parse_request_line(const char *line, struct request_line *parsed_line) {
|
|||
* @param parsed_line The request_line made by parse_request_line
|
||||
*/
|
||||
void free_request_line_items(struct request_line *parsed_line) {
|
||||
free(parsed_line->http_version);
|
||||
free(parsed_line->method);
|
||||
free(parsed_line->uri);
|
||||
if (parsed_line->http_version != NULL) {
|
||||
free(parsed_line->http_version);
|
||||
}
|
||||
if (parsed_line->method != NULL) {
|
||||
free(parsed_line->method);
|
||||
}
|
||||
if (parsed_line->uri != NULL) {
|
||||
free(parsed_line->uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -168,20 +168,55 @@ static int send_file(int client_fd, struct requested_file file) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static enum request_parse_result parse_and_validate_request(struct http_message message, struct request_line *req_line) {
|
||||
int parse_result = parse_request_line(message.start_line, req_line);
|
||||
if (parse_result == -1) {
|
||||
return PARSE_RESULT_MALFORMED;
|
||||
} else if (strcmp(req_line->method, "GET") != 0) {
|
||||
return PARSE_RESULT_BAD_METHOD;
|
||||
} else if (strcmp(req_line->http_version, HTTP_VERSION) != 0) {
|
||||
return PARSE_RESULT_BAD_VERSION;
|
||||
}
|
||||
|
||||
return PARSE_RESULT_OK;
|
||||
}
|
||||
|
||||
enum socket_result serve_one_request(int sock_fd) {
|
||||
int client_fd = accept(sock_fd, NULL, NULL);
|
||||
if (client_fd == -1) {
|
||||
return RESULT_WRITE_ERROR;
|
||||
}
|
||||
struct http_message message = {};
|
||||
get_all_remote_parts(client_fd, TYPE_SERVER, &message);
|
||||
struct request_line parsed_request_line;
|
||||
int parse_result = parse_request_line(message.start_line, &parsed_request_line);
|
||||
if (parse_result == -1) {
|
||||
enum socket_result read_result = get_all_remote_parts(client_fd, TYPE_SERVER, &message);
|
||||
if (read_result == RESULT_MALFORMED) {
|
||||
send_headers(400, client_fd, -1);
|
||||
close(client_fd);
|
||||
return RESULT_MALFORMED;
|
||||
} else if (read_result != RESULT_OK){
|
||||
send_headers(500, client_fd, -1);
|
||||
close(client_fd);
|
||||
return RESULT_READ_ERROR;
|
||||
}
|
||||
struct request_line parsed_request_line = {};
|
||||
enum request_parse_result parse_result = parse_and_validate_request(message, &parsed_request_line);
|
||||
// Ensure our the request line's info is congruent with the server's expectations.
|
||||
if (parse_result != PARSE_RESULT_OK) {
|
||||
int status_code = 500;
|
||||
if (parse_result == PARSE_RESULT_MALFORMED) {
|
||||
status_code = 400;
|
||||
} else if (parse_result == PARSE_RESULT_BAD_METHOD) {
|
||||
status_code = 405;
|
||||
} else if (parse_result == PARSE_RESULT_BAD_VERSION) {
|
||||
status_code = 505;
|
||||
}
|
||||
send_headers(status_code, client_fd, -1);
|
||||
free_request_line_items(&parsed_request_line);
|
||||
free(message.start_line);
|
||||
free(message.contents);
|
||||
if (message.start_line != NULL) {
|
||||
free(message.start_line);
|
||||
}
|
||||
if (message.contents != NULL) {
|
||||
free(message.contents);
|
||||
}
|
||||
if (message.headers != NULL) {
|
||||
free_headers(message.headers);
|
||||
}
|
||||
|
@ -189,7 +224,8 @@ enum socket_result serve_one_request(int sock_fd) {
|
|||
close(client_fd);
|
||||
return RESULT_PROCESSING_ERROR;
|
||||
}
|
||||
struct requested_file file;
|
||||
// Attempt to read the file and return it.
|
||||
struct requested_file file = {};
|
||||
int file_result = get_file_from_url(parsed_request_line.uri, &file);
|
||||
if (file_result == -1) {
|
||||
int send_result = 0;
|
||||
|
@ -199,8 +235,12 @@ enum socket_result serve_one_request(int sock_fd) {
|
|||
send_result = send_headers(403, client_fd, -1);
|
||||
} else {
|
||||
free_request_line_items(&parsed_request_line);
|
||||
free(message.start_line);
|
||||
free(message.contents);
|
||||
if (message.start_line != NULL) {
|
||||
free(message.start_line);
|
||||
}
|
||||
if (message.contents != NULL) {
|
||||
free(message.contents);
|
||||
}
|
||||
if (message.headers != NULL) {
|
||||
free_headers(message.headers);
|
||||
}
|
||||
|
@ -212,8 +252,12 @@ enum socket_result serve_one_request(int sock_fd) {
|
|||
|
||||
if (send_result != 0) {
|
||||
free_request_line_items(&parsed_request_line);
|
||||
free(message.start_line);
|
||||
free(message.contents);
|
||||
if (message.start_line != NULL) {
|
||||
free(message.start_line);
|
||||
}
|
||||
if (message.contents != NULL) {
|
||||
free(message.contents);
|
||||
}
|
||||
if (message.headers != NULL) {
|
||||
free_headers(message.headers);
|
||||
}
|
||||
|
@ -226,8 +270,12 @@ enum socket_result serve_one_request(int sock_fd) {
|
|||
send_file(client_fd, file);
|
||||
}
|
||||
free_request_line_items(&parsed_request_line);
|
||||
free(message.start_line);
|
||||
free(message.contents);
|
||||
if (message.start_line != NULL) {
|
||||
free(message.start_line);
|
||||
}
|
||||
if (message.contents != NULL) {
|
||||
free(message.contents);
|
||||
}
|
||||
if (message.headers != NULL) {
|
||||
free_headers(message.headers);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define FILE_BUFFER_SIZE 1024
|
||||
|
||||
enum server_status {STATUS_LISTENING, STATUS_CLOSED, STATUS_ERROR};
|
||||
enum request_parse_result {PARSE_RESULT_OK, PARSE_RESULT_MALFORMED, PARSE_RESULT_BAD_METHOD, PARSE_RESULT_BAD_VERSION};
|
||||
struct server_info {
|
||||
int sock_fd;
|
||||
enum server_status status;
|
||||
|
|
Loading…
Reference in New Issue