103 lines
2.1 KiB
C++
103 lines
2.1 KiB
C++
|
#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
|