From 95d78149f2cb350300b8af8ec29767da864ea310 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 20:49:49 -0500 Subject: [PATCH 01/10] Remove ServerStartsAndAcceptsRequests test because it affects subsequent tests --- test/HttpServerTest.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index beb4dc2..32ed99e 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -10,23 +10,14 @@ TEST(ServerTest, ConstructorDestructorTest) { HttpServer server {}; } -TEST(HttpServerTest, ServerStartsAndAcceptsRequests) { - HttpServer server {}; - - // Start server in non-blocking mode - server.start_listening(8080); - - // Send real HTTP request using curl - int result = system("curl -s http://localhost:8080 > /dev/null"); - - EXPECT_EQ(result, 0); -} - TEST(HttpServerTest, AcceptsHttpRequest) { - HttpServer server; + HttpServer server {}; + server.get_mapping("/", [](const HttpServer::Request&, HttpServer::Response& res) { + res.body = "test"; + }); server.start_listening(8081); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); int sock = socket(AF_INET, SOCK_STREAM, 0); From fa03f25fff7d6a70bd793c57fb1c681a7b5c22bb Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 20:51:31 -0500 Subject: [PATCH 02/10] Implement a test that handles the case where GET Requests of an unknown api route is called --- test/HttpServerTest.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index 32ed99e..c233572 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -198,3 +198,32 @@ TEST(HttpServerTest, AllUniqueReqMethods) { ASSERT_TRUE(close(listener_fd) != -1); } } + +TEST(HttpServerTest, HandleNonExistentGetRoute) { + HttpServer server {}; + server.start_listening(8083); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(8083); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + std::string request = "GET /foo HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 0\r\n" + "\r\n"; + + int listener_fd = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); + send(listener_fd, request.c_str(), request.size(), 0); + + char buffer[1024] {}; + int bytes = recv(listener_fd, buffer, sizeof(buffer), 0); + std::string result = std::string(buffer); + + EXPECT_GT(bytes, 0); + ASSERT_TRUE(result.find("404 Not Found") != std::string::npos); + ASSERT_TRUE(close(listener_fd) != -1); +} \ No newline at end of file From 7eee1b41aa640624e16399e3f6dc59c23a0df557 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 20:53:02 -0500 Subject: [PATCH 03/10] Implement a test that handles the case where POST Requests of an unknown api route is called This test covers cases where the Http method does not ignore the request body --- test/HttpServerTest.cpp | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index c233572..24c96e6 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -28,7 +28,11 @@ TEST(HttpServerTest, AcceptsHttpRequest) { ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); - const char* request = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"; + const char* request = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" + "Host: localhost\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 0\r\n" + "\r\n"; send(sock, request, strlen(request), 0); char buffer[1024]; @@ -186,7 +190,7 @@ TEST(HttpServerTest, AllUniqueReqMethods) { "\r\n"; int listener_fd = socket(AF_INET, SOCK_STREAM, 0); - ASSERT_EQ(connect(listener_fd, (sockaddr*)&addr, sizeof(addr)), 0); + ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); send(listener_fd, request.c_str(), request.size(), 0); char buffer[1024] {}; @@ -226,4 +230,37 @@ TEST(HttpServerTest, HandleNonExistentGetRoute) { EXPECT_GT(bytes, 0); ASSERT_TRUE(result.find("404 Not Found") != std::string::npos); ASSERT_TRUE(close(listener_fd) != -1); -} \ No newline at end of file +} + +/* + * This test covers a different branch than HandleNonExistentGetRoute + * because POST requests can handle the request body + */ +TEST(HttpServerTest, HandleNonExistentPostRoute) { + HttpServer server {}; + server.start_listening(8084); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(8084); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + std::string request = "POST /foo HTTP/1.1\r\n"; + // "Host: localhost\r\n" + // "Connection: keep-alive\r\n" + // "Content-Length: 0\r\n" + // "\r\n"; + + int listener_fd = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); + send(listener_fd, request.c_str(), request.size(), 0); + + char buffer[1024] {}; + int bytes = recv(listener_fd, buffer, sizeof(buffer), 0); + std::string result = std::string(buffer); + + EXPECT_GT(bytes, 0); + ASSERT_TRUE(result.find("404 Not Found") != std::string::npos); + ASSERT_TRUE(close(listener_fd) != -1); +} From ff6850515cb4c74b3a6215860060e5301d15fc26 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 20:54:01 -0500 Subject: [PATCH 04/10] Implement a test that handles the case where an unknown Http method is called --- test/HttpServerTest.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index 24c96e6..8cef950 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -264,3 +264,37 @@ TEST(HttpServerTest, HandleNonExistentPostRoute) { ASSERT_TRUE(result.find("404 Not Found") != std::string::npos); ASSERT_TRUE(close(listener_fd) != -1); } + +TEST(HttpServerTest, HandleNonExistentHttpMethod) { + HttpServer server {}; + server.start_listening(8084); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(8084); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + std::string request = "FOO /foo HTTP/1.1\r\n"; + // "Host: localhost\r\n" + // "Connection: keep-alive\r\n" + // "Content-Length: 0\r\n" + // "\r\n"; + + int listener_fd = socket(AF_INET, SOCK_STREAM, 0); + ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); + send(listener_fd, request.c_str(), request.size(), 0); + + char buffer[1024] {}; + int bytes = recv(listener_fd, buffer, sizeof(buffer), 0); + std::string result = std::string(buffer); + + EXPECT_GT(bytes, 0); + ASSERT_TRUE(result.find("500 Error") != std::string::npos); + ASSERT_TRUE(close(listener_fd) != -1); +} + +TEST(HttpServerTest, ListenThrowsIfSocketInvalid) { + HttpServer server {}; + EXPECT_THROW(server.listen(-1), std::runtime_error); +} From 653549a335f0e5c14229b1ff9140e45bb81522c9 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 22:31:03 -0500 Subject: [PATCH 05/10] Fix an issue that caused test failures on first build --- test/HttpServerTest.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index 8cef950..1eaf726 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -79,7 +79,7 @@ TEST(HttpServerTest, IgnoreGetReqBody) { server.get_mapping("/hello", [](const HttpServer::Request& req, HttpServer::Response& res){ res.body = req.body; }); - server.start_listening(8082); + server.start_listening(8083); std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -87,7 +87,7 @@ TEST(HttpServerTest, IgnoreGetReqBody) { sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8082); + addr.sin_port = htons(8083); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); @@ -112,7 +112,7 @@ TEST(HttpServerTest, DoesntIgnorePostReqBody) { server.post_mapping("/post-foo", [](const HttpServer::Request& req, HttpServer::Response& res){ res.body = req.body; }); - server.start_listening(8082); + server.start_listening(8084); std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -120,7 +120,7 @@ TEST(HttpServerTest, DoesntIgnorePostReqBody) { sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8082); + addr.sin_port = htons(8084); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); @@ -172,13 +172,13 @@ TEST(HttpServerTest, AllUniqueReqMethods) { res.body = "8"; }); - server.start_listening(8083); + server.start_listening(8085); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8083); + addr.sin_port = htons(8085); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); const std::string methods[9] = { "GET", "POST", "PUT", "PATCH", "OPTIONS", "HEAD", "DELETE", "CONNECT", "TRACE" }; @@ -205,12 +205,12 @@ TEST(HttpServerTest, AllUniqueReqMethods) { TEST(HttpServerTest, HandleNonExistentGetRoute) { HttpServer server {}; - server.start_listening(8083); + server.start_listening(8086); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8083); + addr.sin_port = htons(8086); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "GET /foo HTTP/1.1\r\n" @@ -238,12 +238,12 @@ TEST(HttpServerTest, HandleNonExistentGetRoute) { */ TEST(HttpServerTest, HandleNonExistentPostRoute) { HttpServer server {}; - server.start_listening(8084); + server.start_listening(8087); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8084); + addr.sin_port = htons(8087); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "POST /foo HTTP/1.1\r\n"; @@ -267,12 +267,12 @@ TEST(HttpServerTest, HandleNonExistentPostRoute) { TEST(HttpServerTest, HandleNonExistentHttpMethod) { HttpServer server {}; - server.start_listening(8084); + server.start_listening(8088); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8084); + addr.sin_port = htons(8088); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "FOO /foo HTTP/1.1\r\n"; From 27a5ac3ed7b3d8a7acb6e46d57941ae7ceb71f74 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 23:03:20 -0500 Subject: [PATCH 06/10] Replace all C-style type casting into reinterpret_cast --- test/HttpServerTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index 1eaf726..f45b35e 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -26,7 +26,7 @@ TEST(HttpServerTest, AcceptsHttpRequest) { addr.sin_port = htons(8081); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); + ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); const char* request = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" "Host: localhost\r\n" @@ -59,7 +59,7 @@ TEST(HttpServerTest, AcceptGetRequest) { addr.sin_port = htons(8082); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); + ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); const char* request = "GET /hello HTTP/1.1\r\n\r\n"; send(sock, request, strlen(request), 0); @@ -90,7 +90,7 @@ TEST(HttpServerTest, IgnoreGetReqBody) { addr.sin_port = htons(8083); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); + ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); const char* request = "GET /hello HTTP/1.1\r\n\r\nhello, world"; send(sock, request, strlen(request), 0); @@ -123,7 +123,7 @@ TEST(HttpServerTest, DoesntIgnorePostReqBody) { addr.sin_port = htons(8084); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - ASSERT_EQ(connect(sock, (sockaddr*)&addr, sizeof(addr)), 0); + ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); const char* request = "POST /post-foo HTTP/1.1\r\n\r\nhello, world"; send(sock, request, strlen(request), 0); From 695ea9756ec388f8efab7b258a5115486e6c5245 Mon Sep 17 00:00:00 2001 From: James Yab Date: Sun, 14 Dec 2025 23:04:18 -0500 Subject: [PATCH 07/10] Add proper initialization for stop_flag --- include/HttpServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/HttpServer.h b/include/HttpServer.h index baf0f93..7c8b411 100644 --- a/include/HttpServer.h +++ b/include/HttpServer.h @@ -14,7 +14,7 @@ class HttpServer { ~HttpServer(); - std::atomic stop_flag; + std::atomic stop_flag {}; struct Request { std::string_view route; From fee3c2ec334751e34e8e7ecd5f2a0609d1467d56 Mon Sep 17 00:00:00 2001 From: James Yab Date: Tue, 16 Dec 2025 01:00:27 -0500 Subject: [PATCH 08/10] Add proper requests for the tests --- test/HttpServerTest.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index f45b35e..8a053fc 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -246,11 +246,11 @@ TEST(HttpServerTest, HandleNonExistentPostRoute) { addr.sin_port = htons(8087); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - std::string request = "POST /foo HTTP/1.1\r\n"; - // "Host: localhost\r\n" - // "Connection: keep-alive\r\n" - // "Content-Length: 0\r\n" - // "\r\n"; + std::string request = "POST /foo HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 0\r\n" + "\r\n"; int listener_fd = socket(AF_INET, SOCK_STREAM, 0); ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); @@ -275,11 +275,11 @@ TEST(HttpServerTest, HandleNonExistentHttpMethod) { addr.sin_port = htons(8088); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - std::string request = "FOO /foo HTTP/1.1\r\n"; - // "Host: localhost\r\n" - // "Connection: keep-alive\r\n" - // "Content-Length: 0\r\n" - // "\r\n"; + std::string request = "FOO /foo HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 0\r\n" + "\r\n"; int listener_fd = socket(AF_INET, SOCK_STREAM, 0); ASSERT_EQ(connect(listener_fd, reinterpret_cast(&addr), sizeof(addr)), 0); From 3931eb26f4d67865fb030273fbf9b4b5d9ee66cf Mon Sep 17 00:00:00 2001 From: James Yab Date: Tue, 16 Dec 2025 01:12:03 -0500 Subject: [PATCH 09/10] Refactor proper parsing of the request body This makes sure that the delimiter exists before arithmetic --- src/HttpServer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/HttpServer.cpp b/src/HttpServer.cpp index 069e8e9..82e7a04 100644 --- a/src/HttpServer.cpp +++ b/src/HttpServer.cpp @@ -52,7 +52,7 @@ void HttpServer::listen(int port) { struct sockaddr_storage incoming_addr {}; socklen_t addr_size {sizeof(incoming_addr)}; - int conn_file_descriptor = accept(listener_fd, (struct sockaddr*)&incoming_addr, &addr_size); + int conn_file_descriptor = accept(listener_fd, reinterpret_cast(&incoming_addr), &addr_size); if (conn_file_descriptor == -1) { // If we're stopping, accept failures are expected; don't spam logs. if (stop_flag.load()) break; @@ -143,12 +143,14 @@ void HttpServer::handle_client() { // std::cout << "route: " << route << '\n'; // get body - size_t req_body_start = path.find("\r\n\r\n") + 4; - if (req_body_start == std::string_view::npos) { + size_t req_body_delimiter = path.find("\r\n\r\n"); + if (req_body_delimiter == std::string_view::npos) { close (conn_fd); std::cerr << "Invalid request formatting: the start of the request body is malformed\n"; + continue; } + size_t req_body_start = req_body_delimiter + 4; std::string_view req_body = path.substr(req_body_start, path.size() - req_body_start); // std::cout << "body: " << req_body << '\n'; From d9dffdc22e1666be82eb86d1d04ba42e436d3273 Mon Sep 17 00:00:00 2001 From: James Yab Date: Tue, 16 Dec 2025 01:18:02 -0500 Subject: [PATCH 10/10] Use the same port for all HttpServerTest tests --- test/HttpServerTest.cpp | 85 +++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/test/HttpServerTest.cpp b/test/HttpServerTest.cpp index 8a053fc..2af9e60 100644 --- a/test/HttpServerTest.cpp +++ b/test/HttpServerTest.cpp @@ -4,7 +4,10 @@ #include #include -class HttpServerTest : public ::testing::Test {}; +class HttpServerTest : public ::testing::Test { +public: + static constexpr int port {8081}; +}; TEST(ServerTest, ConstructorDestructorTest) { HttpServer server {}; @@ -15,15 +18,15 @@ TEST(HttpServerTest, AcceptsHttpRequest) { server.get_mapping("/", [](const HttpServer::Request&, HttpServer::Response& res) { res.body = "test"; }); - server.start_listening(8081); + server.start_listening(HttpServerTest::port); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); int sock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8081); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); @@ -48,7 +51,7 @@ TEST(HttpServerTest, AcceptGetRequest) { server.get_mapping("/hello", [](const HttpServer::Request&, HttpServer::Response& res){ res.body = "hello, world"; }); - server.start_listening(8082); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -56,7 +59,7 @@ TEST(HttpServerTest, AcceptGetRequest) { sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8082); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); @@ -79,7 +82,7 @@ TEST(HttpServerTest, IgnoreGetReqBody) { server.get_mapping("/hello", [](const HttpServer::Request& req, HttpServer::Response& res){ res.body = req.body; }); - server.start_listening(8083); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -87,7 +90,7 @@ TEST(HttpServerTest, IgnoreGetReqBody) { sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8083); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); @@ -108,36 +111,44 @@ TEST(HttpServerTest, IgnoreGetReqBody) { } TEST(HttpServerTest, DoesntIgnorePostReqBody) { - HttpServer server {}; - server.post_mapping("/post-foo", [](const HttpServer::Request& req, HttpServer::Response& res){ - res.body = req.body; - }); - server.start_listening(8084); + try { + HttpServer server {}; + server.post_mapping("/foo", [](const HttpServer::Request& req, HttpServer::Response& res){ + res.body = req.body; + }); + server.start_listening(HttpServerTest::port); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); - int sock = socket(AF_INET, SOCK_STREAM, 0); + int sock = socket(AF_INET, SOCK_STREAM, 0); - sockaddr_in addr{}; - addr.sin_family = AF_INET; - addr.sin_port = htons(8084); - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(HttpServerTest::port); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); + ASSERT_EQ(connect(sock, reinterpret_cast(&addr), sizeof(addr)), 0); - const char* request = "POST /post-foo HTTP/1.1\r\n\r\nhello, world"; - send(sock, request, strlen(request), 0); + std::string request = "POST /foo HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: keep-alive\r\n" + "Content-Length: 5\r\n" + "\r\n" + "hello"; - char buffer[1024] {}; - int bytes = recv(sock, buffer, sizeof(buffer), 0); - std::string result = std::string(buffer); + send(sock, request.c_str(), request.size(), 0); - EXPECT_GT(bytes, 0); + char buffer[1024] {}; + int bytes = recv(sock, buffer, sizeof(buffer), 0); + std::string result = std::string(buffer); - // Should find "hello, world" as setting the request body - ASSERT_TRUE(result.find("hello, world") != std::string::npos); + EXPECT_GT(bytes, 0); + ASSERT_TRUE(result.find("hello") != std::string::npos); - close(sock); + close(sock); + } catch (const std::exception& e) { + FAIL() << "Exception occurred: " << e.what(); + } } TEST(HttpServerTest, AllUniqueReqMethods) { @@ -172,13 +183,13 @@ TEST(HttpServerTest, AllUniqueReqMethods) { res.body = "8"; }); - server.start_listening(8085); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8085); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); const std::string methods[9] = { "GET", "POST", "PUT", "PATCH", "OPTIONS", "HEAD", "DELETE", "CONNECT", "TRACE" }; @@ -205,12 +216,12 @@ TEST(HttpServerTest, AllUniqueReqMethods) { TEST(HttpServerTest, HandleNonExistentGetRoute) { HttpServer server {}; - server.start_listening(8086); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8086); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "GET /foo HTTP/1.1\r\n" @@ -238,12 +249,12 @@ TEST(HttpServerTest, HandleNonExistentGetRoute) { */ TEST(HttpServerTest, HandleNonExistentPostRoute) { HttpServer server {}; - server.start_listening(8087); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8087); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "POST /foo HTTP/1.1\r\n" @@ -267,12 +278,12 @@ TEST(HttpServerTest, HandleNonExistentPostRoute) { TEST(HttpServerTest, HandleNonExistentHttpMethod) { HttpServer server {}; - server.start_listening(8088); + server.start_listening(HttpServerTest::port); std::this_thread::sleep_for(std::chrono::milliseconds(1)); sockaddr_in addr{}; addr.sin_family = AF_INET; - addr.sin_port = htons(8088); + addr.sin_port = htons(HttpServerTest::port); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); std::string request = "FOO /foo HTTP/1.1\r\n"