fix: Goodbye memory leaks, welcome to awesome error codes that work just well

This commit is contained in:
Gu://em_ 2025-11-28 15:44:33 +01:00
parent f16bdbdf73
commit eee5f940e3
13 changed files with 96 additions and 40 deletions

View file

@ -48,7 +48,7 @@ int start_daemon(void)
pid_t pid = fork();
if (!pid) // Daemon
{
start_server(config->servers->ip, config->servers->port);
start_server(config);
}
else // Parent
{

View file

@ -5,12 +5,15 @@
#include <string.h>
#include "../utils/parsing/words.h"
#include "../utils/string/string.h"
void destroy_headers(struct http_header *headers)
{
while (headers != NULL)
{
struct http_header *next = headers->next;
string_destroy(headers->field);
string_destroy(headers->value);
free(headers);
headers = next;
}

View file

@ -91,21 +91,19 @@ static void split_target(struct http_request *req)
}
}
// Finds a valid path based on the client input
static bool find_target(struct http_request *req)
// Finds a valid path based on the client input and returns the corresponding
// FILES return value (see files.h)
static int find_target(struct http_request *req)
{
// Check filename
if (!check_filename(req->target))
return false;
return ERR_FILES_FORBIDDEN;
char *target = string_to_charptr(req->target);
int err = is_directory(target);
free(target);
err = 0; // TODO fix that bug
if (err == -1) // Doesn't exists
return false;
else if (err == 1)
if (err == FILES_DIR) // Is a directory
{
// Append default file if directory
if (req->target->data[req->target->size - 1] != '/')
@ -117,11 +115,10 @@ static bool find_target(struct http_request *req)
target = string_to_charptr(req->target);
err = is_directory(target);
free(target);
return err == 0;
return err;
}
// Exists
return true;
return err;
}
// WARNING allocates result on the heap
@ -218,7 +215,7 @@ void handle_request(int client_fd, char *client_ip)
return;
char *method = get_http_method(req->method);
char *target = string_to_charptr(req->target);
log_request(method, target, client_ip);
print_log_request(method, target, client_ip);
free(method);
free(target);
@ -253,12 +250,15 @@ void handle_request(int client_fd, char *client_ip)
int fd = open(target, O_RDONLY);
if (fd > 0)
sendfile(client_fd, fd, 0, atoi(cl_str));
free(target);
free(cl_str);
}
// Log response
method = get_http_method(req->method);
target = string_to_charptr(req->target);
log_response(resp->status_code, method, target, client_ip);
print_log_response(resp->status_code, method, target, client_ip);
free(method);
free(target);
@ -314,12 +314,23 @@ struct http_response *generate_response(struct http_request *req)
// Status code
if (req->status_code == 0)
{
if (!find_target(req))
res->status_code = 404;
else
switch (find_target(req))
{
case FILES_REG:
res->status_code = 200;
break;
case ERR_FILES_NOT_FOUND:
res->status_code = 404;
break;
default:
res->status_code = 403;
break;
}
}
else
res->status_code = req->status_code;
// Check protocol and method
check_req(req, res);
// Headers
@ -339,8 +350,7 @@ struct http_response *generate_response(struct http_request *req)
}
else
{
res->status_code =
404; // TODO replace by 403 once find_target is fixed
res->status_code = 403;
}
}
append_header(&res->headers, create_header("Connection", "close"));

View file

@ -16,11 +16,11 @@ void errlog_init(bool enabled, int logfile_fd, struct server_config *serv_cfg);
*/
void print_err();
/* @brief Prints error logs, just like print_log(), and also to stderr
/* @brief Prints error logs, just like print_log() but for errors
*/
void print_log_err(char *format, ...);
/* @brief Prints error logs, just like print_log()
/* @brief Returns the string corresponding to the last error that happened
*/
char *get_err();

View file

@ -60,14 +60,20 @@ void print_log(char *format, ...)
dprintf(config.logfile_fd, "\n");
}
void log_request(char *request_type, char *target, char *client_ip)
void print_log_request(char *request_type, char *target, char *client_ip)
{
print_log("received %s, on '%s' from %s", request_type, target, client_ip);
}
void log_response(int status_code, char *request_type, char *target,
void print_log_response(int status_code, char *request_type, char *target,
char *client_ip)
{
print_log("responding with %d to %s for %s on '%s'", status_code, client_ip,
request_type, target);
}
void log_terminate(void)
{
if (config.logfile_fd != 0 && config.logfile_fd != STDOUT_FILENO)
close(config.logfile_fd);
}

View file

@ -35,7 +35,7 @@ void print_log(char *format, ...);
* @param target
* @param client_ip
*/
void log_request(char *request_type, char *target, char *client_ip);
void print_log_request(char *request_type, char *target, char *client_ip);
/* @brief Prints response logs with the adequate format in the logfile
*
@ -44,7 +44,11 @@ void log_request(char *request_type, char *target, char *client_ip);
* @param target
* @param client_ip
*/
void log_response(int status_code, char *request_type, char *target,
void print_log_response(int status_code, char *request_type, char *target,
char *client_ip);
/* @brief Gracefully exits the logs module
*/
void log_terminate(void);
#endif // ! LOGS_H

View file

@ -24,7 +24,7 @@ int main(int argc, char **argv)
switch (config->daemon)
{
case NO_OPTION:
start_server(config->servers->ip, config->servers->port);
start_server(config);
break;
case START:
@ -43,5 +43,6 @@ int main(int argc, char **argv)
return 2;
}
config_destroy(config);
return 0;
}

View file

@ -23,7 +23,8 @@
// === Static variables
int server_socket = 0;
static int server_socket = 0;
static struct config *config;
// === Static functions
@ -111,12 +112,13 @@ static void get_ip(struct sockaddr *client_addr, char *res)
static void signal_handler(int signal)
{
print_log("signal received: %d", signal);
print_log("EVENT Signal received: %d", signal);
switch (signal)
{
case SIGINT: {
print_log("Stopping server...");
print_log("STOPPING Stopping server...");
stop_server();
config_destroy(config);
exit(0);
}
default:
@ -126,8 +128,12 @@ static void signal_handler(int signal)
// === Functions
void start_server(const char *host, const char *port)
void start_server(struct config *cfg)
{
config = cfg;
const char *host = config->servers->ip;
const char *port = config->servers->port;
server_socket = get_socket(host, port);
if (server_socket == -1)
// TODO log that
@ -145,14 +151,16 @@ void start_server(const char *host, const char *port)
if (sigemptyset(&siga.sa_mask) < 0)
// TODO log that
return;
if (sigaction(SIGINT, &siga, NULL) == -1)
if (sigaction(SIGINT, &siga, NULL) == -1
|| sigaction(SIGPIPE, &siga, NULL) == -1)
return;
// Main loop
while (1)
{
struct sockaddr client_addr;
int client_fd = accept(server_socket, &client_addr, NULL);
socklen_t client_addr_len = sizeof(struct sockaddr);
int client_fd = accept(server_socket, &client_addr, &client_addr_len);
if (client_fd == -1)
continue;

View file

@ -1,7 +1,7 @@
#ifndef SERVER_H
#define SERVER_H
// #define _POSIX_C_SOURCE 200112L
#include "../config/config.h"
/* @brief Starts the HTTP server
*
@ -10,7 +10,7 @@
* @param hostname
* @param port
*/
void start_server(const char *host, const char *port);
void start_server(struct config *cfg);
/* @brief Stops the currently running HTTP server
*/

View file

@ -2,6 +2,7 @@
#include "files.h"
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
@ -13,10 +14,22 @@
int is_directory(const char *path)
{
struct stat path_stat;
if (lstat(path, &path_stat) != 0)
return S_ISDIR(path_stat.st_mode);
if (lstat(path, &path_stat) == 0)
{
if (S_ISDIR(path_stat.st_mode)) // Directory
return FILES_DIR;
else if (S_ISREG(path_stat.st_mode)) // Regular file
return FILES_REG;
else
return -1;
return FILES_OTHER;
}
else
{
if (errno == ENOENT) // File not found
return ERR_FILES_NOT_FOUND;
else // Other errors
return ERR_FILES_FORBIDDEN;
}
}
// TODO handle logging

View file

@ -5,6 +5,15 @@
#define BUFFER_SIZE 1024
// Return codes
#define FILES_REG 0
#define FILES_DIR 1
#define FILES_OTHER 8
// Errors
#define ERR_FILES_NOT_FOUND -1
#define ERR_FILES_FORBIDDEN -2
// === Includes
#include <stdbool.h>
@ -29,7 +38,8 @@
*
* @param path
*
* @return 1 if path is a directory, 0 if it is not and -1 if path is not valid
* @return Returns the corresponding return value / error code (see header
* definitions)
*/
int is_directory(const char *path);

View file

@ -114,6 +114,7 @@ void str_concat_string(const char *str, size_t size, struct string *to_concat)
memcpy(to_concat->data, str, size);
memcpy(to_concat->data + size, tmp, tmp_size);
free(tmp);
}
}