Rewrite middleware to support epoll
This commit is contained in:
96
src/middleware/middleware.cpp
Normal file
96
src/middleware/middleware.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user