improve error handling

This commit is contained in:
2025-08-02 00:28:24 +02:00
parent c7ad5d7874
commit fa964b2620
6 changed files with 42 additions and 111 deletions

View File

@@ -22,6 +22,7 @@ cws_http *cws_http_parse(char *request_str, int sockfd, cws_config *config) {
char *request_str_cpy = strdup(request_str);
if (!request_str_cpy) {
free(request);
return NULL;
}
@@ -37,13 +38,16 @@ cws_http *cws_http_parse(char *request_str, int sockfd, cws_config *config) {
return NULL;
}
CWS_LOG_DEBUG("method: %s", pch);
int ret = cws_http_parse_method(request, pch);
if (ret < 0) {
/* Not implemented */
cws_http_free(request);
free(request_str_cpy);
cws_http_send_error_page(request, CWS_HTTP_NOT_IMPLEMENTED, "501 Not Implemented", "501 Not Implemented");
cws_http_send_response(request, CWS_HTTP_NOT_IMPLEMENTED);
return NULL;
}
/* Parse location */
@@ -61,6 +65,10 @@ cws_http *cws_http_parse(char *request_str, int sockfd, cws_config *config) {
if (strcmp(request->location, "/") == 0) {
snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s/index.html", config->www);
} else {
size_t location_path_len = strlen(request->location);
if (location_path_len > CWS_HTTP_LOCATION_PATH_LEN) {
request->location[location_path_len - 1] = '\0';
}
snprintf(request->location_path, CWS_HTTP_LOCATION_PATH_LEN, "%s%s", config->www, request->location);
}
CWS_LOG_DEBUG("location path: %s", request->location_path);
@@ -155,7 +163,7 @@ size_t cws_http_response_builder(char **response, char *http_version, cws_http_s
size_t total_len = header_len + body_len_bytes;
*response = (char *)malloc(total_len);
*response = malloc(total_len);
if (*response == NULL) {
return 0;
}
@@ -173,11 +181,11 @@ void cws_http_send_response(cws_http *request, cws_http_status status) {
case CWS_HTTP_OK:
break;
case CWS_HTTP_NOT_FOUND: {
cws_http_send_error_page(request, CWS_HTTP_NOT_FOUND, "404 Not Found", "Resource not found, 404.");
cws_http_send_simple_html(request, CWS_HTTP_NOT_FOUND, "404 Not Found", "Resource not found, 404.");
break;
}
case CWS_HTTP_NOT_IMPLEMENTED: {
cws_http_send_error_page(request, CWS_HTTP_NOT_IMPLEMENTED, "501 Not Implemented", "Method not implemented, 501.");
cws_http_send_simple_html(request, CWS_HTTP_NOT_IMPLEMENTED, "501 Not Implemented", "Method not implemented, 501.");
break;
}
}
@@ -192,7 +200,10 @@ void cws_http_send_resource(cws_http *request) {
/* Retrieve correct Content-Type */
char content_type[1024];
cws_http_get_content_type(request, content_type);
int ret = cws_http_get_content_type(request, content_type);
if (ret < 0) {
cws_http_send_response(request, CWS_HTTP_NOT_FOUND);
}
/* Retrieve file size */
fseek(file, 0, SEEK_END);
@@ -213,13 +224,18 @@ void cws_http_send_resource(cws_http *request) {
if (read_bytes != content_length) {
free(file_data);
CWS_LOG_ERROR("Partial read from file.");
CWS_LOG_ERROR("Partial read from file");
return;
}
char conn[32] = "close";
mcl_bucket *connection = mcl_hm_get(request->headers, "Connection");
if (connection) {
strncpy(conn, (char *)connection->value, sizeof(conn));
}
char *response = NULL;
size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", CWS_HTTP_OK, content_type, "close", file_data, content_length);
CWS_LOG_DEBUG("%s", response);
size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", CWS_HTTP_OK, content_type, conn, file_data, content_length);
size_t bytes_sent = 0;
do {
@@ -231,15 +247,14 @@ void cws_http_send_resource(cws_http *request) {
free(file_data);
}
void cws_http_get_content_type(cws_http *request, char *content_type) {
int cws_http_get_content_type(cws_http *request, char *content_type) {
char *ptr = strrchr(request->location_path, '.');
if (ptr == NULL) {
cws_http_send_error_page(request, CWS_HTTP_NOT_FOUND, "404 Not Found", "404 Not Found.");
return;
return -1;
}
ptr += 1;
char ct[32];
char ct[32] = {0};
/* TODO: Improve content_type (used to test) */
if (strcmp(ptr, "html") == 0 || strcmp(ptr, "css") == 0 || strcmp(ptr, "javascript") == 0) {
@@ -251,9 +266,11 @@ void cws_http_get_content_type(cws_http *request, char *content_type) {
}
snprintf(content_type, 1024, "%s/%s", ct, ptr);
return 0;
}
void cws_http_send_error_page(cws_http *request, cws_http_status status, char *title, char *description) {
void cws_http_send_simple_html(cws_http *request, cws_http_status status, char *title, char *description) {
char body[512];
memset(body, 0, sizeof(body));
@@ -269,8 +286,14 @@ void cws_http_send_error_page(cws_http *request, cws_http_status status, char *t
title, description);
size_t body_len = strlen(body) * sizeof(char);
char conn[32] = "close";
mcl_bucket *connection = mcl_hm_get(request->headers, "Connection");
if (connection) {
strncpy(conn, (char *)connection->value, sizeof(conn));
}
char *response = NULL;
size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", status, "text/html", "close", body, body_len);
size_t response_len = cws_http_response_builder(&response, "HTTP/1.1", status, "text/html", conn, body, body_len);
send(request->sockfd, response, response_len, 0);
free(response);
}