96 lines
2.6 KiB
C++
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;
|
|
}
|
|
} |