Decentralised Art Server
High-performance C++ backend that exposes HTML interface and a secure REST API for managing Performative Transactions entities
 
Loading...
Searching...
No Matches
route.hpp
Go to the documentation of this file.
1#pragma once
2#include <string>
3#include <functional>
4using namespace std::placeholders;
5
6#include <chrono>
7#include <memory>
8#include <utility>
9#include <regex>
10#include <vector>
11#include <cassert>
12
13#include "native.h"
14#include <asio.hpp>
15#include <absl/hash/hash.h>
16#include <absl/container/flat_hash_map.h>
17
18#include "http.hpp"
19
20#include "route_arg.hpp"
21#include "route_key.hpp"
22
23namespace dcn::server
24{
25 using QueryArgsList = absl::flat_hash_map<std::string, RouteArg>;
26
35 using StreamingHandlerDefinition = std::function<asio::awaitable<void>(
36 asio::ip::tcp::socket &,
37 const dcn::http::Request &,
38 std::vector<RouteArg>,
40 std::chrono::steady_clock::time_point &)>;
41
48 {
49 public:
50 enum class Kind
51 {
54 };
55
56 private:
57 class Base
58 {
59 public:
60 virtual ~Base() = default;
61 };
62
63 template<typename... Args>
64 struct Wrapper : public Base
65 {
66 Wrapper(std::function<asio::awaitable<http::Response>(Args...)> func)
67 : function(std::move(func))
68 {}
69
70 std::function<asio::awaitable<http::Response>(Args...)> function;
71 };
72
73 public:
74
75 template<typename... Args>
76 RouteHandlerFunc(std::function<asio::awaitable<http::Response>(Args...)> func)
77 : _kind(Kind::Response),
78 _base(std::make_unique<Wrapper<Args...>>(std::move(func)))
79 {}
80
82 : _kind(Kind::Streaming),
83 _streaming(std::move(func))
84 {}
85
87
88 Kind kind() const { return _kind; }
89
90 template<typename... Args>
91 asio::awaitable<http::Response> operator()(Args && ... args) const
92 {
93 Wrapper<Args...>* wrapper_ptr = dynamic_cast<Wrapper<Args...>*>(_base.get());
94
95 if(wrapper_ptr)
96 {
97 co_return co_await wrapper_ptr->function(std::forward<Args>(args)...);
98 }
99 else
100 {
101 throw std::runtime_error("Invalid arguments to function object call!");
102 }
103 }
104
105 asio::awaitable<void> invokeStreaming(
106 asio::ip::tcp::socket & sock,
107 const http::Request & request,
108 std::vector<RouteArg> route_args,
109 QueryArgsList query_args,
110 std::chrono::steady_clock::time_point & deadline) const
111 {
112 if(_kind != Kind::Streaming || !_streaming)
113 {
114 throw std::runtime_error("RouteHandlerFunc::invokeStreaming called on non-streaming handler");
115 }
116 co_await _streaming(sock, request, std::move(route_args), std::move(query_args), deadline);
117 }
118
119 private:
120 Kind _kind;
121 std::unique_ptr<Base> _base;
123 };
124
130 class Router
131 {
132 public:
133 Router() = default;
134 ~Router() = default;
135
136 void addRoute(RouteKey route, RouteHandlerFunc handler);
137
138 std::tuple<const RouteHandlerFunc *, std::vector<RouteArg>, QueryArgsList> findRoute(const http::Request & request) const;
139 protected:
140 std::tuple<bool, std::vector<RouteArg>, QueryArgsList> doesRouteMatch(
141 const RouteKey & route,
142 const http::Method & request_method,
143 const std::string & module_path,
144 const std::vector<std::string> & request_path_info_segments,
145 const absl::flat_hash_map<std::string, std::string> request_query_segments) const;
146
147 private:
148 absl::flat_hash_map<RouteKey, RouteHandlerFunc> _routes;
149 };
150}
Definition http.hpp:110
A class representing a route handler function.
Definition route.hpp:48
asio::awaitable< http::Response > operator()(Args &&... args) const
Definition route.hpp:91
Kind
Definition route.hpp:51
RouteHandlerFunc(std::function< asio::awaitable< http::Response >(Args...)> func)
Definition route.hpp:76
RouteHandlerFunc(StreamingHandlerDefinition func)
Definition route.hpp:81
Kind kind() const
Definition route.hpp:88
asio::awaitable< void > invokeStreaming(asio::ip::tcp::socket &sock, const http::Request &request, std::vector< RouteArg > route_args, QueryArgsList query_args, std::chrono::steady_clock::time_point &deadline) const
Definition route.hpp:105
RouteHandlerFunc(RouteHandlerFunc &&other)=default
A class representing a route key, which is a combination of a HTTP method and a URL.
Definition route_key.hpp:20
A class representing a router for handling HTTP requests.
Definition route.hpp:131
std::tuple< bool, std::vector< RouteArg >, QueryArgsList > doesRouteMatch(const RouteKey &route, const http::Method &request_method, const std::string &module_path, const std::vector< std::string > &request_path_info_segments, const absl::flat_hash_map< std::string, std::string > request_query_segments) const
Definition route.cpp:5
void addRoute(RouteKey route, RouteHandlerFunc handler)
Definition route.cpp:153
std::tuple< const RouteHandlerFunc *, std::vector< RouteArg >, QueryArgsList > findRoute(const http::Request &request) const
Definition route.cpp:122
Method
Enum to represent the request method.
Definition http_method.hpp:31
Definition route.hpp:24
std::function< asio::awaitable< void >(asio::ip::tcp::socket &, const dcn::http::Request &, std::vector< RouteArg >, QueryArgsList, std::chrono::steady_clock::time_point &)> StreamingHandlerDefinition
Streaming handler signature.
Definition route.hpp:40
absl::flat_hash_map< std::string, RouteArg > QueryArgsList
Definition route.hpp:25