85 lines
1.6 KiB
C++
85 lines
1.6 KiB
C++
#ifndef seafire__server__middleware_hxx_
|
|
#define seafire__server__middleware_hxx_
|
|
|
|
#include <seafire/server/request-handler.hxx>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace seafire::server
|
|
{
|
|
|
|
/// Implements middleware functionality.
|
|
///
|
|
class middleware_t
|
|
{
|
|
public:
|
|
template<typename T>
|
|
middleware_t(T handler)
|
|
: handler_{std::make_shared<container_t<T>>(std::move(handler))}
|
|
{}
|
|
|
|
void
|
|
invoke(request_t&, response_t&, request_handler_t const&) const;
|
|
|
|
template<typename, typename... Args>
|
|
friend
|
|
middleware_t
|
|
make_middleware(Args&&...);
|
|
|
|
private:
|
|
struct concept_t
|
|
{
|
|
virtual
|
|
~concept_t() noexcept = default;
|
|
|
|
virtual
|
|
void
|
|
invoke(request_t&, response_t&, request_handler_t const&) const = 0;
|
|
|
|
};
|
|
|
|
template<typename T>
|
|
struct container_t
|
|
: concept_t
|
|
{
|
|
template<typename... Args>
|
|
container_t(Args&&... args)
|
|
: handler{std::forward<Args>(args)...}
|
|
{}
|
|
|
|
void
|
|
invoke(request_t& req,
|
|
response_t& res,
|
|
request_handler_t const& next) const override
|
|
{
|
|
handler(req, res, next);
|
|
}
|
|
|
|
T handler;
|
|
|
|
};
|
|
|
|
explicit
|
|
middleware_t(std::shared_ptr<concept_t const>);
|
|
|
|
std::shared_ptr<concept_t const> handler_;
|
|
|
|
};
|
|
|
|
template<typename T, typename... Args>
|
|
middleware_t
|
|
make_middleware(Args&&... args)
|
|
{
|
|
return middleware_t{
|
|
std::make_shared<middleware_t::container_t<T>>(std::forward<Args>(args)...)
|
|
};
|
|
}
|
|
|
|
request_handler_t
|
|
make_middleware(std::vector<middleware_t> const&, request_handler_t);
|
|
|
|
} // namespace seafire::server
|
|
|
|
#endif
|