RESTinio рд╕реЗ easy_parser рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдзрд┐рдХрд░рдг HTTP рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП C ++ рдХреЛрдб рдХреЛ рдХрд┐рддрдирд╛ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП?


рд╣рдо 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() ) );

   //    name=value   .
   auto params_seq = maybe_empty_comma_separated_list_p< param_container_t >(
         produce< param_t >(
            token_p() >> to_lower() >> &param_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()
               )
            ) >> &param_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() >> &param_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()
      )
   ) >> &param_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


рдкреНрд░рд╢реНрди рдХрд╛ рджреВрд╕рд░рд╛ рдЙрддреНрддрд░ "рдпрд╣ рд▓реЗрдЦ рдХреНрдпреЛрдВ рдФрд░ рдХрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛?" рдмрд╕ рддреБрдЪреНрдЫ рдФрд░ рд╕реНрдкрд╖реНрдЯ: рдореИрдВ рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдпрд╛рдж рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЬреАрд╡рд┐рдд рд╣реИ рдФрд░ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрддреА рд╣реИред рдЖрдк рдЗрд╕реЗ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЕрдкрдиреА рднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рд╣рдорд╛рд░реЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдЬреЛ рдЖрдкрдХреЛ рдкрд╕рдВрдж рдЖрдпрд╛, рдЬреЛ рдЖрдкрдХреЛ рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛, рдХреНрдпрд╛ рдпрд╛рдж рдЖ рд░рд╣рд╛ рдерд╛, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдЖрдк рдЪрд╛рд╣рддреЗ рдереЗ, рд╡рд╣ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ ... рд╣рдо рд╕рднреА рд░рдЪрдирд╛рддреНрдордХ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЛ рд╕реБрдирддреЗ рд╣реИрдВ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдкрд╛рдардХ рдЗрд╕рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред )


All Articles