diff --git a/webserv-tester b/webserv-tester index 1daf3e5..0a4c692 160000 --- a/webserv-tester +++ b/webserv-tester @@ -1 +1 @@ -Subproject commit 1daf3e55aa913c8d5120a942b2513ca36d7309ac +Subproject commit 0a4c692fc618e0b8d26a8e6d9079c22c74345834 diff --git a/webserv/router/Router.cpp b/webserv/router/Router.cpp index cf5854b..a527cf0 100644 --- a/webserv/router/Router.cpp +++ b/webserv/router/Router.cpp @@ -1,19 +1,17 @@ -#include // for Router - -#include -#include - #include // for Client #include // for AConfig #include // for ADirective #include // for DirectiveValue #include // for CgiHandler #include // for CgiProcess -#include // for FileHandler -#include // for URI -#include // for HttpRequest -#include // for Log, LOCATION -#include // for RedirectHandler +#include +#include // for FileHandler +#include // for RedirectHandler +#include // for URI +#include // for HttpRequest +#include +#include // for Log, LOCATION +#include // for Router #include // for exception #include // for unique_ptr, make_unique @@ -46,7 +44,7 @@ std::unique_ptr Router::handleRequest() HttpRequest &request = client_->getHttpRequest(); HttpResponse &response = client_->getHttpResponse(); - + const AConfig *config = request.getUri().getConfig(); auto validator = std::make_unique(config, &request); @@ -70,6 +68,9 @@ std::unique_ptr Router::handleRequest() catch (const std::exception &e) { Log::error("CGI process failed: " + std::string(e.what())); + // Ensure we return an error response instead of a null handler to avoid hanging/connection drops + ErrorHandler::createErrorResponse(500, response, config); + return nullptr; } } else diff --git a/webserv/server/Server.cpp b/webserv/server/Server.cpp index a56ccc7..4e7c18b 100644 --- a/webserv/server/Server.cpp +++ b/webserv/server/Server.cpp @@ -241,9 +241,52 @@ void Server::handleEvent(struct epoll_event *event) Log::trace(LOCATION); if ((event->events & EPOLLERR) > 0) { - Log::error("Epoll error on fd " + std::to_string(event->data.fd) + ": " + std::strerror(errno)); - remove(getListener(event->data.fd)); - close(event->data.fd); + int fd = event->data.fd; + Log::error("Epoll error on fd " + std::to_string(fd) + ": " + std::strerror(errno)); + // If this is a listener socket, remove just that listener + if (listener_fds_.contains(fd)) + { + try + { + remove(getListener(fd)); + } + catch (const std::exception &e) + { + Log::warning(std::string("Failed to remove listener on EPOLLERR: ") + e.what()); + } + close(fd); + listener_fds_.erase(fd); + } + else + { + // Non-listener sockets: resolve to client/socket and handle gracefully + try + { + Client &client = getClient(fd); + ASocket &socket = client.getSocket(fd); + if (socket.getType() == ASocket::Type::CGI_SOCKET) + { + Log::info("EPOLLERR on CGI socket fd " + std::to_string(fd) + ", invoking callback"); + socket.callback(); + } + else if (socket.getType() == ASocket::Type::CLIENT_SOCKET) + { + Log::warning("EPOLLERR on client socket fd " + std::to_string(fd) + ", disconnecting client"); + disconnect(client); + } + else + { + Log::warning("EPOLLERR on auxiliary socket fd " + std::to_string(fd) + ", removing"); + remove(socket); + close(fd); + } + } + catch (const std::exception &e) + { + Log::warning(std::string("EPOLLERR on unknown/non-tracked fd, closing: ") + e.what()); + close(fd); + } + } return; } if ((event->events & EPOLLHUP) > 0)