136 lines
3.7 KiB
C++
136 lines
3.7 KiB
C++
namespace seafire::resources
|
|
{
|
|
|
|
void
|
|
handle(server::request_t& req,
|
|
server::response_t& res,
|
|
Resource auto const& r)
|
|
{
|
|
using resource_traits = traits::resource_traits<std::decay_t<decltype(r)>>;
|
|
|
|
auto const not_allowed = [&req, &res]
|
|
{
|
|
set<protocol::rfc7231::allow_t>(res, resource_traits::allowed_methods());
|
|
res.send(server::common_error_t::method_not_allowed);
|
|
};
|
|
|
|
auto const& method = req.get_message().method();
|
|
|
|
// GET
|
|
//
|
|
if (method == "GET" || method == "HEAD") {
|
|
if constexpr (resource_traits::is_gettable) {
|
|
negotiate<typename resource_traits::get_representation_type>(
|
|
req,
|
|
res,
|
|
[&req, &res, &r](std::optional<protocol::media_type_t> const& accepted_type)
|
|
{
|
|
handle_get(
|
|
req,
|
|
res,
|
|
r,
|
|
accepted_type,
|
|
req.get_message().method() == "HEAD" ? get_kind_t::head : get_kind_t::get
|
|
);
|
|
}
|
|
);
|
|
|
|
return;
|
|
}
|
|
else {
|
|
not_allowed();
|
|
}
|
|
}
|
|
|
|
// PUT (update)
|
|
//
|
|
else if (method == "PUT") {
|
|
if constexpr (resource_traits::is_updatable) {
|
|
if constexpr (std::is_same_v<void, typename resource_traits::update_result_type>) {
|
|
handle_update(req, res, r, std::nullopt);
|
|
}
|
|
else if constexpr (representation::Representation<typename resource_traits::update_result_type>) {
|
|
negotiate<typename resource_traits::update_result_type>(
|
|
req,
|
|
res,
|
|
[&req, &res, &r](std::optional<protocol::media_type_t> const& accepted_type)
|
|
{
|
|
handle_update(req, res, r, accepted_type);
|
|
}
|
|
);
|
|
}
|
|
else {
|
|
negotiate<typename traits::resource_traits<typename resource_traits::update_result_type>::get_representation_type>(
|
|
req,
|
|
res,
|
|
[&req, &res, &r](std::optional<protocol::media_type_t> const& accepted_type)
|
|
{
|
|
handle_update(req, res, r, accepted_type);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
not_allowed();
|
|
}
|
|
}
|
|
|
|
// POST (create)
|
|
//
|
|
else if (method == "POST") {
|
|
if constexpr (resource_traits::is_creatable) {
|
|
if constexpr (std::is_same_v<void, typename resource_traits::update_result_type>) {
|
|
handle_create(req, res, r, std::nullopt);
|
|
}
|
|
else if constexpr (representation::Representation<typename resource_traits::create_result_type>) {
|
|
negotiate<typename resource_traits::create_result_type>(
|
|
req,
|
|
res,
|
|
[&req, &res, &r](std::optional<protocol::media_type_t> const& accepted_type)
|
|
{
|
|
handle_create(req, res, r, accepted_type);
|
|
}
|
|
);
|
|
}
|
|
else {
|
|
using one = typename resource_traits::create_result_type;
|
|
using two = typename traits::resource_traits<one>::get_representation_type;
|
|
//using resource_traits = traits::resource_traits<
|
|
negotiate<two>(
|
|
req,
|
|
res,
|
|
[&req, &res, &r](std::optional<protocol::media_type_t> const& accepted_type)
|
|
{
|
|
handle_create(req, res, r, accepted_type);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
not_allowed();
|
|
}
|
|
}
|
|
|
|
// DELETE
|
|
//
|
|
else if (method == "DELETE") {
|
|
#if 0
|
|
if constexpr (resource_traits::is_erasable) {
|
|
handle_erase(tx, r);
|
|
return;
|
|
}
|
|
else {
|
|
not_allowed();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// method not implemented.
|
|
//
|
|
else {
|
|
res.send(server::common_error_t::not_implemented);
|
|
}
|
|
}
|
|
|
|
} // namespace seafire::resources
|