From 4c7a15672349264360ad49989e95bec679d5283e Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Fri, 29 Aug 2025 17:46:58 +0700 Subject: [PATCH] added config and tls --- Makefile | 2 +- config.json | 9 +++ src/ConfigManager.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ src/ConfigManager.h | 39 ++++++++++ src/config.c | 7 ++ src/config.h | 7 ++ src/database.c | 3 +- src/main.c | 33 ++++++--- src/static.c | 7 ++ src/static.h | 5 ++ 10 files changed, 274 insertions(+), 10 deletions(-) create mode 100644 config.json create mode 100644 src/ConfigManager.c create mode 100644 src/ConfigManager.h create mode 100644 src/config.c create mode 100644 src/config.h create mode 100644 src/static.c create mode 100644 src/static.h diff --git a/Makefile b/Makefile index 13af952..86b2eaa 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -Wall -g -std=gnu2x +CFLAGS = -Wall -g -std=gnu2x -DMG_TLS=MG_TLS_BUILTIN LDFLAGS = LIBS = -lpthread -lcrypto -lsqlite3 INCLUDES = -I./src/lib -I./src diff --git a/config.json b/config.json new file mode 100644 index 0000000..0e30634 --- /dev/null +++ b/config.json @@ -0,0 +1,9 @@ +{ + "database": "users.db", + "address": "localhost:8222", + "default_users_file": "users.json", + "web": "./web", + "tls_enabled": true, + "tls_cert": "/home/tola/certs/localhost/localhost.crt", + "tls_key": "/home/tola/certs/localhost/localhost.key" +} \ No newline at end of file diff --git a/src/ConfigManager.c b/src/ConfigManager.c new file mode 100644 index 0000000..b968fea --- /dev/null +++ b/src/ConfigManager.c @@ -0,0 +1,172 @@ +#include "ConfigManager.h" +#include +#include +#include +#include +#include +#include "file.h" + +typedef struct ConfigManager { + cJSON *config; + pthread_mutex_t config_file_mutex; + char *config_file_name; +} ConfigManager; + +ConfigManager *cm_new_config() { + ConfigManager *newcm = malloc(sizeof(ConfigManager)); + newcm->config_file_name = nullptr; + newcm->config = nullptr; + return newcm; +} + +ConfigManager *cm_new_config_from_file(const char *filename) { + ConfigManager *newcm = malloc(sizeof(ConfigManager)); + newcm->config_file_name = strdup(filename); + pthread_mutex_lock(&(newcm->config_file_mutex)); + char *config_file_content = read_file(newcm->config_file_name); + newcm->config = cJSON_Parse(config_file_content); + pthread_mutex_unlock(&(newcm->config_file_mutex)); + return newcm; +} + +ConfigManager *cm_new_config_from_object(cJSON *config) { + ConfigManager *newcm = malloc(sizeof(ConfigManager)); + newcm->config = config; + newcm->config_file_name = nullptr; + return newcm; +} + +void cm_set_config_from_file(ConfigManager *cm, const char *filename) { + cm->config_file_name = strdup(filename); + pthread_mutex_lock(&(cm->config_file_mutex)); + char *config_file_content = read_file(cm->config_file_name); + cm->config = cJSON_Parse(config_file_content); + pthread_mutex_unlock(&(cm->config_file_mutex)); +} + +void cm_set_config_from_object(ConfigManager *cm, cJSON *config) { + cm->config = config; +} + +void cm_delete_config(ConfigManager *cm) { + if (!cm) { + return; + } + if (cm->config) { + cJSON_Delete(cm->config); + } + if (cm->config_file_name) { + free(cm->config_file_name); + } + free(cm); +} + +void cm_print_config(const ConfigManager *cm) { + printf("Config: %s\n", cJSON_Print(cm->config)); +} + +char *cm_get_config_filename(ConfigManager *cm) { + return strdup(cm->config_file_name); +} + +cJSON *cm_get_config(ConfigManager *cm) { + return cJSON_Duplicate(cm->config, (cJSON_bool) true); +} + +char *cm_get_parameter_as_string(ConfigManager *cm, const char *param_name) { + cJSON *param = cJSON_GetObjectItem(cm->config, param_name); + if (!param) return nullptr; + char *param_value = strdup(param->valuestring); + return param_value; +} + +int cm_get_parameter_as_int(ConfigManager *cm, const char *param_name) { + cJSON *param = cJSON_GetObjectItem(cm->config, param_name); + return param->valueint; +} +double cm_get_parameter_as_double(ConfigManager *cm, const char *param_name) { + cJSON *param = cJSON_GetObjectItem(cm->config, param_name); + return param->valuedouble; +} +float cm_get_parameter_as_float(ConfigManager *cm, const char *param_name) { + cJSON *param = cJSON_GetObjectItem(cm->config, param_name); + return param->valuedouble; +} +bool cm_get_parameter_as_bool(ConfigManager *cm, const char *param_name) { + cJSON *param = cJSON_GetObjectItem(cm->config, param_name); + if (!param) return false; + return param->valueint; +} + +void cm_set_string_parameter(ConfigManager *cm, const char *name, + const char *value) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddStringToObject(cm->config, name, value); + return; + } + cJSON_SetValuestring(param, value); +} +void cm_set_int_parameter(ConfigManager *cm, const char *name, + const int value) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddNumberToObject(cm->config, name, value); + return; + } + cJSON_SetIntValue(param, value); +} +void cm_set_double_parameter(ConfigManager *cm, const char *name, + const double value) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddNumberToObject(cm->config, name, value); + return; + } + cJSON_SetNumberValue(param, value); +} +void cm_set_float_parameter(ConfigManager *cm, const char *name, + const float value) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddNumberToObject(cm->config, name, value); + return; + } + cJSON_SetNumberValue(param, value); +} +void cm_set_bool_parameter(ConfigManager *cm, const char *name, + const bool value) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddBoolToObject(cm->config, name, value); + return; + } + cJSON_SetBoolValue(param, value); +} +void cm_set_null_parameter(ConfigManager *cm, const char *name) { + cJSON *param = cJSON_GetObjectItem(cm->config, name); + if (!param) { + cJSON_AddNullToObject(cm->config, name); + return; + } + cJSON_ReplaceItemInObject(cm->config, name, cJSON_CreateNull()); +} + +void cm_save_config(ConfigManager *cm) { + pthread_mutex_lock(&(cm->config_file_mutex)); + FILE *configfile = fopen(cm->config_file_name, "w+"); + char *configvalue = cJSON_Print(cm->config); + fprintf(configfile, configvalue); + fclose(configfile); + free(configvalue); + pthread_mutex_unlock(&(cm->config_file_mutex)); +} +void cm_save_config_to_file(ConfigManager *cm, const char *filename) { + pthread_mutex_lock(&(cm->config_file_mutex)); + FILE *configfile = fopen(filename, "w+"); + char *configvalue = cJSON_Print(cm->config); + fprintf(configfile, configvalue); + fclose(configfile); + free(configvalue); + pthread_mutex_unlock(&(cm->config_file_mutex)); +} \ No newline at end of file diff --git a/src/ConfigManager.h b/src/ConfigManager.h new file mode 100644 index 0000000..bec4dde --- /dev/null +++ b/src/ConfigManager.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +typedef struct ConfigManager ConfigManager; + +ConfigManager *cm_new_config(); +ConfigManager *cm_new_config_from_file(const char *filename); +ConfigManager *cm_new_config_from_object(cJSON *config); + +void cm_set_config_from_file(ConfigManager *cm, const char *filename); +void cm_set_config_from_object(ConfigManager *cm, cJSON *config); + +void cm_set_string_parameter(ConfigManager *cm, const char *name, + const char *value); +void cm_set_int_parameter(ConfigManager *cm, const char *name, const int value); +void cm_set_double_parameter(ConfigManager *cm, const char *name, + const double value); +void cm_set_float_parameter(ConfigManager *cm, const char *name, + const float value); +void cm_set_bool_parameter(ConfigManager *cm, const char *name, + const bool value); +void cm_set_null_parameter(ConfigManager *cm, const char *name); + +void cm_print_config(const ConfigManager *cm); + +void cm_delete_config(ConfigManager *cm); + +char *cm_get_config_filename(ConfigManager *cm); +cJSON *cm_get_config(ConfigManager *cm); + +char *cm_get_parameter_as_string(ConfigManager *cm, const char *param_name); +int cm_get_parameter_as_int(ConfigManager *cm, const char *param_name); +double cm_get_parameter_as_double(ConfigManager *cm, const char *param_name); +float cm_get_parameter_as_float(ConfigManager *cm, const char *param_name); +bool cm_get_parameter_as_bool(ConfigManager *cm, const char *param_name); + +void cm_save_config(ConfigManager *cm); +void cm_save_config_to_file(ConfigManager *cm, const char *filename); \ No newline at end of file diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..20e196a --- /dev/null +++ b/src/config.c @@ -0,0 +1,7 @@ +#include "config.h" + +ConfigManager *config = nullptr; + +void init_config(const char *filename) { + config = cm_new_config_from_file(filename); +} \ No newline at end of file diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..75d4d78 --- /dev/null +++ b/src/config.h @@ -0,0 +1,7 @@ +#pragma once + +#include "ConfigManager.h" + +extern ConfigManager *config; + +void init_config(const char *filename); \ No newline at end of file diff --git a/src/database.c b/src/database.c index baaf430..17c7aa4 100644 --- a/src/database.c +++ b/src/database.c @@ -3,12 +3,13 @@ #include #include "sql.h" #include +#include "config.h" sqlite3* db = nullptr; pthread_mutex_t db_mutex = PTHREAD_MUTEX_INITIALIZER; void init_db() { - if (sqlite3_open("users.db", &db) != SQLITE_OK) { + if (sqlite3_open(cm_get_parameter_as_string(config, "database"), &db) != SQLITE_OK) { fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); diff --git a/src/main.c b/src/main.c index 8a5219e..11498d0 100644 --- a/src/main.c +++ b/src/main.c @@ -1,15 +1,13 @@ #include #include #include +#include "config.h" #include "cors.h" #include "database.h" #include "route.h" +#include "static.h" #include "user.h" - -static void root_handler(struct mg_connection *c, struct mg_http_message *hm) { - struct mg_http_serve_opts opts = {.root_dir = "./web/"}; - mg_http_serve_dir(c, hm, &opts); -} +#include "file.h" static const struct route routes[] = { {"GET", "/#", root_handler}, @@ -26,6 +24,17 @@ static const struct route routes[] = { {nullptr, nullptr, nullptr}}; void ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_ERROR) { + // Обработка ошибок соединения + MG_LOG(MG_LL_ERROR, ("Ошибка соединения: %s", (char *) ev_data)); + } + if (ev == MG_EV_ACCEPT && c->is_tls) { + struct mg_tls_opts opts; + memset(&opts, 0, sizeof(opts)); + opts.cert = mg_str(read_file("/home/tola/certs/localhost/cert.pem")); + opts.key = mg_str(read_file("/home/tola/certs/localhost/key.pem")); + mg_tls_init(c, &opts); + } if (ev == MG_EV_HTTP_MSG) { const auto hm = (struct mg_http_message *) ev_data; bool route_found = false; @@ -48,16 +57,24 @@ void ev_handler(struct mg_connection *c, int ev, void *ev_data) { } int main(void) { + init_config("config.json"); init_db(); migrate_db(); - db_get_users_from_file("users.json"); + const char *default_users_filename = + cm_get_parameter_as_string(config, "default_users_file"); + if (default_users_filename) db_get_users_from_file("users.json"); struct mg_mgr mgr; mg_log_set(MG_LL_DEBUG); mg_mgr_init(&mgr); - mg_http_listen(&mgr, "http://0.0.0.0:8222", ev_handler, nullptr); - while (true) { + const char *address = cm_get_parameter_as_string(config, "address"); + // address ? mg_http_listen(&mgr, cm_get_parameter_as_string(config, "address"), + // ev_handler, nullptr) + // : mg_http_listen(&mgr, "http://0.0.0.0:8222", ev_handler, nullptr); + mg_http_listen(&mgr, "https://0.0.0.0:8222", ev_handler, nullptr); + for (;;) { mg_mgr_poll(&mgr, 1000); } + mg_mgr_free(&mgr); return 0; } diff --git a/src/static.c b/src/static.c new file mode 100644 index 0000000..af5bb1c --- /dev/null +++ b/src/static.c @@ -0,0 +1,7 @@ +#include "static.h" +#include "config.h" + +void root_handler(struct mg_connection *c, struct mg_http_message *hm) { + struct mg_http_serve_opts opts = {.root_dir = cm_get_parameter_as_string(config, "web")}; + mg_http_serve_dir(c, hm, &opts); +} \ No newline at end of file diff --git a/src/static.h b/src/static.h new file mode 100644 index 0000000..47fea0d --- /dev/null +++ b/src/static.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +void root_handler(struct mg_connection *c, struct mg_http_message *hm); \ No newline at end of file