Rewrite middleware to support epoll

This commit is contained in:
2019-06-29 12:46:29 +02:00
parent 72a6a745ff
commit 4d90d18660
27 changed files with 670 additions and 318 deletions

View File

@@ -0,0 +1,96 @@
#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;
}
}