6 #include <unordered_map> 8 #include <boost/lexical_cast.hpp> 46 #ifdef CROW_ENABLE_SSL 75 namespace routing_handler_call_helper
77 template <
typename T,
int Pos>
81 static const int pos = Pos;
84 template <
typename H1>
93 template <
typename F,
int NInt,
int NU
int,
int NDouble,
int NString,
typename S1,
typename S2>
98 template <
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename ... Args1,
typename ... Args2>
99 struct call<
F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>,
black_magic::S<Args2...>>
103 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<int64_t, NInt>>;
104 call<
F, NInt+1, NUint, NDouble, NString,
109 template <
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename ... Args1,
typename ... Args2>
110 struct call<
F, NInt, NUint, NDouble, NString, black_magic::S<uint64_t, Args1...>,
black_magic::S<Args2...>>
114 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<uint64_t, NUint>>;
115 call<
F, NInt, NUint+1, NDouble, NString,
120 template <
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename ... Args1,
typename ... Args2>
125 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<double, NDouble>>;
126 call<
F, NInt, NUint, NDouble+1, NString,
131 template <
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename ... Args1,
typename ... Args2>
132 struct call<
F, NInt, NUint, NDouble, NString, black_magic::S<std::string, Args1...>,
black_magic::S<Args2...>>
136 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<std::string, NString>>;
137 call<
F, NInt, NUint, NDouble, NString+1,
142 template <
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename ... Args1>
150 cparams.params.template get<typename Args1::type>(Args1::pos)...
155 template <
typename Func,
typename ... ArgsWrapped>
158 template <
typename ... Args>
159 void set2(Func f,
typename std::enable_if<
160 !std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::
type,
const request&>::value
164 #ifdef CROW_CAN_USE_CPP14 175 template <
typename Req,
typename ... Args>
192 template <
typename ... Args>
193 void set2(Func f,
typename std::enable_if<
194 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::
type,
const request&>::value &&
195 !std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::
type,
response&>::value
207 template <
typename ... Args>
208 void set2(Func f,
typename std::enable_if<
209 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::
type,
const request&>::value &&
210 std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::
type,
response&>::value
216 template <
typename ... Args>
223 template <
typename ... Args>
230 template <
typename ... Args>
281 #ifdef CROW_ENABLE_SSL 288 template <
typename Func>
295 template <
typename Func>
302 template <
typename Func>
309 template <
typename Func>
318 std::function<void(crow::websocket::connection&, const std::string&, bool)>
message_handler_;
319 std::function<void(crow::websocket::connection&, const std::string&)>
close_handler_;
323 template <
typename T>
330 ((
self_t*)
this)->rule_to_upgrade_.reset(p);
346 template <
typename ... MethodArgs>
350 ((
self_t*)
this)->methods_ |= 1 << (int)method;
369 throw std::runtime_error(
name_ + (!
name_.empty() ?
": " :
"") +
"no handler for url " +
rule_);
378 template <
typename Func>
381 #ifdef CROW_MSVC_WORKAROUND 392 #ifdef CROW_MSVC_WORKAROUND 393 template <
typename Func,
size_t ... Indices>
395 template <
typename Func,
unsigned ... Indices>
397 std::function<void(const request&, response&, const routing_params&)>
400 #ifdef CROW_MSVC_WORKAROUND 408 typename function_t::template arg<Indices>...>::value))
410 throw std::runtime_error(
"route_dynamic: Handler type is mismatched with URL parameters: " +
rule_);
413 ret.template set2<typename function_t::template arg<Indices>...>(std::move(f));
417 template <
typename Func>
421 (*this).template operator()<Func>(std::forward(f));
424 std::function<void(const request&, response&, const routing_params&)>
erased_handler_;
428 template <
typename ... Args>
443 throw std::runtime_error(
name_ + (!
name_.empty() ?
": " :
"") +
"no handler for url " +
rule_);
447 template <
typename Func>
453 "Handler type is mismatched with URL parameters");
454 static_assert(!std::is_same<
void, decltype(f(std::declval<Args>()...))>::value,
455 "Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
463 template <
typename Func>
464 typename std::enable_if<
472 "Handler type is mismatched with URL parameters");
473 static_assert(!std::is_same<
void, decltype(f(std::declval<crow::request>(), std::declval<Args>()...))>::value,
474 "Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
482 template <
typename Func>
483 typename std::enable_if<
493 "Handler type is mismatched with URL parameters");
494 static_assert(std::is_same<
void, decltype(f(std::declval<crow::request>(), std::declval<crow::response&>(), std::declval<Args>()...))>::value,
495 "Handler function with response argument should have void return type");
500 template <
typename Func>
504 (*this).template operator()<Func>(std::forward(f));
536 std::unordered_map<std::string, unsigned>
children;
545 [](
unsigned x){
return !x; });
556 for(
auto x :
node->param_childrens)
563 if (
node->children.empty())
565 bool mergeWithChild =
true;
566 for(
auto& kv :
node->children)
571 mergeWithChild =
false;
577 decltype(
node->children) merged;
578 for(
auto& kv :
node->children)
581 for(
auto& child_kv : child->
children)
583 merged[kv.first + child_kv.first] = child_kv.second;
586 node->children = std::move(merged);
591 for(
auto& kv :
node->children)
607 if (!
head()->IsSimpleNode())
608 throw std::runtime_error(
"Internal error: Trie header should be simple!");
612 std::pair<unsigned, routing_params>
find(
const std::string& req_url,
const Node*
node =
nullptr,
unsigned pos = 0,
routing_params* params =
nullptr)
const 615 if (params ==
nullptr)
623 if (pos == req_url.size())
624 return {
node->rule_index, *params};
626 auto update_found = [&found, &match_params](std::pair<unsigned, routing_params>& ret)
628 if (ret.first && (!found || found > ret.first))
631 match_params = std::move(ret.second);
637 char c = req_url[pos];
638 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-')
642 long long int value = strtoll(req_url.data()+pos, &eptr, 10);
643 if (errno != ERANGE && eptr != req_url.data()+pos)
645 params->int_params.push_back(value);
648 params->int_params.pop_back();
655 char c = req_url[pos];
656 if ((c >=
'0' && c <=
'9') || c ==
'+')
660 unsigned long long int value = strtoull(req_url.data()+pos, &eptr, 10);
661 if (errno != ERANGE && eptr != req_url.data()+pos)
663 params->uint_params.push_back(value);
666 params->uint_params.pop_back();
673 char c = req_url[pos];
674 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-' || c ==
'.')
678 double value = strtod(req_url.data()+pos, &eptr);
679 if (errno != ERANGE && eptr != req_url.data()+pos)
681 params->double_params.push_back(value);
684 params->double_params.pop_back();
692 for(; epos < req_url.size(); epos ++)
694 if (req_url[epos] ==
'/')
700 params->string_params.push_back(req_url.substr(pos, epos-pos));
703 params->string_params.pop_back();
709 size_t epos = req_url.size();
713 params->string_params.push_back(req_url.substr(pos, epos-pos));
716 params->string_params.pop_back();
720 for(
auto& kv :
node->children)
722 const std::string& fragment = kv.first;
725 if (req_url.compare(pos, fragment.size(), fragment) == 0)
727 auto ret =
find(req_url, child, pos + fragment.size(), params);
732 return {found, match_params};
735 void add(
const std::string& url,
unsigned rule_index)
739 for(
unsigned i = 0; i < url.size(); i ++)
744 static struct ParamTraits
759 for(
auto& x:paramTraits)
761 if (url.compare(i, x.name.size(), x.name) == 0)
763 if (!
nodes_[idx].param_childrens[(
int)x.type])
766 nodes_[idx].param_childrens[(int)x.type] = new_node_idx;
768 idx =
nodes_[idx].param_childrens[(int)x.type];
778 std::string piece(&c, 1);
779 if (!
nodes_[idx].children.count(piece))
782 nodes_[idx].children.emplace(piece, new_node_idx);
784 idx =
nodes_[idx].children[piece];
787 if (
nodes_[idx].rule_index)
788 throw std::runtime_error(
"handler already exists for " + url);
789 nodes_[idx].rule_index = rule_index;
873 template <u
int64_t N>
877 auto ruleObject =
new RuleT(rule);
886 rules_.emplace_back(ruleObject);
891 if (rule.size() > 1 && rule.back() ==
'/')
893 std::string rule_without_trailing_slash = rule;
894 rule_without_trailing_slash.pop_back();
906 auto upgraded = rule->upgrade();
908 rule = std::move(upgraded);
914 template <
typename Adaptor>
918 unsigned rule_index = found.first;
927 if (rule_index >=
rules_.size())
928 throw std::runtime_error(
"Trie internal structure corrupted!");
948 if ((
rules_[rule_index]->get_methods() & (1<<(uint32_t)req.
method)) == 0)
961 rules_[rule_index]->handle_upgrade(req, res, std::move(adaptor));
963 catch(std::exception& e)
972 CROW_LOG_ERROR <<
"An uncaught exception occurred. The type was unknown so no information was available.";
983 unsigned rule_index = found.first;
994 if (rule_index >=
rules_.size())
995 throw std::runtime_error(
"Trie internal structure corrupted!");
1015 if ((
rules_[rule_index]->get_methods() & (1<<(uint32_t)req.
method)) == 0)
1028 rules_[rule_index]->handle(req, res, found.second);
1030 catch(std::exception& e)
1032 CROW_LOG_ERROR <<
"An uncaught exception occurred: " << e.what();
1039 CROW_LOG_ERROR <<
"An uncaught exception occurred. The type was unknown so no information was available.";
1052 std::vector<std::unique_ptr<BaseRule>>
rules_;
Definition: http_response.h:12
std::function< void(crow::websocket::connection &, const std::string &)> close_handler_
Definition: routing.h:319
std::function< void(const crow::request &, crow::response &, Args...)> type
Definition: routing.h:219
void handle_upgrade(const request &req, response &, SocketAdaptor &&adaptor) override
Definition: routing.h:277
void operator()(std::string name, Func &&f)
Definition: routing.h:501
uint32_t get_methods()
Definition: routing.h:54
TaggedRule(std::string rule)
Definition: routing.h:434
void operator()(const request &req, response &res, const routing_params ¶ms)
Definition: routing.h:239
black_magic::arguments< N >::type::template rebind< TaggedRule > & new_rule_tagged(const std::string &rule)
Definition: routing.h:874
Definition: socket_adaptors.h:12
const Node * head() const
Definition: routing.h:838
uint32_t methods_
Definition: routing.h:60
const uint32_t T[512]
Definition: groestl_tables.h:34
Definition: routing.h:324
virtual void handle_upgrade(const request &, response &res, SocketAdaptor &&)
Definition: routing.h:41
virtual void validate()=0
unsigned new_node()
Definition: routing.h:848
Definition: http_request.h:23
Func f
Definition: routing.h:189
const request & req
Definition: routing.h:89
#define F(w, k)
Definition: sha512-blocks.c:61
T type
Definition: routing.h:80
Definition: routing.h:429
boost::make_recursive_variant< std::nullptr_t, std::string, int, double, bool, uint64_t, int64_t, uint32_t, internal::lambda_t< boost::recursive_variant_ >, std::shared_ptr< internal::object_t< boost::recursive_variant_ > >, internal::map< const std::string, boost::recursive_variant_ >, std::vector< boost::recursive_variant_ > >::type node
Definition: mstch.hpp:116
self_t & onmessage(Func f)
Definition: routing.h:296
Definition: routing.h:857
std::function< void(const crow::request &, crow::response &, Args...)> type
Definition: routing.h:233
void validate() override
Definition: routing.h:439
self_t & onerror(Func f)
Definition: routing.h:310
virtual ~BaseRule()
Definition: routing.h:28
void operator()(F cparams)
Definition: routing.h:134
Definition: routing.h:529
const int RULE_SPECIAL_REDIRECT_SLASH
Definition: routing.h:527
void optimizeNode(Node *node)
Definition: routing.h:554
Definition: block_queue.cpp:41
std::vector< std::unique_ptr< BaseRule > > rules_
Definition: routing.h:1052
Definition: routing.h:176
void operator()(Func f)
Definition: routing.h:379
std::unique_ptr< BaseRule > upgrade()
Definition: routing.h:33
void validate() override
Definition: routing.h:365
void validate() override
Definition: routing.h:267
void operator()(const request &req, response &res, Args... args)
Definition: routing.h:183
Definition: utility.h:237
Trie trie_
Definition: routing.h:1053
void handle_upgrade(const request &req, response &res, Adaptor &&adaptor)
Definition: routing.h:915
Definition: websocket.h:28
std::function< void(crow::websocket::connection &)> error_handler_
Definition: routing.h:320
const std::string & get_header_value(const std::string &key) const
Definition: http_request.h:50
ParamType
Definition: common.h:58
void set2(Func f, typename std::enable_if< !std::is_same< typename std::tuple_element< 0, std::tuple< Args..., void >>::type, const request &>::value, int >::type=0)
Definition: routing.h:159
std::function< void(crow::websocket::connection &, const std::string &, bool)> message_handler_
Definition: routing.h:318
void operator()(F cparams)
Definition: routing.h:101
std::array< unsigned,(int) ParamType::MAX > param_childrens
Definition: routing.h:535
Definition: utility.h:455
bool IsSimpleNode() const
Definition: routing.h:538
Trie()
Definition: routing.h:549
void set2(Func f, typename std::enable_if< std::is_same< typename std::tuple_element< 0, std::tuple< Args..., void >>::type, const request &>::value &&!std::is_same< typename std::tuple_element< 1, std::tuple< Args..., void, void >>::type, response &>::value, int >::type=0)
Definition: routing.h:193
Definition: utility.h:247
void handle(const request &req, response &res, const routing_params ¶ms) override
Definition: routing.h:373
declaration and default definition for the functions used the API
void handle(const request &req, response &res)
Definition: routing.h:979
const routing_params & params
Definition: routing.h:88
std::string url
Definition: http_request.h:27
void debug_print()
Definition: routing.h:1046
std::function< void(const crow::request &, crow::response &, Args...)> type
Definition: routing.h:226
Definition: routing.h:156
std::vector< Node > nodes_
Definition: routing.h:854
void debug_print()
Definition: routing.h:832
handler_type_helper< ArgsWrapped... >::type handler_
Definition: routing.h:237
std::unique_ptr< BaseRule > rule_to_upgrade_
Definition: routing.h:65
unsigned rule_index
Definition: routing.h:534
self_t & onopen(Func f)
Definition: routing.h:289
#define CROW_LOG_ERROR
Definition: logging.h:130
std::enable_if< !black_magic::CallHelper< Func, black_magic::S< Args... > >::value &&!black_magic::CallHelper< Func, black_magic::S< crow::request, Args... > >::value, void >::type operator()(Func &&f)
Definition: routing.h:487
type
Definition: json.h:74
static uint64_t get_parameter_tag_runtime(const char *s, unsigned p=0)
Definition: utility.h:191
Definition: utility.h:329
HTTPMethod method
Definition: http_request.h:25
void operator()(F cparams)
Definition: routing.h:145
response & res
Definition: routing.h:90
std::unordered_map< std::string, unsigned > children
Definition: routing.h:536
#define CROW_LOG_DEBUG
Definition: logging.h:139
void handle(const request &req, response &res, const routing_params ¶ms) override
Definition: routing.h:507
std::enable_if< black_magic::CallHelper< Func, black_magic::S< Args... > >::value, void >::type operator()(Func &&f)
Definition: routing.h:449
std::string name_
Definition: routing.h:63
void debug_node_print(Node *n, int level)
Definition: routing.h:792
Definition: utility.h:148
H1 & handler
Definition: routing.h:87
void internal_add_rule_object(const std::string &rule, BaseRule *ruleObject)
Definition: routing.h:884
void validate()
Definition: routing.h:899
req_handler_wrapper(Func f)
Definition: routing.h:178
WebSocketRule & websocket()
Definition: routing.h:327
std::enable_if< !black_magic::CallHelper< Func, black_magic::S< Args... > >::value &&black_magic::CallHelper< Func, black_magic::S< crow::request, Args... > >::value, void >::type operator()(Func &&f)
Definition: routing.h:468
Definition: routing.h:217
Definition: routing.h:532
void optimize()
Definition: routing.h:599
self_t & onclose(Func f)
Definition: routing.h:303
self_t & name(std::string name) noexcept
Definition: routing.h:334
void add(const std::string &url, unsigned rule_index)
Definition: routing.h:735
std::function< void(const request &, response &, const routing_params &)> wrap(Func f, black_magic::seq< Indices... >)
Definition: routing.h:398
DynamicRule(std::string rule)
Definition: routing.h:360
std::function< void(crow::websocket::connection &)> open_handler_
Definition: routing.h:317
void operator()(std::string name, Func &&f)
Definition: routing.h:418
void validate()
Definition: routing.h:605
std::pair< unsigned, routing_params > find(const std::string &req_url, const Node *node=nullptr, unsigned pos=0, routing_params *params=nullptr) const
Definition: routing.h:612
BaseRule(std::string rule)
Definition: routing.h:23
void operator()(F cparams)
Definition: routing.h:123
virtual void handle(const request &, response &, const routing_params &)=0
Node * head()
Definition: routing.h:843
Definition: routing.h:356
const char * name
Definition: simplewallet.cpp:180
void end()
Definition: http_response.h:93
void add_header(std::string key, std::string value)
Definition: http_response.h:29
Definition: utility.h:340
std::function< void(const crow::request &, crow::response &, Args...)> handler_
Definition: routing.h:523
self_t & methods(HTTPMethod method)
Definition: routing.h:340
static bool is_parameter_tag_compatible(uint64_t a, uint64_t b)
Definition: utility.h:167
void set2(Func f, typename std::enable_if< std::is_same< typename std::tuple_element< 0, std::tuple< Args..., void >>::type, const request &>::value &&std::is_same< typename std::tuple_element< 1, std::tuple< Args..., void, void >>::type, response &>::value, int >::type=0)
Definition: routing.h:208
std::string method_name(HTTPMethod method)
Definition: common.h:34
void operator()(F cparams)
Definition: routing.h:112
self_t & methods(HTTPMethod method, MethodArgs ... args_method)
Definition: routing.h:347
HTTPMethod
Definition: common.h:11
std::function< void(const request &, response &, const routing_params &)> erased_handler_
Definition: routing.h:424
Definition: routing.h:258
Router()
Definition: routing.h:860
static const int pos
Definition: routing.h:81
std::string rule_
Definition: routing.h:62
void handle(const request &, response &res, const routing_params &) override
Definition: routing.h:271
#define CROW_LOG_INFO
Definition: logging.h:136
Definition: utility.h:300
DynamicRule & new_rule_dynamic(const std::string &rule)
Definition: routing.h:864
WebSocketRule(std::string rule)
Definition: routing.h:262