From 2d9bf7a37f15af04b2ed0f3cc491349a6e00ede0 Mon Sep 17 00:00:00 2001 From: Quinten Date: Wed, 29 Oct 2025 14:29:59 +0100 Subject: [PATCH] feat: add remote addr to cgi env --- webserv/client/Client.cpp | 19 ++++++++++++++++++- webserv/client/Client.hpp | 9 +++------ webserv/config/validation/ConfigValidator.cpp | 2 ++ webserv/handler/CgiEnvironment.cpp | 2 +- webserv/handler/FileHandler.cpp | 2 -- webserv/handler/RedirectHandler.cpp | 1 - webserv/socket/ClientSocket.cpp | 7 ++++++- webserv/socket/ClientSocket.hpp | 5 ++++- webserv/socket/ServerSocket.cpp | 9 +++++---- 9 files changed, 39 insertions(+), 17 deletions(-) diff --git a/webserv/client/Client.cpp b/webserv/client/Client.cpp index 2056608..2abffa5 100644 --- a/webserv/client/Client.cpp +++ b/webserv/client/Client.cpp @@ -20,6 +20,8 @@ #include // for move, pair #include // for vector +#include +#include #include // for send #include // for ssize_t @@ -183,4 +185,19 @@ HttpRequest &Client::getHttpRequest() const noexcept HttpResponse &Client::getHttpResponse() const noexcept { return *httpResponse_; -} \ No newline at end of file +} + +// NOLINTBEGIN +std::string Client::getClientAddress() const noexcept +{ + const struct sockaddr *addr = clientSocket_->getAddress(); + if (addr->sa_family == AF_INET) + { + const struct sockaddr_in *ipv4 = reinterpret_cast(addr); + const char *addr = inet_ntoa(ipv4->sin_addr); + return std::string(addr); + } + + return ""; +} +// NOLINTEND \ No newline at end of file diff --git a/webserv/client/Client.hpp b/webserv/client/Client.hpp index 54e89fc..5037d24 100644 --- a/webserv/client/Client.hpp +++ b/webserv/client/Client.hpp @@ -15,6 +15,7 @@ #include // for size_t #include // for unique_ptr +#include #include // for unordered_map class Server; @@ -41,20 +42,16 @@ class Client void respond() const; void poll() const; - // [[nodiscard]] int getStatusCode() const noexcept; - [[nodiscard]] ASocket &getSocket(int fd = -1) const; - // void setStatusCode(int code); - // void setCgiSockets(CgiSocket *cgiStdIn, CgiSocket *cgiStdOut); - // void removeCgiSocket(CgiSocket *cgiSocket); - void addSocket(ASocket *socket); void removeSocket(ASocket *socket); [[nodiscard]] HttpRequest &getHttpRequest() const noexcept; [[nodiscard]] HttpResponse &getHttpResponse() const noexcept; + [[nodiscard]] std::string getClientAddress() const noexcept; + private: // int statusCode_ = Http::StatusCode::OK; constexpr static size_t bufferSize_ = 8192; // 8KB buffer for reading CGI output diff --git a/webserv/config/validation/ConfigValidator.cpp b/webserv/config/validation/ConfigValidator.cpp index d252e41..b99bc6f 100644 --- a/webserv/config/validation/ConfigValidator.cpp +++ b/webserv/config/validation/ConfigValidator.cpp @@ -42,6 +42,8 @@ ConfigValidator::ConfigValidator(const GlobalConfig *config) : engine_(std::make engine_->addLocationRule("root", std::make_unique(true)); engine_->addLocationRule("cgi_ext", std::make_unique(false)); + // TODO: Add a validation rule for redirect + engine_->validate(); } diff --git a/webserv/handler/CgiEnvironment.cpp b/webserv/handler/CgiEnvironment.cpp index 8c2fe7a..9f7e94d 100644 --- a/webserv/handler/CgiEnvironment.cpp +++ b/webserv/handler/CgiEnvironment.cpp @@ -37,7 +37,7 @@ CgiEnvironment::CgiEnvironment(const URI &uri, const HttpRequest &request) env_["SERVER_NAME"] = host; env_["SERVER_PORT"] = std::to_string(port); - env_["REMOTE_ADDR"] = ""; // Placeholder, should be set to actual remote address + env_["REMOTE_ADDR"] = request.getClient().getClientAddress(); // Placeholder, should be set to actual remote address env_["REDIRECT_STATUS"] = "200"; // Required by PHP with force-cgi-redirect enabled env_["SERVER_SOFTWARE"] = "Webserv/1.0"; env_["REQUEST_SCHEME"] = "HTTP"; diff --git a/webserv/handler/FileHandler.cpp b/webserv/handler/FileHandler.cpp index 1b17b3d..d62123b 100644 --- a/webserv/handler/FileHandler.cpp +++ b/webserv/handler/FileHandler.cpp @@ -72,8 +72,6 @@ void FileHandler::handleDirectory(const std::string &dirpath, ResourceType type) if (type == DIRECTORY_AUTOINDEX) { Log::debug("Requested path is a directory: " + dirpath); - // ErrorHandler::createErrorResponse(Http::StatusCode::FORBIDDEN, response_, config_); - // TODO: This doesn't trigger for some reason :p (I Know why, i hacked the index in uri.cpp) response_.setBody(AutoIndex::generate(dirpath, uri_)); response_.setStatus(Http::StatusCode::OK); return; diff --git a/webserv/handler/RedirectHandler.cpp b/webserv/handler/RedirectHandler.cpp index 8dc8823..64ad9d3 100644 --- a/webserv/handler/RedirectHandler.cpp +++ b/webserv/handler/RedirectHandler.cpp @@ -27,7 +27,6 @@ void RedirectHandler::handle() "Found"; response_.setBody(body); - } } diff --git a/webserv/socket/ClientSocket.cpp b/webserv/socket/ClientSocket.cpp index cf18c1d..f7dbf95 100644 --- a/webserv/socket/ClientSocket.cpp +++ b/webserv/socket/ClientSocket.cpp @@ -3,7 +3,7 @@ #include // for LOCATION, Log #include // for ASocket -ClientSocket::ClientSocket(int fd) : ASocket(fd) +ClientSocket::ClientSocket(int fd, struct sockaddr address) : ASocket(fd), address_(address) { Log::trace(LOCATION); } @@ -12,3 +12,8 @@ ASocket::Type ClientSocket::getType() const noexcept { return ASocket::Type::CLIENT_SOCKET; } + +const struct sockaddr *ClientSocket::getAddress() const noexcept +{ + return &address_; +} \ No newline at end of file diff --git a/webserv/socket/ClientSocket.hpp b/webserv/socket/ClientSocket.hpp index d31be0d..78068f5 100644 --- a/webserv/socket/ClientSocket.hpp +++ b/webserv/socket/ClientSocket.hpp @@ -9,7 +9,10 @@ class ClientSocket : public ASocket { public: - explicit ClientSocket(int fd); + explicit ClientSocket(int fd, struct sockaddr address); [[nodiscard]] ASocket::Type getType() const noexcept override; + [[nodiscard]] const struct sockaddr *getAddress() const noexcept; + private: + struct sockaddr address_; }; \ No newline at end of file diff --git a/webserv/socket/ServerSocket.cpp b/webserv/socket/ServerSocket.cpp index afd90bc..f0756c3 100644 --- a/webserv/socket/ServerSocket.cpp +++ b/webserv/socket/ServerSocket.cpp @@ -1,8 +1,7 @@ -#include - #include // for Log, LOCATION #include // for ASocket #include // for ClientSocket +#include #include // for allocator, make_unique, unique_ptr #include // for runtime_error @@ -72,11 +71,13 @@ ASocket::Type ServerSocket::getType() const noexcept std::unique_ptr ServerSocket::accept() const { Log::trace(LOCATION); - int client_fd = ::accept(getFd(), nullptr, nullptr); + struct sockaddr client_address{}; + socklen_t address_len = sizeof(client_address); + int client_fd = ::accept(getFd(), &client_address, &address_len); if (client_fd < 0) { Log::error("Accept failed"); throw std::runtime_error("Accept failed"); } - return std::make_unique(client_fd); + return std::make_unique(client_fd, client_address); }