diff --git a/CMakeLists.txt b/CMakeLists.txt index 52edc57..9752af9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,17 +6,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_COMPILER_LAUNCHER ccache) -# options for spdlog -set(SPDLOG_ENABLE_PCH ON CACHE BOOL "Build static or shared library using precompiled header to speed up compilation time") -set(SPDLOG_BUILD_WARNINGS ON CACHE BOOL "Enable compiler warnings") -set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "Use external fmt library instead of bundled") -set(SPDLOG_PREVENT_CHILD_FD ON CACHE BOOL "Prevent from child processes to inherit log file descriptors") -set(SPDLOG_NO_THREAD_ID ON CACHE BOOL "prevent spdlog from querying the thread id on each log call if thread id is not needed") -set(SPDLOG_NO_TLS ON CACHE BOOL "prevent spdlog from using thread local storage") - -add_subdirectory(external/spdlog) -# end - find_package(Boost REQUIRED COMPONENTS system) find_package(OpenSSL REQUIRED) find_package(OpenMP REQUIRED) @@ -42,11 +31,12 @@ set(COMPILE_FLAGS -Wmove -Wopenmp -funroll-loops - -flto=thin -fwhole-program-vtables + -flto=thin + -fwhole-program-vtables -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free ) set(LINKER_OPTIONS - PRIVATE -Wl,--sort-common,--as-needed + -Wl,--sort-common,--as-needed -stdlib=libc++ -flto=thin -fwhole-program-vtables @@ -70,11 +60,26 @@ set(FILES include/cache_files.hpp src/simdjson.cpp include/simdjson.h - ) + include/configuration.hpp src/configuration.cpp) + +# options for spdlog +set(SPDLOG_ENABLE_PCH ON CACHE BOOL "Build static or shared library using precompiled header to speed up compilation time") +set(SPDLOG_BUILD_WARNINGS ON CACHE BOOL "Enable compiler warnings") +set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "Use external fmt library instead of bundled") +set(SPDLOG_PREVENT_CHILD_FD ON CACHE BOOL "Prevent from child processes to inherit log file descriptors") +set(SPDLOG_NO_THREAD_ID ON CACHE BOOL "prevent spdlog from querying the thread id on each log call if thread id is not needed") +set(SPDLOG_NO_TLS ON CACHE BOOL "prevent spdlog from using thread local storage") +set(SPDLOG_NO_ATOMIC_LEVELS ON CACHE BOOL "prevent spdlog from using of std::atomic log levels (use only if your code never modifies log levels concurrently") + +add_subdirectory(external/spdlog EXCLUDE_FROM_ALL) +target_compile_definitions(spdlog PRIVATE ${COMPILE_DEFINITIONS}) +target_compile_options(spdlog PRIVATE ${COMPILE_FLAGS}) +target_link_options(spdlog PRIVATE ${LINKER_OPTIONS}) +# end add_executable(GeminiServer ${FILES}) target_precompile_headers(GeminiServer PRIVATE ${HEADERS}) target_compile_definitions(GeminiServer PRIVATE ${COMPILE_DEFINITIONS}) target_compile_options(GeminiServer PRIVATE ${COMPILE_FLAGS}) -target_link_options(GeminiServer ${LINKER_OPTIONS}) -target_link_libraries(GeminiServer ${LINKER_FLAGS} spdlog::spdlog) \ No newline at end of file +target_link_options(GeminiServer PRIVATE ${LINKER_OPTIONS}) +target_link_libraries(GeminiServer ${LINKER_FLAGS} spdlog) \ No newline at end of file diff --git a/README.md b/README.md index 9e15a25..032230f 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,46 @@ # A C++ Gemini server + ## Introduction -As I saw other implementations in Rust but no C++ to compete, I felt that I had to do something ;-). -It is also a chance for me and a friend (Brumaire) to practice C++ and to try to get as much performance as possible (my speciality is HPC so… Yeah). + +As I saw other implementations in Rust but no C++ to compete, I felt that I had to do something ;-). It is also a chance for me and a friend ( +Brumaire) to practice C++ and to try to get as much performance as possible (my speciality is HPC so… Yeah). ## Design + I use PlantUML to do the class diagram for the design. It's a work in progress. ## Goal + What we want is a high performance server using asynchrony at first, and then maybe multi-threading to have the maximum possible performance. ## Configuration + **WIP** -The configuration of the server is made through a JSON file `config.json`. The JSON parser is [simdjson](https://github.com/simdjson/simdjson) directly integrated -in our source code. +The configuration of the server is made through a JSON file `config.json`. The JSON parser is [simdjson](https://github.com/simdjson/simdjson) +directly integrated in our source code. ### Structure of the file + - content - - path : string, folder to the content of your site. + - path : string, folder to the content of your site. - cache - - enable_cache: bool, to enable cache of files or not - - cache_size : unsigned int, the maximum size in bytes to put in cache + - enable_cache: bool, to enable cache of files or not + - cache_size : unsigned int, the maximum size in bytes to put in cache - ssl - - pem_path : string - - cert_path : string + - pem_path : string + - cert_path : string ## Dependencies -It uses a bundled version of `spdlog` as a git submodule, but it does not use the `fmt` lib that is inside `spdlog`. + +It uses a bundled version of `spdlog` as a git submodule, but it does not use the `fmt` lib that is inside `spdlog` (you can still change it in the +CMakeLists). ## Documentation + The doc of the code is made with [doxygen](https://www.doxygen.nl/), the `Doxyfile` is at the root of the repo. ## TODO/features + * Possibility of an applicative gateway (like CGI for example) * Content in RAM cache * Asynchronous (boost ASIO deals with it) \ No newline at end of file diff --git a/include/configuration.hpp b/include/configuration.hpp new file mode 100644 index 0000000..4f8ba63 --- /dev/null +++ b/include/configuration.hpp @@ -0,0 +1,47 @@ +#ifndef GEMINISERVER_CONFIGURATION_HPP +#define GEMINISERVER_CONFIGURATION_HPP + +#include "simdjson.h" +#include +#include + + +namespace gemini { + struct Information; + + class CacheFiles; + + using namespace std::literals::string_literals; + + /** + * \class Configuration + * \brief This class is used to configurate the whole server and different classes. + * + * The configuration is made through a JSON file structured like this : + * + * { + * "content" : folder_to_content, + * "cache" : { + * "enable_cache" : bool, + * "cache_size" : int + * }, + * "ssl" : { + * "pem_path" : string, + * "cert_path" : string + * } + * } + */ + class Configuration { + private: + const std::string filename{ "config.json"s }; + + public: + Configuration() = default; + + explicit Configuration(const std::string &filename) : filename(filename) {} + + std::pair> create_infos() const; + }; +} + +#endif //GEMINISERVER_CONFIGURATION_HPP diff --git a/include/information.hpp b/include/information.hpp index 9afee52..370635a 100644 --- a/include/information.hpp +++ b/include/information.hpp @@ -6,7 +6,15 @@ namespace gemini { * \brief This struct is used to store information inside, used by any other class/struct. */ struct Information { + const bool enable_cache{ false }; + const std::size_t cache_size{ 0 }; + const std::string ssl_pem_path{}; + const std::string ssl_cert_path{}; + Information() = default; + + Information(const bool enableCache, const size_t cacheSize, std::string sslPemPath, std::string sslCertPath) : + enable_cache(enableCache), cache_size(cacheSize), ssl_pem_path(std::move(sslPemPath)), ssl_cert_path(std::move(sslCertPath)) {} }; } diff --git a/main.cpp b/main.cpp index ec3351e..eb96b4a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,11 @@ #include +#include +#include int main() { + // Create logger + auto logger = spdlog::stdout_color_st("single_log"); + spdlog::set_default_logger(logger); std::cout << "Hello, World!" << std::endl; return EXIT_SUCCESS; } diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..dbc552f --- /dev/null +++ b/src/configuration.cpp @@ -0,0 +1,15 @@ +#include "../include/configuration.hpp" +#include "../include/information.hpp" +#include "../include/cache_files.hpp" + +std::pair> gemini::Configuration::create_infos() const { + simdjson::dom::parser parser; + const auto config = parser.load(filename); + const Information infos{ + config["cache"]["enable_cache"].get_bool(), + config["cache"]["cache_size"].get_uint64(), + config["ssl"]["pem_path"].get_c_str().value(), + config["ssl"]["cert_path"].get_c_str().value() }; + return std::make_pair(infos, + infos.enable_cache ? std::optional(CacheFiles(config["content"]["path"].get_c_str().value(), infos)) : std::nullopt); +}