RESTinio
authorization.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
5 /*!
6  * @file
7  * @brief Stuff related to value of Authorization HTTP-field.
8  *
9  * @since v.0.6.7
10  */
11 
12 #pragma once
13 
14 #include <restinio/helpers/http_field_parsers/basics.hpp>
15 
16 #include <restinio/variant.hpp>
17 
18 #include <iostream>
19 
20 namespace restinio
21 {
22 
23 namespace http_field_parsers
24 {
25 
27 {
28 
30 
31 //
32 // is_token68_char_predicate_t
33 //
34 /*!
35  * @brief A preducate for symbol_producer_template that checks that
36  * a symbol can be used inside token68 from RFC7235.
37  *
38  * @since v.0.6.7
39  */
42 {
44 
46  bool
47  operator()( const char actual ) const noexcept
48  {
49  return base_type_t::operator()(actual)
50  || '-' == actual
51  || '.' == actual
52  || '_' == actual
53  || '~' == actual
54  || '+' == actual
55  || '/' == actual
56  ;
57  }
58 };
59 
60 //
61 // token68_symbol_p
62 //
64 inline auto
66 {
69 }
70 
71 //
72 // token68_t
73 //
74 /*!
75  * @brief A structure for holding a value of token68 from RFC7235.
76  *
77  * The actual value of token68 is stored as `std::string` inside that
78  * struct.
79  *
80  * @since v.0.6.7
81  */
82 struct token68_t
83 {
85 };
86 
87 inline std::ostream &
88 operator<<( std::ostream & to, const token68_t & v )
89 {
90  return (to << v.value);
91 }
92 
93 //
94 // token68_p
95 //
97 inline auto
99 {
100  return produce< token68_t >(
101  produce< std::string >(
102  repeat( 1, N, token68_symbol_p() >> to_container() ),
103  repeat( 0, N, symbol_p('=') >> to_container() )
104  ) >> &token68_t::value
105  );
106 }
107 
108 } /* authorization_details */
109 
110 //
111 // authorization_value_t
112 //
113 /*!
114  * @brief Tools for working with the value of Authorization HTTP-field.
115  *
116  * This struct represents parsed value of HTTP-field Authorization
117  * (see https://tools.ietf.org/html/rfc7235):
118 @verbatim
119 Authorization = credentials
120 
121 credentials = auth-scheme [ 1*SP ( token68 / [ #auth-param ] ) ]
122 
123 auth-scheme = token
124 
125 auth-param = token BWS "=" BWS ( token / quoted-string )
126 
127 token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
128 @endverbatim
129  *
130  * @since v.0.6.7
131  */
133 {
134  //! An indicator of the source form of the value of a parameter.
135  enum class value_form_t
136  {
137  //! The value of a parameter was specified as token.
138  token,
139  //! The value of a parameter was specified as quoted_string.
141  };
142 
143  //! A storage for the value of a parameter.
145  {
146  //! The value of a parameter.
148  //! How this value was represented: as a token, or a quoted string?
150  };
151 
152  //! A storage for a parameter with a name and a value.
153  struct param_t
154  {
155  //! The name of a parameter.
157  //! The value of a parameter.
159  };
160 
161  //! Type of container for holding parameters.
163 
164  //! Type for holding a value of token68 from RFC7235.
165  using token68_t = authorization_details::token68_t;
166 
167  //! Type for holding a parameter for authorization.
169 
170  //! A value of auth-scheme.
172  //! A parameter for authorization.
173  /*!
174  * @note
175  * It can be empty.
176  */
178 
179  /*!
180  * @brief A factory function for a parser of Authorization value.
181  *
182  * @since v.0.6.7
183  */
185  static auto
187  {
188  using namespace authorization_details;
189 
190  auto token_to_v = []( std::string v ) -> param_value_t {
191  return { std::move(v), value_form_t::token };
192  };
193  auto qstring_to_v = []( std::string v ) -> param_value_t {
194  return { std::move(v), value_form_t::quoted_string };
195  };
196 
197  // NOTE: token68 should consume all input.
198  // So there should not be any symbols after the value.
199  auto token68_seq = sequence(
200  token68_p() >> as_result(),
201  not_clause( any_symbol_p() >> skip() ) );
202  // Parameters list can be empty.
204  produce< param_t >(
205  token_p() >> to_lower() >> &param_t::name,
206  ows(),
207  symbol('='),
208  ows(),
210  alternatives(
211  token_p() >> convert( token_to_v ) >> as_result(),
213  >> as_result()
214  )
215  ) >> &param_t::value
216  )
217  ) >> as_result();
218 
219  return produce< authorization_value_t >(
221  maybe(
222  repeat( 1, N, space() ),
226  )
227  );
228  }
229 
230  /*!
231  * @brief An attempt to parse Authorization HTTP-field.
232  *
233  * @since v.0.6.7
234  */
236  static expected_t<
240  {
242  }
243 };
244 
245 //
246 // Various helpers for dumping values to std::ostream.
247 //
248 inline std::ostream &
250  std::ostream & to,
252 {
253  if(authorization_value_t::value_form_t::token == v.form)
254  to << v.value;
255  else
256  to << '"' << v.value << '"';
257  return to;
258 }
259 
260 inline std::ostream &
262  std::ostream & to,
263  const authorization_value_t::param_t & v )
264 {
265  return (to << v.name << '=' << v.value);
266 }
267 
268 inline std::ostream &
270  std::ostream & to,
272 {
273  struct printer_t
274  {
275  std::ostream & to;
276 
277  void
278  operator()( const authorization_value_t::token68_t & t ) const
279  {
280  to << t;
281  }
282 
283  void
284  operator()( const authorization_value_t::param_container_t & c ) const
285  {
286  bool first = true;
287  to << '{';
288  for( const auto & param : c )
289  {
290  if( !first )
291  to << ", ";
292  else
293  first = false;
294 
295  to << param;
296  }
297  to << '}';
298  }
299  };
300 
301  restinio::visit( printer_t{ to }, p );
302 
303  return to;
304 }
305 
306 inline std::ostream &
308  std::ostream & to,
309  const authorization_value_t & v )
310 {
311  return (to << v.auth_scheme << ' ' << v.auth_param);
312 }
313 
314 } /* namespace http_field_parsers */
315 
316 } /* namespace restinio */
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
std::ostream & operator<<(std::ostream &to, const authorization_value_t::auth_param_t &p)
value_form_t
An indicator of the source form of the value of a parameter.
std::ostream & operator<<(std::ostream &to, const authorization_value_t::param_value_t &v)
A storage for a parameter with a name and a value.
value_form_t form
How this value was represented: as a token, or a quoted string?
The value of a parameter was specified as token.
The value of a parameter was specified as quoted_string.
std::string auth_scheme
A value of auth-scheme.
std::ostream & operator<<(std::ostream &to, const authorization_value_t &v)
std::ostream & operator<<(std::ostream &to, const token68_t &v)
RESTINIO_NODISCARD auto try_parse_field(const generic_request_t< Extra_Data > &req, http_field_t field_id, string_view_t default_value=string_view_t{})
A helper function for extraction and parsing a value of HTTP-field.
static RESTINIO_NODISCARD expected_t< authorization_value_t, restinio::easy_parser::parse_error_t > try_parse(string_view_t what)
An attempt to parse Authorization HTTP-field.
std::ostream & operator<<(std::ostream &to, const authorization_value_t::param_t &v)
A structure for holding a value of token68 from RFC7235.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
Definition: value_or.hpp:64
auth_param_t auth_param
A parameter for authorization.