Files
http-server/src/middleware/middleware.cpp

96 lines
2.6 KiB
C++

#include "middleware.hpp"
#include "notfound.hpp"
#include "staticcontent.hpp"
#include "unimplemented.hpp"
#include <unistd.h>
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<State>(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<BaseMiddleware> && middleware)
{
middlewares.emplace_back(std::move(middleware));
}
Middleware Middleware::CreateWithStaticFile(Logger & logger, std::string const & rootDirectory)
{
Middleware middleware(logger);
middleware.UseMiddleware(std::make_unique<StaticContent>(logger, rootDirectory));
middleware.UseMiddleware(std::make_unique<NotFound>(logger));
middleware.UseMiddleware(std::make_unique<Unimplemented>(logger));
return middleware;
}
}