From d18d93da08e8800c3568113e8c1cce9ae0a7a496 Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:56:39 +0300 Subject: [PATCH 1/6] move socket includes to subfolder --- libs/includes/Server.h | 2 +- libs/includes/{ => Socket}/ISocket.h | 0 libs/includes/{ => Socket}/PosixSocket.h | 0 libs/includes/{ => Socket}/WindowsSocket.h | 0 libs/includes/SocketFactory.h | 6 +++--- libs/sources/Server.cpp | 6 +++--- libs/sources/{ => Socket}/PosixSocket.cpp | 2 +- libs/sources/{ => Socket}/WindowsSocket.cpp | 2 +- libs/sources/SocketFactory.cpp | 10 +++++----- tests/server_tests.cpp | 2 +- tests/socket_tests.cpp | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) rename libs/includes/{ => Socket}/ISocket.h (100%) rename libs/includes/{ => Socket}/PosixSocket.h (100%) rename libs/includes/{ => Socket}/WindowsSocket.h (100%) rename libs/sources/{ => Socket}/PosixSocket.cpp (98%) rename libs/sources/{ => Socket}/WindowsSocket.cpp (99%) diff --git a/libs/includes/Server.h b/libs/includes/Server.h index fb44be7..dd48732 100644 --- a/libs/includes/Server.h +++ b/libs/includes/Server.h @@ -9,10 +9,10 @@ #include "DefineSystem.h" #include "Directory.h" -#include "ISocket.h" #include "Logger.h" #include "Request.h" #include "Response.h" +#include "Socket/ISocket.h" #include "Util.h" namespace simple_http_server { diff --git a/libs/includes/ISocket.h b/libs/includes/Socket/ISocket.h similarity index 100% rename from libs/includes/ISocket.h rename to libs/includes/Socket/ISocket.h diff --git a/libs/includes/PosixSocket.h b/libs/includes/Socket/PosixSocket.h similarity index 100% rename from libs/includes/PosixSocket.h rename to libs/includes/Socket/PosixSocket.h diff --git a/libs/includes/WindowsSocket.h b/libs/includes/Socket/WindowsSocket.h similarity index 100% rename from libs/includes/WindowsSocket.h rename to libs/includes/Socket/WindowsSocket.h diff --git a/libs/includes/SocketFactory.h b/libs/includes/SocketFactory.h index d14ddce..9ee4e12 100644 --- a/libs/includes/SocketFactory.h +++ b/libs/includes/SocketFactory.h @@ -1,14 +1,14 @@ #ifndef SIMPLE_HTTP_SERVER_SOCKETFACTORY_H #define SIMPLE_HTTP_SERVER_SOCKETFACTORY_H -#include "ISocket.h" +#include "Socket/ISocket.h" namespace simple_http_server { class SocketFactory { public: - static auto CreateSocket(const std::string& address, - int port) -> std::unique_ptr; + static auto CreateSocket(const std::string& address, int port) + -> std::unique_ptr; }; } // namespace simple_http_server diff --git a/libs/sources/Server.cpp b/libs/sources/Server.cpp index 499baef..8557471 100644 --- a/libs/sources/Server.cpp +++ b/libs/sources/Server.cpp @@ -14,10 +14,10 @@ #include #include "Directory.h" -#include "ISocket.h" #include "Logger.h" #include "Request.h" #include "Response.h" +#include "Socket/ISocket.h" #include "SocketFactory.h" #include "ThreadPool.h" #include "Util.h" @@ -194,8 +194,8 @@ void Server::MapDirectory(const std::string& url, const Directory& directory) { } auto Server::Render(const std::filesystem::path& file, - const std::string& content_type, - HeadersMap headers) -> Response { + const std::string& content_type, HeadersMap headers) + -> Response { std::ifstream temp(file, std::ios::binary); std::string content((std::istreambuf_iterator(temp)), diff --git a/libs/sources/PosixSocket.cpp b/libs/sources/Socket/PosixSocket.cpp similarity index 98% rename from libs/sources/PosixSocket.cpp rename to libs/sources/Socket/PosixSocket.cpp index afc0c63..7a6eb78 100644 --- a/libs/sources/PosixSocket.cpp +++ b/libs/sources/Socket/PosixSocket.cpp @@ -12,7 +12,7 @@ #include #include -#include "PosixSocket.h" +#include "Socket/PosixSocket.h" namespace simple_http_server { diff --git a/libs/sources/WindowsSocket.cpp b/libs/sources/Socket/WindowsSocket.cpp similarity index 99% rename from libs/sources/WindowsSocket.cpp rename to libs/sources/Socket/WindowsSocket.cpp index 9ec675f..f71801a 100644 --- a/libs/sources/WindowsSocket.cpp +++ b/libs/sources/Socket/WindowsSocket.cpp @@ -2,7 +2,7 @@ #ifdef WINDOWS -#include "WindowsSocket.h" +#include "Socket/WindowsSocket.h" #define SIMPLE_HTTP_SERVER_LIBS_POSIXSOCKET_H_USELESS_DEFINE // define to tell #undef SIMPLE_HTTP_SERVER_LIBS_POSIXSOCKET_H_USELESS_DEFINE // clang-format to diff --git a/libs/sources/SocketFactory.cpp b/libs/sources/SocketFactory.cpp index d2f19a2..f6d0bdf 100644 --- a/libs/sources/SocketFactory.cpp +++ b/libs/sources/SocketFactory.cpp @@ -4,20 +4,20 @@ #include #include "DefineSystem.h" -#include "ISocket.h" +#include "Socket/ISocket.h" #ifdef POSIX -#include "PosixSocket.h" +#include "Socket/PosixSocket.h" #elif defined WINDOWS -#include "WindowsSocket.h" +#include "Socket/WindowsSocket.h" #else #error Unknown platform #endif namespace simple_http_server { -auto SocketFactory::CreateSocket(const std::string& address, - int port) -> std::unique_ptr { +auto SocketFactory::CreateSocket(const std::string& address, int port) + -> std::unique_ptr { #ifdef POSIX return std::make_unique(address, port); #elif defined WINDOWS diff --git a/tests/server_tests.cpp b/tests/server_tests.cpp index 6a7fcdc..0fc246f 100644 --- a/tests/server_tests.cpp +++ b/tests/server_tests.cpp @@ -9,10 +9,10 @@ #include #include -#include "ISocket.h" #include "Logger.h" #include "Request.h" #include "Server.h" +#include "Socket/ISocket.h" #include "SocketFactory.h" namespace simple_http_server { diff --git a/tests/socket_tests.cpp b/tests/socket_tests.cpp index 0eea283..9a53951 100644 --- a/tests/socket_tests.cpp +++ b/tests/socket_tests.cpp @@ -5,7 +5,7 @@ #include #include -#include "ISocket.h" +#include "Socket/ISocket.h" #include "SocketFactory.h" namespace simple_http_server { From fa0e18018803514a664000153592ed4b124e0b0c Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:56:39 +0300 Subject: [PATCH 2/6] Move to Clang 22 --- CMakeLists.txt | 12 ++++---- libs/includes/DefineSystem.h | 2 +- libs/includes/Directory.h | 6 ++-- libs/includes/Logger.h | 2 ++ libs/includes/Request.h | 4 +-- libs/includes/Response.h | 19 +++++++++---- libs/sources/Logger.cpp | 4 ++- libs/sources/Request.cpp | 9 +++--- libs/sources/Response.cpp | 9 ++---- libs/sources/Server.cpp | 14 ++++++---- libs/sources/SocketFactory.cpp | 4 +-- libs/sources/ThreadPool.cpp | 5 ++-- main.cpp | 51 +++++++++++++++++++++------------- tests/logger_tests.cpp | 2 +- tests/request_tests.cpp | 10 +++---- tests/server_tests.cpp | 15 +++++----- tests/socket_tests.cpp | 2 +- 17 files changed, 98 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df5b3c6..4959616 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.25) project(simple-http-server) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -19,28 +19,28 @@ if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE IN_LIST CMAKE_CONFIGURATION_TYPES) endif() if(CMAKE_C_COMPILER_ID STREQUAL GNU OR CMAKE_C_COMPILER_ID MATCHES Clang) - set(CMAKE_C_FLAGS "-std=20 -pedantic -Wall -Werror -ggdb") + set(CMAKE_C_FLAGS "-std=23 -pedantic -Wall -Werror -ggdb") set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-optimize-sibling-calls -fno-omit-frame-pointer") set(CMAKE_C_FLAGS_LSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=leak") set(CMAKE_C_FLAGS_MSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=memory -fno-optimize-sibling-calls -fno-omit-frame-pointer") set(CMAKE_C_FLAGS_UBSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined") set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG} --coverage") elseif(MSVC) - set(CMAKE_C_FLAGS "/std:c20 /W4 /WX") + set(CMAKE_C_FLAGS "/std:c23 /W4 /WX") set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_DEBUG} /fsanitize=address") set(CMAKE_EXE_LINKER_FLAGS_ASAN "/debug /INCREMENTAL:NO") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang) - set(CMAKE_CXX_FLAGS "-std=c++20 -pedantic -Wall -Werror -ggdb") + set(CMAKE_CXX_FLAGS "-std=c++23 -pedantic -Wall -Werror -ggdb") set(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-optimize-sibling-calls -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS_LSAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=leak") set(CMAKE_CXX_FLAGS_MSAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=memory -fno-optimize-sibling-calls -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS_UBSAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage") elseif(MSVC) - set(CMAKE_CXX_FLAGS "/std:c++20 /W4 /WX") + set(CMAKE_CXX_FLAGS "/std:c++23 /W4 /WX") set(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} /fsanitize=address") set(CMAKE_EXE_LINKER_FLAGS_ASAN "/debug /INCREMENTAL:NO") endif() @@ -101,7 +101,7 @@ if(BUILD_TESTING) include(FetchContent) FetchContent_Declare( googletest - URL https://github.com/google/googletest/archive/d144031940543e15423a25ae5a8a74141044862f.zip + URL https://github.com/google/googletest/archive/d72f9c8aea6817cdf1ca0ac10887f328de7f3da2.zip DOWNLOAD_EXTRACT_TIMESTAMP NEW ) diff --git a/libs/includes/DefineSystem.h b/libs/includes/DefineSystem.h index a615595..b2de1f6 100644 --- a/libs/includes/DefineSystem.h +++ b/libs/includes/DefineSystem.h @@ -1,4 +1,4 @@ -#if defined __has_include +#ifdef __has_include #if __has_include() #define WINDOWS #elif __has_include() diff --git a/libs/includes/Directory.h b/libs/includes/Directory.h index 4cb274d..42ae0e1 100644 --- a/libs/includes/Directory.h +++ b/libs/includes/Directory.h @@ -11,7 +11,7 @@ namespace simple_http_server { class Directory { public: - enum AllowType : std::uint8_t { BLACKLIST, WHITELIST }; + enum class AllowType : std::uint8_t { BLACKLIST, WHITELIST }; private: std::filesystem::path path_; @@ -20,12 +20,14 @@ class Directory { AllowType type_; std::vector allow_set_; + + // NOLINTNEXTLINE(bugprone-throwing-static-initialization) inline static const std::vector forced_blacklist_ = { std::regex("^.*\\.\\..*$")}; // to block path traversal public: explicit Directory(std::filesystem::path path, HeadersMap headers = {}, - AllowType type = BLACKLIST, + AllowType type = AllowType::BLACKLIST, std::vector allow_set = {}) : path_(std::move(path)), headers_(std::move(headers)), diff --git a/libs/includes/Logger.h b/libs/includes/Logger.h index 0f076b8..c984fdd 100644 --- a/libs/includes/Logger.h +++ b/libs/includes/Logger.h @@ -17,6 +17,7 @@ namespace simple_http_server { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define X(level, name, i) level = (i), +// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class) enum Level : std::uint8_t { LOGGER_LEVELS }; #undef X @@ -32,6 +33,7 @@ class Logger { public: // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define X(level, name, _) name, + // NOLINTNEXTLINE(bugprone-throwing-static-initialization) inline static const std::vector level_name = {LOGGER_LEVELS}; #undef X private: diff --git a/libs/includes/Request.h b/libs/includes/Request.h index d619775..e7c8a12 100644 --- a/libs/includes/Request.h +++ b/libs/includes/Request.h @@ -10,7 +10,7 @@ namespace simple_http_server { class Request { public: - enum Type : std::uint8_t { + enum class Type : std::uint8_t { GET, POST, // add here new types such as DELETE and etc @@ -24,7 +24,7 @@ class Request { static auto ParseArguments(const std::string& url_with_args) -> ArgumentsMap; static auto DecodeURL(std::string& url_with_args); - Type type_ = UNKNOWN; + Type type_ = Type::UNKNOWN; std::string url_; ArgumentsMap arguments_; std::string httpVersion_; diff --git a/libs/includes/Response.h b/libs/includes/Response.h index 39313d0..b547d7a 100644 --- a/libs/includes/Response.h +++ b/libs/includes/Response.h @@ -19,6 +19,7 @@ class Response { [[nodiscard]] auto Empty() const -> bool { return (statusCode_ == 0); } + // NOLINTNEXTLINE(cppcoreguidelines-use-enum-class) enum HttpStatusCodes : std::uint16_t { OK = 200, FORBIDDEN = 403, @@ -33,11 +34,19 @@ class Response { HeadersMap headers_; std::string body_; - inline static const std::unordered_map defaultMessages_{ - {OK, "OK"}, - {NOT_FOUND, "Not Found"}, - {FORBIDDEN, "Forbidden"}, - {INTERNAL_ERROR, "Internal Server Error"}}; + static constexpr auto defaultMessage(int code) noexcept -> std::string_view { + switch (code) { + return "OK"; + case HttpStatusCodes::NOT_FOUND: + return "Not Found"; + case HttpStatusCodes::FORBIDDEN: + return "Forbidden"; + case HttpStatusCodes::INTERNAL_ERROR: + return "Internal Server Error"; + default: + return "Unknown"; + } + } }; } // namespace simple_http_server diff --git a/libs/sources/Logger.cpp b/libs/sources/Logger.cpp index 2a1eff9..62fcda6 100644 --- a/libs/sources/Logger.cpp +++ b/libs/sources/Logger.cpp @@ -10,7 +10,9 @@ namespace simple_http_server { +// NOLINTNEXTLINE(bugprone-throwing-static-initialization) std::filesystem::path Logger::logFilename_ = "./server.log"; +// NOLINTNEXTLINE(bugprone-throwing-static-initialization) std::ofstream Logger::logStream_; Level Logger::logLevel_ = WARNING; bool Logger::isInit_ = false; @@ -44,7 +46,7 @@ void Logger::Log(Level level, std::ostringstream&& message) { const time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); Logger::logStream_ << std::put_time(std::localtime(&now), "%Y-%m-%d@%H:%M:%S") - << " " << level_name[level] << " " + << " " << level_name.at(level) << " " << std::move(message).str() << "\n"; Flush(); // TODO(dzen) think about flush(); probably should use Flush() each N lines diff --git a/libs/sources/Request.cpp b/libs/sources/Request.cpp index e205b5c..d451493 100644 --- a/libs/sources/Request.cpp +++ b/libs/sources/Request.cpp @@ -16,7 +16,8 @@ auto Request::ParseArguments(const std::string& url_with_args) -> ArgumentsMap { auto next_arg = args_start; - auto parse_argument = [&ret, &url_with_args](auto current_arg) mutable { + auto parse_argument = [&ret, + &url_with_args](auto current_arg) mutable -> auto { auto sep = url_with_args.find('=', current_arg); auto next_arg = url_with_args.find('&', current_arg + 1); @@ -55,11 +56,11 @@ auto Request::DecodeURL(std::string& url_with_args) { res.reserve(url_with_args.length()); for (std::string::size_type it = 0; it < url_with_args.length(); ++it) { - if (url_with_args[it] == '%' && it < url_with_args.length() - 3) { - res += HexToDec({url_with_args[it + 1], url_with_args[it + 2]}); + if (url_with_args.at(it) == '%' && it < url_with_args.length() - 3) { + res += HexToDec({url_with_args.at(it + 1), url_with_args.at(it + 2)}); it += 2; } else { - res += url_with_args[it]; + res += url_with_args.at(it); } } diff --git a/libs/sources/Response.cpp b/libs/sources/Response.cpp index 0a040de..4e1a68b 100644 --- a/libs/sources/Response.cpp +++ b/libs/sources/Response.cpp @@ -1,7 +1,6 @@ #include "Response.h" #include -#include #include #include @@ -14,12 +13,8 @@ Response::Response(int statusCode, std::string body, HeadersMap headers, : statusCode_(statusCode), headers_(std::move(headers)), body_(std::move(body)) { - if (statusMessage.empty() && !defaultMessages_.contains(statusCode)) { - throw std::runtime_error("no message for error code provided"); - } - - statusMessage_ = (statusMessage.empty() ? defaultMessages_.at(statusCode_) - : statusMessage); + statusMessage_ = + (statusMessage.empty() ? defaultMessage(statusCode_) : statusMessage); if (!headers_.contains("Content-Length")) { headers_.emplace("Content-Length", std::to_string(body_.length())); } diff --git a/libs/sources/Server.cpp b/libs/sources/Server.cpp index 8557471..849bff2 100644 --- a/libs/sources/Server.cpp +++ b/libs/sources/Server.cpp @@ -44,7 +44,8 @@ void Server::Start() { try { const auto& client_sock = socket_->Accept(); - threadPool.enqueue([this, client_sock]() { HandleClient(client_sock); }); + threadPool.enqueue( + [this, client_sock]() -> auto { HandleClient(client_sock); }); } catch (const std::exception& exception) { LOG(ERROR, exception.what()); @@ -73,18 +74,19 @@ auto Server::TryRenderFile(const Request& request) -> Response { path /= request.GetUrl().substr(prev_pos + 1); - auto check_path = [](const auto& type, const auto& set, const auto& path) { - bool allowed = (type == Directory::BLACKLIST); + auto check_path = [](const auto& type, const auto& set, + const auto& path) -> auto { + bool allowed = (type == Directory::AllowType::BLACKLIST); for (const auto& reg : set) { if (std::regex_match(path.string(), reg)) { - allowed = (type == Directory::WHITELIST); + allowed = (type == Directory::AllowType::WHITELIST); } } return allowed; }; - bool allowed = - check_path(Directory::BLACKLIST, Directory::GetForcedBlacklist(), path); + bool allowed = check_path(Directory::AllowType::BLACKLIST, + Directory::GetForcedBlacklist(), path); allowed = (allowed ? check_path(dir.GetType(), dir.GetAllowSet(), path) : false); diff --git a/libs/sources/SocketFactory.cpp b/libs/sources/SocketFactory.cpp index f6d0bdf..4f457fb 100644 --- a/libs/sources/SocketFactory.cpp +++ b/libs/sources/SocketFactory.cpp @@ -8,7 +8,7 @@ #ifdef POSIX #include "Socket/PosixSocket.h" -#elif defined WINDOWS +#elifdef WINDOWS #include "Socket/WindowsSocket.h" #else #error Unknown platform @@ -20,7 +20,7 @@ auto SocketFactory::CreateSocket(const std::string& address, int port) -> std::unique_ptr { #ifdef POSIX return std::make_unique(address, port); -#elif defined WINDOWS +#elifdef WINDOWS return std::make_unique(address, port); #else #error Unknown platform diff --git a/libs/sources/ThreadPool.cpp b/libs/sources/ThreadPool.cpp index 0905f76..dd28211 100644 --- a/libs/sources/ThreadPool.cpp +++ b/libs/sources/ThreadPool.cpp @@ -11,7 +11,7 @@ ThreadPool::ThreadPool(std::uint64_t numThreads) { for (decltype(numThreads) i = 0; i < numThreads; ++i) { - workers_.emplace_back([this] { workerThread(); }); + workers_.emplace_back([this]() -> void { workerThread(); }); } } @@ -39,7 +39,8 @@ void ThreadPool::workerThread() { std::function task; { std::unique_lock lock(queueMutex_); - condition_.wait(lock, [this] { return stop_ || !tasks_.empty(); }); + condition_.wait(lock, + [this]() -> auto { return stop_ || !tasks_.empty(); }); if (stop_ && tasks_.empty()) { return; diff --git a/main.cpp b/main.cpp index 13d40cb..3ce2e8c 100644 --- a/main.cpp +++ b/main.cpp @@ -5,31 +5,42 @@ #include "Request.h" #include "Response.h" #include "Server.h" +#include "exception" +#include "iostream" auto main() -> int { - static constexpr int DEFAULT_PORT = 8080; - simple_http_server::Server server("0.0.0.0", DEFAULT_PORT, - simple_http_server::DEBUG); + try { + static constexpr int DEFAULT_PORT = 8080; + simple_http_server::Server server("0.0.0.0", DEFAULT_PORT, + simple_http_server::DEBUG); - server.MapUrl( - "/plain", - [](const simple_http_server::Request&) { - return simple_http_server::Response( - simple_http_server::Response::HttpStatusCodes::OK, - "Hello world in plain text"); - }, - true); + server.MapUrl( + "/plain", + [](const simple_http_server::Request&) -> auto { + return simple_http_server::Response( + simple_http_server::Response::HttpStatusCodes::OK, + "Hello world in plain text"); + }, + true); - server.MapUrl("/", [](const simple_http_server::Request&) { - return simple_http_server::Server::Render("index.html"); - }); + server.MapUrl("/", [](const simple_http_server::Request&) -> auto { + return simple_http_server::Server::Render("index.html"); + }); - server.MapDirectory("/dir", - simple_http_server::Directory( - "./", {}, simple_http_server::Directory::WHITELIST, - {std::regex("^.*.log$")})); + server.MapDirectory( + "/dir", + simple_http_server::Directory( + "./", {}, simple_http_server::Directory::AllowType::WHITELIST, + {std::regex("^.*.log$")})); - server.Start(); + server.Start(); - return 0; + return 0; + } catch (const std::exception& exc) { + std::cerr << "Fatal error: " << exc.what() << '\n'; + return 1; + } catch (...) { + std::cerr << "Unknown fatal error\n"; + return 1; + } } diff --git a/tests/logger_tests.cpp b/tests/logger_tests.cpp index 3cf993a..0e4a19a 100644 --- a/tests/logger_tests.cpp +++ b/tests/logger_tests.cpp @@ -32,7 +32,7 @@ TEST(Logger, MainTest) { for (const auto& line : levels) { log >> time >> level >> messageKey >> messageValue; - EXPECT_EQ(level, Logger::level_name[line.first]); + EXPECT_EQ(level, Logger::level_name.at(line.first)); EXPECT_EQ(messageKey, "line.second:"); EXPECT_EQ(messageValue, line.second); } diff --git a/tests/request_tests.cpp b/tests/request_tests.cpp index cedafab..a11757a 100644 --- a/tests/request_tests.cpp +++ b/tests/request_tests.cpp @@ -13,7 +13,7 @@ TEST(Request, Parse) { "\r\n" "field1=value1&field2=value2"); - EXPECT_EQ(parsed.GetType(), Request::POST); + EXPECT_EQ(parsed.GetType(), Request::Type::POST); EXPECT_EQ(parsed.GetUrl(), "/home.html"); EXPECT_EQ(parsed.GetArguments(), ArgumentsMap()); EXPECT_EQ(parsed.GetHttpVersion(), "HTTP/1.1"); @@ -32,7 +32,7 @@ TEST(Request, ParseWithArguments) { "Gecko/20100101 Firefox/50.0\r\n" "\r\n"); - EXPECT_EQ(parsed.GetType(), Request::GET); + EXPECT_EQ(parsed.GetType(), Request::Type::GET); EXPECT_EQ(parsed.GetUrl(), "/home.html"); EXPECT_EQ(parsed.GetArguments(), ArgumentsMap({{"a", "b"}, {"c", "d"}})); EXPECT_EQ(parsed.GetHttpVersion(), "HTTP/1.1"); @@ -52,7 +52,7 @@ TEST(Request, ParseDecoded) { "Gecko/20100101 Firefox/50.0\r\n" "\r\n"); - EXPECT_EQ(parsed.GetType(), Request::GET); + EXPECT_EQ(parsed.GetType(), Request::Type::GET); EXPECT_EQ(parsed.GetUrl(), "/home.html"); EXPECT_EQ(parsed.GetArguments(), ArgumentsMap({{"a", "b b"}, {"c", "d"}})); EXPECT_EQ(parsed.GetHttpVersion(), "HTTP/1.1"); @@ -71,7 +71,7 @@ TEST(Request, ParseInvalidHeaders) { "User-Agent: \r\n" "\r\n"); - EXPECT_EQ(parsed.GetType(), Request::UNKNOWN); + EXPECT_EQ(parsed.GetType(), Request::Type::UNKNOWN); EXPECT_EQ(parsed.GetUrl(), "google.com"); EXPECT_EQ(parsed.GetArguments(), ArgumentsMap({})); EXPECT_EQ(parsed.GetHttpVersion(), "HTTP/1.1"); @@ -88,7 +88,7 @@ TEST(Request, ParseInvalidHeadersWithValid) { "(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36\r\n" "\r\n"); - EXPECT_EQ(parsed.GetType(), Request::GET); + EXPECT_EQ(parsed.GetType(), Request::Type::GET); EXPECT_EQ(parsed.GetUrl(), "/manager/html"); EXPECT_EQ(parsed.GetArguments(), ArgumentsMap({})); EXPECT_EQ(parsed.GetHttpVersion(), "HTTP/1.1"); diff --git a/tests/server_tests.cpp b/tests/server_tests.cpp index 0fc246f..891e270 100644 --- a/tests/server_tests.cpp +++ b/tests/server_tests.cpp @@ -1,13 +1,14 @@ #include +#include #include #include #include #include #include +#include #include #include -#include #include "Logger.h" #include "Request.h" @@ -18,11 +19,10 @@ namespace simple_http_server { namespace { -const std::vector results = { +constexpr std::array results = { "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: " "17\r\n\r\ntest1234片仮名", "HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"}; -} // namespace class ServerTest : public testing::TestWithParam> { protected: @@ -44,17 +44,17 @@ class ServerTest : public testing::TestWithParam> { server = new Server("127.0.0.1", port); // NOLINT - server_thread = std::thread([]() { + server_thread = std::thread([]() -> auto { server->MapUrl( "/true", - [](const simple_http_server::Request&) { + [](const simple_http_server::Request&) -> auto { return simple_http_server::Response( simple_http_server::Response::OK, "test1234片仮名"); }, true); server->MapUrl( "/false", - [](const simple_http_server::Request&) { + [](const simple_http_server::Request&) -> auto { return simple_http_server::Response( simple_http_server::Response::OK, "test1234片仮名"); }, @@ -98,7 +98,7 @@ TEST_P(ServerTest, TestMappings) { EXPECT_FALSE(resp->empty()); EXPECT_EQ(std::string(resp->begin(), resp->end()), - results[GetParam().second]); + results.at(GetParam().second)); } INSTANTIATE_TEST_SUITE_P(, ServerTest, @@ -107,4 +107,5 @@ INSTANTIATE_TEST_SUITE_P(, ServerTest, std::make_pair("/true/1234", 0), std::make_pair("/false/1234", 1))); +} // namespace } // namespace simple_http_server diff --git a/tests/socket_tests.cpp b/tests/socket_tests.cpp index 9a53951..dbee7be 100644 --- a/tests/socket_tests.cpp +++ b/tests/socket_tests.cpp @@ -25,7 +25,7 @@ TEST(Socket, BasicPong) { ASSERT_TRUE(server->BindAndListen()); - std::thread server_thread([&server, &test_message]() { + std::thread server_thread([&server, &test_message]() -> auto { auto client_sock = server->Accept(); const auto& received = server->ReceiveMessage(client_sock); From ccf28f3fe2b02c45b5d7d01241da0fbf0bba6a40 Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Mon, 11 May 2026 22:31:28 +0300 Subject: [PATCH 3/6] Fix tests --- .gitignore | 1 + libs/includes/Response.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1a5a6b3..c8d63fb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .vscode/ **/.DS_Store **/*build*/ +Testing/ diff --git a/libs/includes/Response.h b/libs/includes/Response.h index b547d7a..f928cd6 100644 --- a/libs/includes/Response.h +++ b/libs/includes/Response.h @@ -36,7 +36,8 @@ class Response { static constexpr auto defaultMessage(int code) noexcept -> std::string_view { switch (code) { - return "OK"; + case HttpStatusCodes::OK: + return "OK"; case HttpStatusCodes::NOT_FOUND: return "Not Found"; case HttpStatusCodes::FORBIDDEN: From 67a47800f3e558d4401ae28dd02f62c611a7d288 Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Sat, 23 May 2026 14:01:21 +0300 Subject: [PATCH 4/6] Move runners to clang 22 too --- .github/workflows/ctest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ctest.yml b/.github/workflows/ctest.yml index 7f37eb1..1520e82 100644 --- a/.github/workflows/ctest.yml +++ b/.github/workflows/ctest.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - name: Configure CMake - run: CXX=clang++-19 CC=clang-19 cmake -S ${{github.workspace}}/ -B ${{runner.workspace}}/build -DCLANG_TIDY_NAME=clang-tidy-19 + run: CXX=clang++-22 CC=clang-22 cmake -S ${{github.workspace}}/ -B ${{runner.workspace}}/build -DCLANG_TIDY_NAME=clang-tidy-22 - name: Build working-directory: ${{runner.workspace}}/build From 5e11f8a7169432768563a965fc06a7ea5ee9cc75 Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Sat, 23 May 2026 15:40:15 +0300 Subject: [PATCH 5/6] Fix windows build --- libs/includes/Socket/WindowsSocket.h | 1 + libs/sources/Socket/WindowsSocket.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/includes/Socket/WindowsSocket.h b/libs/includes/Socket/WindowsSocket.h index 841d39c..1ba7f20 100644 --- a/libs/includes/Socket/WindowsSocket.h +++ b/libs/includes/Socket/WindowsSocket.h @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/libs/sources/Socket/WindowsSocket.cpp b/libs/sources/Socket/WindowsSocket.cpp index f71801a..9bab1b5 100644 --- a/libs/sources/Socket/WindowsSocket.cpp +++ b/libs/sources/Socket/WindowsSocket.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include // I have no idea, where SOCKET_ERROR, etc defined, so @@ -89,7 +90,7 @@ auto WindowsSocket::SendMessageAndCloseClient( auto WindowsSocket::Accept() -> WindowsSocket::SocketDescriptor { auto client_addr = accept(socketDescriptor_, nullptr, nullptr); - if (client_addr == INVALID_SOCKET) { + if (std::cmp_equal(client_addr, INVALID_SOCKET)) { throw std::runtime_error("could not accept socket"); } From e51d30a2ea19395118acbeec43369cff94ae297f Mon Sep 17 00:00:00 2001 From: dzen03 <43926347+dzen03@users.noreply.github.com> Date: Sat, 23 May 2026 15:42:01 +0300 Subject: [PATCH 6/6] Fix CI --- .github/workflows/ctest.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ctest.yml b/.github/workflows/ctest.yml index 1520e82..51b6025 100644 --- a/.github/workflows/ctest.yml +++ b/.github/workflows/ctest.yml @@ -13,7 +13,7 @@ jobs: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Configure CMake run: CXX=clang++-22 CC=clang-22 cmake -S ${{github.workspace}}/ -B ${{runner.workspace}}/build -DCLANG_TIDY_NAME=clang-tidy-22 @@ -40,10 +40,10 @@ jobs: shell: pwsh steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Configure CMake - run: cmake -S ${{github.workspace}}\ -B ${{runner.workspace}}\build -G "Ninja" + run: cmake -S ${{github.workspace}}\ -B ${{runner.workspace}}\build -G "MinGW Makefiles" - name: Build working-directory: ${{runner.workspace}}\build