RESTinio
Loading...
Searching...
No Matches
express.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
13
14#include <restinio/optional.hpp>
15
17
20
23
24#include <map>
25#include <vector>
26
27namespace restinio
28{
29
30namespace router
31{
32
33namespace impl
34{
35
37
38} /* namespace impl */
39
40//
41// route_params_t
42//
43
45
58{
59 public:
61 std::vector< std::pair< string_view_t, string_view_t > >;
63 std::vector< string_view_t >;
64
65 private:
67
68 void
70 std::unique_ptr< char[] > request_target,
71 std::shared_ptr< std::string > key_names_buffer,
73 named_parameters_container_t named_parameters,
74 indexed_parameters_container_t indexed_parameters )
75 {
76 m_request_target = std::move( request_target );
78 m_match = match;
79 m_named_parameters = std::move( named_parameters );
80 m_indexed_parameters = std::move( indexed_parameters );
81 }
82
83 public:
84 route_params_t() = default;
85
88
89 route_params_t( const route_params_t & ) = delete;
91
94
98 {
99 return find_named_parameter_with_check( key ).second;
100 }
101
103 bool
104 has( string_view_t key ) const noexcept
105 {
107 }
108
112 get_param( string_view_t key ) const noexcept
113 {
114 const auto it = find_named_parameter( key );
115
116 return m_named_parameters.end() != it ?
119 }
120
123 operator [] ( std::size_t i ) const
124 {
125 if( i >= m_indexed_parameters.size() )
126 throw exception_t{ fmt::format( "invalid parameter index: {}", i ) };
127
128 return m_indexed_parameters.at( i );
129 }
130
136
137 private:
138 named_parameters_container_t::const_iterator
140 {
141 return
142 std::find_if(
143 m_named_parameters.begin(),
144 m_named_parameters.end(),
145 [&]( const auto p ){
146 return key == p.first;
147 } );
148 }
149
150 named_parameters_container_t::const_reference
152 {
153 auto it = find_named_parameter( key );
154
155 if( m_named_parameters.end() == it )
156 throw exception_t{
157 fmt::format(
158 "invalid parameter name: {}",
159 std::string{ key.data(), key.size() } ) };
160
161 return *it;
162 }
163
165
176 std::unique_ptr< char[] > m_request_target;
177
179 std::shared_ptr< std::string > m_key_names_buffer;
180
183
186
189};
190
191namespace impl
192{
193
194//
195// route_params_accessor_t
196//
197
200{
202 static void
205 std::unique_ptr< char[] > request_target,
206 std::shared_ptr< std::string > key_names_buffer,
210 {
211 rp.match(
212 std::move( request_target ),
213 std::move( key_names_buffer ),
214 match_,
215 std::move( named_parameters ),
216 std::move( indexed_parameters ) );
217 }
218
221 static const auto &
223 {
224 return rp.m_named_parameters;
225 }
226
227 static const auto &
229 {
230 return rp.m_indexed_parameters;
231 }
233};
234
235//
236// route_params_appender_t
237//
238
271
274
275//
276// route_matcher_t
277//
278
280template < typename Regex_Engine = std_regex_engine_t >
282{
283 public:
284 using regex_t = typename Regex_Engine::compiled_regex_t;
285 using match_results_t = typename Regex_Engine::match_results_t;
286
289 http_method_id_t method,
291 std::shared_ptr< std::string > named_params_buffer,
293 : m_route_regex{ std::move( route_regex ) }
296 {
297 assign( m_method_matcher, std::move(method) );
298 }
299
308 template< typename Method_Matcher >
312 std::shared_ptr< std::string > named_params_buffer,
314 : m_route_regex{ std::move( route_regex ) }
317 {
318 assign(
320 std::forward<Method_Matcher>(method_matcher) );
321 }
322
323 route_matcher_t() = default;
325
327 bool
330 route_params_t & parameters ) const
331 {
332 match_results_t matches;
333 if( Regex_Engine::try_match(
334 target_path.view(),
336 matches ) )
337 {
338 assert( m_param_appender_sequence.size() + 1 >= matches.size() );
339
340 // Data for route_params_t initialization.
341
342 auto captured_params = target_path.giveout_data();
343
344 const string_view_t match{
345 captured_params.get() + Regex_Engine::submatch_begin_pos( matches[0] ),
346 Regex_Engine::submatch_end_pos( matches[0] ) -
347 Regex_Engine::submatch_begin_pos( matches[0] ) } ;
348
351
352 route_params_appender_t param_appender{ named_parameters, indexed_parameters };
353
354 // Std regex and pcre engines handle
355 // trailing groups with empty values differently.
356 // Std despite they are empty includes them in the list of match results;
357 // Pcre on the other hand does not.
358 // So the second for is for pushing empty values
359 std::size_t i = 1;
360 for( ; i < matches.size(); ++i )
361 {
362 const auto & m = matches[ i ];
366 captured_params.get() + Regex_Engine::submatch_begin_pos( m ),
367 Regex_Engine::submatch_end_pos( m ) -
368 Regex_Engine::submatch_begin_pos( m ) } );
369 }
370
371 for( ; i < m_param_appender_sequence.size() + 1; ++i )
372 {
375 string_view_t{ captured_params.get(), 0 } );
376 }
377
378 // Init route parameters.
380 parameters,
381 std::move( captured_params ),
382 m_named_params_buffer, // Do not move (it is used on each match).
383 std::move( match ),
384 std::move( named_parameters ),
385 std::move( indexed_parameters ) );
386
387 return true;
388 }
389
390 return false;
391 }
392
393 inline bool
395 const http_request_header_t & h,
397 route_params_t & parameters ) const
398 {
399 return m_method_matcher->match( h.method() ) &&
400 match_route( target_path, parameters );
401 }
402
403 private:
406
409
411 std::shared_ptr< std::string > m_named_params_buffer;
412
415};
416
417} /* namespace impl */
418
419//
420// generic_express_request_handler_t
421//
438template< typename Extra_Data >
443 >;
444
445//
446// express_request_handler_t
447//
458
459//
460// generic_express_route_entry_t
461//
462
464
469template<
470 typename Regex_Engine,
471 typename Extra_Data_Factory >
473{
474 public:
476 typename Extra_Data_Factory::data_t
477 >;
479 typename Extra_Data_Factory::data_t
480 >;
481
482 private:
486 Regex_Engine >;
487
488 template< typename Method_Matcher >
493 : m_matcher{
495 std::move( matcher_data.m_regex ),
496 std::move( matcher_data.m_named_params_buffer ),
497 std::move( matcher_data.m_param_appender_sequence ) }
498 , m_handler{ std::move( handler ) }
499 {}
500
501 public:
503 const generic_express_route_entry_t & ) = delete;
505 const generic_express_route_entry_t & ) = delete;
506
509 generic_express_route_entry_t && ) = default;
510
513
514 template< typename Method_Matcher >
522 path2regex::path2regex< impl::route_params_appender_t, Regex_Engine >(
524 options ),
525 std::move( handler ) }
526 {}
527
528 template< typename Method_Matcher >
539
543 bool
545 const http_request_header_t & h,
547 route_params_t & params ) const
548 {
549 return m_matcher( h, target_path, params );
550 }
551
556 {
557 return m_handler( std::move( rh ), std::move( rp ) );
558 }
559
560 private:
563};
564
565//
566// express_route_entry_t
567//
574template<
579
580//
581// generic_express_router_t
582//
583
585
608template<
609 typename Regex_Engine,
610 typename Extra_Data_Factory >
612{
613 public:
623 typename Extra_Data_Factory::data_t
624 >;
625
628
632 {
633 impl::target_path_holder_t target_path{ req->header().path() };
634 route_params_t params;
635 for( const auto & entry : m_handlers )
636 {
637 if( entry.match( req->header(), target_path, params ) )
638 {
639 return entry.handle( std::move( req ), std::move( params ) );
640 }
641 }
642
643 // Here: none of the routes matches this handler.
644
646 {
647 // If non matched request handler is set
648 // then call it.
649 return m_non_matched_request_handler( std::move( req ) );
650 }
651
652 return request_not_handled();
653 }
654
657 template< typename Method_Matcher >
658 void
663 {
665 std::forward<Method_Matcher>(method_matcher),
668 std::move( handler ) );
669 }
670
671 template< typename Method_Matcher >
672 void
678 {
679 m_handlers.emplace_back(
680 std::forward<Method_Matcher>(method_matcher),
682 options,
683 std::move( handler ) );
684 }
685
686 void
696
697 void
709
710 void
720
721 void
733
734 void
744
745 void
757
758 void
768
769 void
781
782 void
792
793 void
806
808 void
813
814 private:
818 >;
819
821 std::vector< route_entry_t > m_handlers;
822
825};
826
827//
828// express_router_t
829//
839template<
844
845} /* namespace router */
846
848template < typename Value_Type >
851{
852 return get< Value_Type >( params[ key ] );
853}
854
856template < typename Value_Type >
858get( const router::route_params_t & params, std::size_t index )
859{
860 return get< Value_Type >( params[ index ] );
861}
862
863} /* namespace restinio */
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
A type for representation of HTTP method ID.
Options for matching routes.
A single generic express route entry.
Definition express.hpp:473
RESTINIO_NODISCARD bool match(const http_request_header_t &h, impl::target_path_holder_t &target_path, route_params_t &params) const
Checks if request header matches entry, and if so, set route params.
Definition express.hpp:544
generic_express_route_entry_t(Method_Matcher &&method_matcher, matcher_init_data_t matcher_data, actual_request_handler_t handler)
Definition express.hpp:489
generic_express_request_handler_t< typename Extra_Data_Factory::data_t > actual_request_handler_t
Definition express.hpp:477
generic_express_route_entry_t & operator=(const generic_express_route_entry_t &)=delete
RESTINIO_NODISCARD request_handling_status_t handle(actual_request_handle_t rh, route_params_t rp) const
Calls a handler of given request with given params.
Definition express.hpp:555
generic_express_route_entry_t(Method_Matcher &&method_matcher, string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:515
generic_express_route_entry_t(generic_express_route_entry_t &&)=default
generic_request_handle_t< typename Extra_Data_Factory::data_t > actual_request_handle_t
Definition express.hpp:480
generic_express_route_entry_t(Method_Matcher &&method_matcher, string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:529
generic_express_route_entry_t & operator=(generic_express_route_entry_t &&)=default
actual_request_handler_t m_handler
Definition express.hpp:562
generic_express_route_entry_t()=default
generic_express_route_entry_t(const generic_express_route_entry_t &)=delete
impl::route_matcher_t< Regex_Engine > m_matcher
Definition express.hpp:561
Generic Express.js style router.
Definition express.hpp:612
void http_post(string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:770
void http_get(string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:711
void http_put(string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:794
generic_non_matched_request_handler_t< typename Extra_Data_Factory::data_t > non_matched_handler_t
Definition express.hpp:624
void non_matched_request_handler(non_matched_handler_t nmrh)
Set handler for requests that don't match any route.
Definition express.hpp:809
RESTINIO_NODISCARD request_handling_status_t operator()(actual_request_handle_t req) const
Definition express.hpp:631
non_matched_handler_t m_non_matched_request_handler
Handler that is called for requests that don't match any route.
Definition express.hpp:824
void http_head(string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:746
void http_delete(string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:698
generic_request_handle_t< typename Extra_Data_Factory::data_t > actual_request_handle_t
Definition express.hpp:615
void http_delete(string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:687
std::vector< route_entry_t > m_handlers
A list of existing routes.
Definition express.hpp:821
void add_handler(Method_Matcher &&method_matcher, string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:673
void http_put(string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:783
void http_head(string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:735
void http_post(string_view_t route_path, actual_request_handler_t handler)
Definition express.hpp:759
void http_get(string_view_t route_path, const path2regex::options_t &options, actual_request_handler_t handler)
Definition express.hpp:722
void add_handler(Method_Matcher &&method_matcher, string_view_t route_path, actual_request_handler_t handler)
Add handlers.
Definition express.hpp:659
generic_express_router_t(generic_express_router_t &&)=default
typename generic_express_route_entry_t< Regex_Engine, Extra_Data_Factory >::actual_request_handler_t actual_request_handler_t
Definition express.hpp:620
A special class that allows to hold a copy of small-size method_matchers or a pointer to dynamically ...
A matcher for a given path.
Definition express.hpp:282
route_matcher_t(Method_Matcher &&method_matcher, regex_t route_regex, std::shared_ptr< std::string > named_params_buffer, param_appender_sequence_t param_appender_sequence)
Definition express.hpp:309
buffered_matcher_holder_t m_method_matcher
HTTP method to match.
Definition express.hpp:405
regex_t m_route_regex
Regex of a given route.
Definition express.hpp:408
param_appender_sequence_t m_param_appender_sequence
Parameters values.
Definition express.hpp:414
bool match_route(target_path_holder_t &target_path, route_params_t &parameters) const
Try to match a given request target with this route.
Definition express.hpp:328
typename Regex_Engine::match_results_t match_results_t
Definition express.hpp:285
bool operator()(const http_request_header_t &h, target_path_holder_t &target_path, route_params_t &parameters) const
Definition express.hpp:394
std::shared_ptr< std::string > m_named_params_buffer
Buffer for named parameters names string views.
Definition express.hpp:411
typename Regex_Engine::compiled_regex_t regex_t
Definition express.hpp:284
route_matcher_t(route_matcher_t &&)=default
route_matcher_t(http_method_id_t method, regex_t route_regex, std::shared_ptr< std::string > named_params_buffer, param_appender_sequence_t param_appender_sequence)
Creates matcher with a given parameters.
Definition express.hpp:288
Helper class for gthering parameters from route.
Definition express.hpp:241
route_params_t::indexed_parameters_container_t & m_indexed_parameters
Definition express.hpp:269
void add_indexed_param(string_view_t value)
Definition express.hpp:262
void add_named_param(string_view_t key, string_view_t value)
Definition express.hpp:256
route_params_t::named_parameters_container_t & m_named_parameters
Definition express.hpp:268
route_params_appender_t(route_params_appender_t &&)=delete
route_params_appender_t & operator=(const route_params_appender_t &)=delete
route_params_appender_t(const route_params_appender_t &)=delete
route_params_appender_t(route_params_t::named_parameters_container_t &named_parameters, route_params_t::indexed_parameters_container_t &indexed_parameters)
Definition express.hpp:243
Helper class for holding a unique instance of char array with target_path value.
Parameters extracted from route.
Definition express.hpp:58
named_parameters_container_t::const_reference find_named_parameter_with_check(string_view_t key) const
Definition express.hpp:151
auto indexed_parameters_size() const noexcept
Definition express.hpp:134
optional_t< string_view_t > get_param(string_view_t key) const noexcept
Get the value of a parameter if it exists.
Definition express.hpp:112
bool has(string_view_t key) const noexcept
Check parameter.
Definition express.hpp:104
std::vector< string_view_t > indexed_parameters_container_t
Definition express.hpp:63
void match(std::unique_ptr< char[] > request_target, std::shared_ptr< std::string > key_names_buffer, string_view_t match, named_parameters_container_t named_parameters, indexed_parameters_container_t indexed_parameters)
Definition express.hpp:69
route_params_t(const route_params_t &)=delete
std::unique_ptr< char[] > m_request_target
A raw request target.
Definition express.hpp:176
std::vector< std::pair< string_view_t, string_view_t > > named_parameters_container_t
Definition express.hpp:61
string_view_t match() const noexcept
Matched route.
Definition express.hpp:93
named_parameters_container_t m_named_parameters
Named params.
Definition express.hpp:185
route_params_t & operator=(route_params_t &&)=default
auto named_parameters_size() const noexcept
Get number of parameters.
Definition express.hpp:133
indexed_parameters_container_t m_indexed_parameters
Indexed params.
Definition express.hpp:188
route_params_t(route_params_t &&)=default
string_view_t operator[](string_view_t key) const
Get named parameter.
Definition express.hpp:97
named_parameters_container_t::const_iterator find_named_parameter(string_view_t key) const noexcept
Definition express.hpp:139
string_view_t m_match
Matched pattern.
Definition express.hpp:182
std::shared_ptr< std::string > m_key_names_buffer
Shared buffer for string_view of named parameterts names.
Definition express.hpp:179
#define RESTINIO_NODISCARD
Stuff related to method_matchers.
std::vector< param_appender_t< Route_Param_Appender > > param_appender_sequence_t
A sequence of appenders for submatches.
path2regex::param_appender_sequence_t< route_params_appender_t > param_appender_sequence_t
Definition express.hpp:273
std::function< request_handling_status_t(generic_request_handle_t< Extra_Data >) > generic_non_matched_request_handler_t
A generic type of handler for non-matched requests.
std::function< request_handling_status_t(generic_request_handle_t< Extra_Data >, route_params_t) > generic_express_request_handler_t
Type of generic handler for one route.
Definition express.hpp:443
generic_express_request_handler_t< no_extra_data_factory_t::data_t > express_request_handler_t
Type of a handler for one route in the case when there is no extra-data in request object.
Definition express.hpp:457
RESTINIO_NODISCARD constexpr request_handling_status_t request_not_handled() noexcept
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
nonstd::string_view string_view_t
std::shared_ptr< generic_request_t< Extra_Data > > generic_request_handle_t
An alias for shared-pointer to incoming request.
request_handling_status_t
Request handling status.
Value_Type get(const router::route_params_t &params, string_view_t key)
Cast named parameter value to a given type.
Definition express.hpp:850
STL namespace.
The definition of the non_matched_request_handler type.
The default extra-data-factory to be used in server's traits if a user doesn't specify own one.
Resulting regex and param extraction for a specific route.
Route params private internals accessor.
Definition express.hpp:200
static const auto & named_parameters(const route_params_t &rp) noexcept
Get values containers for all parameters (used in unit tests).
Definition express.hpp:222
static const auto & indexed_parameters(const route_params_t &rp) noexcept
Definition express.hpp:228
static void match(route_params_t &rp, std::unique_ptr< char[] > request_target, std::shared_ptr< std::string > key_names_buffer, string_view_t match_, route_params_t::named_parameters_container_t named_parameters, route_params_t::indexed_parameters_container_t indexed_parameters)
Init parameters with a matched route params.
Definition express.hpp:203
virtual RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept=0
Is the specified method can be applied to a route?
Regex engine implementation for using with standard regex implementation.
Implementation of target_path_holder helper class.
#define const
Definition zconf.h:230