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
|