Add a ton of validation

master
Nick Krichevsky 2018-09-09 23:25:10 -04:00
parent 6f0d71a07b
commit 90e333a892
3 changed files with 71 additions and 16 deletions

View File

@ -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);
}
}
/**

View File

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

View File

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