
рд╣рдо C ++ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд┐рдП рдЧрдП RESTinio HTTP рд╕рд░реНрд╡рд░ рдХреЛ рдореБрдлреНрдд рдФрд░ рдУрдкрди рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ ред R ++inio рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ C ++ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдпрд╣рд╛рдВ ( рд╣рд╛рд▓ рдХреЗ рдЙрджрд╛рд╣рд░рдг ) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ ред
C ++ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЬрд╛рджреВ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХреЗ рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ easy_parser рдерд╛, рдЬреЛ рдкреАрдИрдЬреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдиреАрдЪреЗ рдХреА рдУрд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдерд╛ ред HTTP рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд┐рдЫрд▓реЗ рд╡рд░реНрд╖ рдИрдЬрд╝реА_рдкреЗрдЬрд╝рд░ рдХреЛ RESTINIO рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред
рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ easy_parser рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рдмрд╛рдд рдХреА рдереА ред рдФрд░ рдЖрдЬ рдореИрдВ рдпрд╣ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ Restinio рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ easy_parser рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рд╛рдзрд┐рдХрд░рдг HTTP рд╣реЗрдбрд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдХреЗред рдЖрдЗрдП, рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд░реЗрд╕реНрдЯрд┐рдирд┐рдпреЛ рдХреА рд╣рд┐рдореНрдордд рдХреЛ рджреЗрдЦреЗрдВред
рд╡реНрдпрд╛рдХрд░рдг рдкреНрд░рд╛рдзрд┐рдХрд░рдг
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╢реАрд░реНрд╖ рд▓реЗрдЦ рд╕рдВрд░рдЪрдирд╛ RFC7235 рдореЗрдВ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреА рдЧрдИ рд╣реИ:
authorization-field = "Authorization" ":" OWS credentials
credentials = auth-scheme [ 1*SP ( token68 / [ #auth-param ] ) ]
auth-scheme = token
auth-param = token BWS "=" BWS ( token / quoted-string )
token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
рдЙрдиред рдкреНрд░рдорд╛рдгреАрдХрд░рдг рд╢реАрд░реНрд╖рдХ рдХреЗ рдореВрд▓реНрдп рдореЗрдВ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдпреЛрдЬрдирд╛ рдХрд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╛рдо рдФрд░ рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
, token68 ( , base64), "=".
Authorization easy_parser?
?
easy_parser , , .
, , :
struct authorization_value_t
{
enum class value_form_t { token, quoted_string };
struct param_value_t
{
std::string value;
value_form_t form;
};
struct param_t
{
std::string name;
param_value_t value;
};
using param_container_t = std::vector< param_t >;
struct token68_t
{
std::string value;
};
using auth_param_t = variant_t< token68_t, param_container_t >;
std::string auth_scheme;
auth_param_t auth_param;
};
authorization_value_t
: auth_scheme
auth_params
. auth_params
тАФ token68_t
, , param_t
.
Authorization
producer
, , . ( ) , , :
auto make_parser()
{
...
return produce< authorization_value_t >(
token_p() >> to_lower() >> &authorization_value_t::auth_scheme,
maybe(
repeat( 1, N, space() ),
produce< auth_param_t >(
alternatives( token68_seq, params_seq )
) >> &authorization_value_t::auth_param
)
);
}
make_parser
-, authorization_value_t
. produce
, . produce
, C++ DSL.
:
- token ( RFC7230). token-
auth_scheme
authorization_value_t
; - , , ,
maybe
; - ;
- token68, . ,
auth_param
authorization_value_t
auth_param_t
.
- . , , easy_parser DSL.
, - , , token68_seq
params_seq
. , ;)
token68_seq?
token68_seq
тАФ , make_parser
:
auto token68_seq = sequence(
token68_p() >> as_result(),
not_clause( any_symbol_p() >> skip() ) );
, token68_seq
тАФ . token68 , , .
, , token68 . PEG, not-predicate. Not-pedicate , , . , not-predicate, .
, RFC7617 , token68, . , token68 . , .
token68_seq
, token68_p
. :
struct is_token68_char_predicate_t
: protected hfp_impl::is_alphanum_predicate_t
{
using base_type_t = hfp_impl::is_alphanum_predicate_t;
bool operator()( const char actual ) const noexcept
{
return base_type_t::operator()(actual)
|| '-' == actual
|| '.' == actual
|| '_' == actual
|| '~' == actual
|| '+' == actual
|| '/' == actual
;
}
};
inline auto token68_symbol_p()
{
return restinio::easy_parser::impl::symbol_producer_template_t<
is_token68_char_predicate_t >{};
}
inline auto token68_p()
{
return produce< token68_t >(
produce< std::string >(
repeat( 1, N, token68_symbol_p() >> to_container() ),
repeat( 0, N, symbol_p('=') >> to_container() )
) >> &token68_t::value
);
}
, token68_p
. is_token68_char_predicate_t
token68_symbol_p
тАФ . , easy_parser , - , : digit_p
, space_p
, hexdigit_p
, alpha_symbol_p
, alphanum_symbol_p
.. , , token68, . is_token68_char_predicate_t
token68_symbol_p
.
token68_p
token68 -- : token68, =
. .
params_seq?
, params_seq
. , , make_parser
, :
auto make_parser()
{
auto token_to_v = []( std::string v ) -> param_value_t {
return { std::move(v), value_form_t::token };
};
auto qstring_to_v = []( std::string v ) -> param_value_t {
return { std::move(v), value_form_t::quoted_string };
};
auto token68_seq = sequence(
token68_p() >> as_result(),
not_clause( any_symbol_p() >> skip() ) );
auto params_seq = maybe_empty_comma_separated_list_p< param_container_t >(
produce< param_t >(
token_p() >> to_lower() >> ¶m_t::name,
ows(),
symbol('='),
ows(),
produce< param_value_t >(
alternatives(
token_p() >> convert( token_to_v ) >> as_result(),
quoted_string_p() >> convert( qstring_to_v )
>> as_result()
)
) >> ¶m_t::value
)
) >> as_result();
return produce< authorization_value_t >(
token_p() >> to_lower() >> &authorization_value_t::auth_scheme,
maybe(
repeat( 1, N, space() ),
produce< auth_param_t >(
alternatives( token68_seq, params_seq )
) >> &authorization_value_t::auth_param
)
);
}
, lambda- token_to_v
qstring_to_v
. , std::string
param_value_t
, : token quoted-string.
- , name=value
std::string
, param_value_t
, std::string
.
params_seq
:
auto params_seq = maybe_empty_comma_separated_list_p< param_container_t >(
...
) >> as_result();
params_seq
, param_container_t
. , .
maybe_empty_comma_separated_list_p
easy_parser- , RFC HTTP #auth-param
, #
:
[ ( "," / auth-param ) *( OWS "," [ OWS auth-param ] ) ]
params_seq
, . auth-param
. , -, :
produce< param_t >(
token_p() >> to_lower() >> ¶m_t::name,
ows(),
symbol('='),
ows(),
produce< param_value_t >(
alternatives(
token_p() >> convert( token_to_v ) >> as_result(),
quoted_string_p() >> convert( qstring_to_v )
>> as_result()
)
) >> ¶m_t::value
)
, param_t
, :
- token,
param_t::name
; - (
ows
OWS
(.. optional whitespace) RFC7230); =
;- ;
- (..
param_value_t
), : token, quoted-string. token, , token_to_v
( ) . quoted-string, , qstring_to_v
; param_value_t
param_t::value
.
, , .
" ?" .
, , , , RESTinio , . , , RESTinio.
, . , RESTinio, , , C++ . , .
easy_parser RESTinio , RESTinio HTTP-.
, - , - . ( , ), - .
, - ( bison, coco/r, ragel .) . RESTinio header-only ( libhttp-parser). - header-only . , : , - RESTinio, , - ( , RESTinio)? ragel coco/r? , .
, C++ DSL. , RESTinio - Boost- - PEGTL , .. . , (Boost.Spirit PEGTL) , . , show stopper-. easy_parser.
C HTTP- RESTinio easy_parser-. .
...
, easy_parser, . . , a) RFC, b) , , , c) d) . , , - 4-6 , easy_parser- тАФ 15-20 .
, easy_parser- RESTinio , - RESTinio .
RESTinio
рдкреНрд░рд╢реНрди рдХрд╛ рджреВрд╕рд░рд╛ рдЙрддреНрддрд░ "рдпрд╣ рд▓реЗрдЦ рдХреНрдпреЛрдВ рдФрд░ рдХрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛?" рдмрд╕ рддреБрдЪреНрдЫ рдФрд░ рд╕реНрдкрд╖реНрдЯ: рдореИрдВ рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдпрд╛рдж рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЬреАрд╡рд┐рдд рд╣реИ рдФрд░ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрддреА рд╣реИред рдЖрдк рдЗрд╕реЗ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЕрдкрдиреА рднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рд╣рдорд╛рд░реЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдЬреЛ рдЖрдкрдХреЛ рдкрд╕рдВрдж рдЖрдпрд╛, рдЬреЛ рдЖрдкрдХреЛ рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛, рдХреНрдпрд╛ рдпрд╛рдж рдЖ рд░рд╣рд╛ рдерд╛, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдЖрдк рдЪрд╛рд╣рддреЗ рдереЗ, рд╡рд╣ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ ... рд╣рдо рд╕рднреА рд░рдЪрдирд╛рддреНрдордХ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЛ рд╕реБрдирддреЗ рд╣реИрдВ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдкрд╛рдардХ рдЗрд╕рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред )