22 #ifndef _LIBS_WEBVIEW_ROUTER_H_ 23 #define _LIBS_WEBVIEW_ROUTER_H_ 25 #include <core/exceptions/software.h> 26 #include <webview/request.h> 57 std::find_if(routes_.begin(), routes_.end(), [
this, &path_args, request](
auto &r) ->
bool {
59 return (std::get<1>(r) == request->
method()
60 && this->path_match(request->
url(), std::get<3>(r), path_args));
62 if (ri == routes_.end()) {
65 return std::get<4>(*ri);
78 const std::string & path,
79 std::map<std::string, std::string> &path_args)
81 auto ri = std::find_if(
82 routes_.begin(), routes_.end(), [
this, &path_args, &method, &path](
auto &r) ->
bool {
83 return (std::get<1>(r) == method && this->path_match(path, std::get<3>(r), path_args));
85 if (ri == routes_.end()) {
88 return std::get<4>(*ri);
106 std::find_if(routes_.begin(), routes_.end(), [method, &path, &weight](
auto &r) ->
bool {
107 return (std::get<0>(r) == weight && std::get<1>(r) == method && std::get<2>(r) == path);
109 if (ri != routes_.end()) {
110 throw Exception(
"URL handler already registered for %s", path.c_str());
112 routes_.push_back(std::make_tuple(weight, method, path, gen_regex(path), handler));
114 [](
const auto &a,
const auto &b) ->
bool {
return (std::get<0>(a) < std::get<0>(b)); });
129 add(method, path, handler, 0);
139 auto ri = std::find_if(routes_.begin(), routes_.end(), [method, &path](
auto &r) ->
bool {
140 return (std::get<1>(r) == method && std::get<2>(r) == path);
142 if (ri != routes_.end()) {
148 typedef std::pair<std::regex, std::vector<std::string>> path_regex;
150 std::pair<std::regex, std::vector<std::string>>
151 gen_regex(
const std::string &path)
153 std::string::size_type pos = 0;
155 if (path[0] !=
'/') {
156 throw Exception(
"Path '%s' must start with /", path.c_str());
158 if ((pos = path.find_first_of(
"[]()^$")) != std::string::npos) {
159 throw Exception(
"Found illegal character '%c' at position '%zu' in '%s'",
165 std::regex to_re(
"\\{([^+*\\}]+?)[+*]?\\}");
166 std::string m_path = path;
169 while ((pos = m_path.find_first_of(
".", pos)) != std::string::npos) {
170 m_path.replace(pos, 1,
"\\.");
174 while ((pos = m_path.find_first_of(
"+*", pos)) != std::string::npos) {
175 if (pos < m_path.length() - 1 && m_path[pos + 1] !=
'}') {
176 m_path.replace(pos, 1, std::string(
"\\") + m_path[pos]);
184 std::vector<std::string> match_indexes;
185 while (regex_search(m_path, match, to_re)) {
186 std::string full_match = match[0];
187 re_url += match.prefix();
188 if (full_match[full_match.length() - 2] ==
'+') {
190 }
else if (full_match[full_match.length() - 2] ==
'*') {
193 re_url +=
"([^/]+?)";
195 match_indexes.push_back(match[1]);
196 m_path = match.suffix();
201 return std::make_pair(std::regex(re_url), match_indexes);
211 path_match(
const std::string & url,
212 const path_regex & path_re,
213 std::map<std::string, std::string> &path_args)
216 if (std::regex_match(url, matches, path_re.first)) {
217 if (matches.size() != path_re.second.size() + 1) {
220 for (
size_t i = 0; i < path_re.second.size(); ++i) {
222 path_args[path_re.second[i]] = matches[i + 1].str();
231 std::list<std::tuple<int, WebRequest::Method, std::string, path_regex, T>> routes_;
void add(WebRequest::Method method, const std::string &path, T handler)
Add a handler.
void add(WebRequest::Method method, const std::string &path, T handler, int weight)
Add a handler with weight.
Fawkes library namespace.
A NULL pointer was supplied where not allowed.
Method method() const
Get HTTP transfer method.
Base class for exceptions in Fawkes.
Web request meta data carrier.
void remove(WebRequest::Method method, const std::string &path)
Remove a handler.
T & find_handler(const WebRequest *request, std::map< std::string, std::string > &path_args)
Find a handler.
const std::string & url() const
Get URL.
Method
HTTP transfer methods.
T & find_handler(WebRequest::Method method, const std::string &path, std::map< std::string, std::string > &path_args)
Find a handler.