#include "middleware.hpp" #include "notfound.hpp" #include "staticcontent.hpp" #include "unimplemented.hpp" #include namespace Middleware { MiddlewareResult::MiddlewareResult(bool const _writeResult, int const _socketFd) : writeResult(_writeResult), socketFd(_socketFd) { } Middleware::Middleware(Logger & _logger) : logger(_logger) { } MiddlewareResult Middleware::Loop(State & state, ScheduleHelper & scheduleHelper) { for(size_t i = state.middlewareIndex; i < middlewares.size(); ++i) { middlewares[i]->HandleRequest(state, scheduleHelper); if (state.finished) { break; } if (state.awaiting) { state.middlewareIndex = i; eventFdToSocketFdMap[state.awaitingFd] = state.socketFd; return MiddlewareResult (false, state.socketFd); } } int const socketFd = state.socketFd; auto stateResult = socketFdToStateMap.find(socketFd); if (stateResult != socketFdToStateMap.end()) { socketFdToStateMap.erase(stateResult); // The state parameter is now invalid!! } return MiddlewareResult(true, socketFd); } MiddlewareResult Middleware::Start(int const socketFd, ScheduleHelper & scheduleHelper, Http::Request const & request, Http::Response & response) { auto & statePtr = socketFdToStateMap[socketFd]; statePtr = std::make_unique(socketFd, request, response); return Loop(*statePtr, scheduleHelper); } MiddlewareResult Middleware::Continue(int const fd, ScheduleHelper & scheduleHelper) { auto socketFdResult = eventFdToSocketFdMap.find(fd); if (socketFdResult == eventFdToSocketFdMap.end()) { close(fd); logger.Warning("Dangeling filedescriptor closed in middleware"); return MiddlewareResult(false, -1); } int const socketFd = socketFdResult->second; eventFdToSocketFdMap.erase(socketFdResult); auto stateResult = socketFdToStateMap.find(socketFd); if (stateResult == socketFdToStateMap.end()) { close(fd); close(socketFd); logger.Warning("Stateless socket file descriptor and associated event file descriptor closed"); return MiddlewareResult(false, -1); } return Loop(*(stateResult->second), scheduleHelper); } void Middleware::UseMiddleware(std::unique_ptr && middleware) { middlewares.emplace_back(std::move(middleware)); } Middleware Middleware::CreateWithStaticFile(Logger & logger, std::string const & rootDirectory) { Middleware middleware(logger); middleware.UseMiddleware(std::make_unique(logger, rootDirectory)); middleware.UseMiddleware(std::make_unique(logger)); middleware.UseMiddleware(std::make_unique(logger)); return middleware; } }