103 lines
2.1 KiB
C++
Raw Normal View History

2025-03-07 02:25:54 +01:00
#include <seafire/routing/router.hxx>
#include <seafire/routing/diagnostics.hxx>
namespace seafire::routing
{
static
std::string
normalize_path(std::string const& path)
{
std::stringstream ipath{path};
std::vector<std::string> segments;
for (std::string segment; std::getline(ipath, segment, '/');) {
if (segment.empty()) {
continue;
}
if (segment == ".") {
continue;
}
if (segment == "..") {
if (!segments.empty()) {
segments.pop_back();
}
continue;
}
segments.push_back(segment);
}
std::string normalized;
for (auto const& j : segments) {
normalized += '/';
normalized += j;
}
return normalized.empty() ? "/" : normalized;
}
router_t::
router_t(common::diagnostics_t& diagnostics, routing_table_t table)
: diagnostics_{diagnostics}, rt_{std::move(table)}
{}
routing_table_t const&
router_t::
routing_table() const
{
return rt_;
}
void
router_t::
on_request(server::request_t& req, server::response_t& res) const
{
trace() << "on_request(...)";
auto path = normalize_path(req.get_message().target_uri().path_str());
trace() << "locating endpoint for [" << path << "]";
auto result = routing_table().find_route(path);
if (!result) {
trace() << "endpoint for [" << path << "] not found";
res.send(server::common_error_t::not_found);
return;
}
auto trace_endpoint = [&result](common::diagnostics_t::proxy_t proxy)
{
proxy << "endpoint found";
for (auto const& j : result->params.map())
proxy << "\n -> " << j.first << " = " << j.second << '\n';
};
trace_endpoint(trace());
req.extensions().extend(&res.memory().alloc(result->params));
result->handler.invoke(req, res);
}
void
router_t::
operator()(server::request_t& req, server::response_t& res) const
{
on_request(req, res);
}
common::diagnostics_t::proxy_t
router_t::
trace() const
{
return diagnostics_ << routing_category();
}
} // namespace seafire::routing