RESTinio
Loading...
Searching...
No Matches
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 <iostream>
17#include <variant>
18
19namespace restinio
20{
21
22namespace http_field_parsers
23{
24
26{
27
28namespace hfp_impl = restinio::http_field_parsers::impl;
29
30//
31// is_token68_char_predicate_t
32//
33/*!
34 * @brief A preducate for symbol_producer_template that checks that
35 * a symbol can be used inside token68 from RFC7235.
36 *
37 * @since v.0.6.7
38 */
40 : protected hfp_impl::is_alphanum_predicate_t
41{
43
44 [[nodiscard]]
45 bool
46 operator()( const char actual ) const noexcept
47 {
48 return base_type_t::operator()(actual)
49 || '-' == actual
50 || '.' == actual
51 || '_' == actual
52 || '~' == actual
53 || '+' == actual
54 || '/' == actual
55 ;
56 }
57};
58
59//
60// token68_symbol_p
61//
62[[nodiscard]]
63inline auto
65{
66 return restinio::easy_parser::impl::symbol_producer_template_t<
67 is_token68_char_predicate_t >{};
68}
69
70//
71// token68_t
72//
73/*!
74 * @brief A structure for holding a value of token68 from RFC7235.
75 *
76 * The actual value of token68 is stored as `std::string` inside that
77 * struct.
78 *
79 * @since v.0.6.7
80 */
82{
83 std::string value;
84};
85
86inline std::ostream &
87operator<<( std::ostream & to, const token68_t & v )
88{
89 return (to << v.value);
90}
91
92//
93// token68_p
94//
95[[nodiscard]]
96inline auto
98{
99 return produce< token68_t >(
100 produce< std::string >(
101 repeat( 1, N, token68_symbol_p() >> to_container() ),
102 repeat( 0, N, symbol_p('=') >> to_container() )
103 ) >> &token68_t::value
104 );
105}
106
107} /* authorization_details */
108
109//
110// authorization_value_t
111//
112/*!
113 * @brief Tools for working with the value of Authorization HTTP-field.
114 *
115 * This struct represents parsed value of HTTP-field Authorization
116 * (see https://tools.ietf.org/html/rfc7235):
117@verbatim
118Authorization = credentials
119
120credentials = auth-scheme [ 1*SP ( token68 / [ #auth-param ] ) ]
121
122auth-scheme = token
123
124auth-param = token BWS "=" BWS ( token / quoted-string )
125
126token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
127@endverbatim
128 *
129 * @since v.0.6.7
130 */
132{
133 //! An indicator of the source form of the value of a parameter.
134 enum class value_form_t
135 {
136 //! The value of a parameter was specified as token.
138 //! The value of a parameter was specified as quoted_string.
140 };
141
142 //! A storage for the value of a parameter.
144 {
145 //! The value of a parameter.
146 std::string value;
147 //! How this value was represented: as a token, or a quoted string?
149 };
150
151 //! A storage for a parameter with a name and a value.
152 struct param_t
153 {
154 //! The name of a parameter.
155 std::string name;
156 //! The value of a parameter.
158 };
159
160 //! Type of container for holding parameters.
162
163 //! Type for holding a value of token68 from RFC7235.
165
166 //! Type for holding a parameter for authorization.
168
169 //! A value of auth-scheme.
170 std::string auth_scheme;
171 //! A parameter for authorization.
172 /*!
173 * @note
174 * It can be empty.
175 */
177
178 /*!
179 * @brief A factory function for a parser of Authorization value.
180 *
181 * @since v.0.6.7
182 */
183 [[nodiscard]]
184 static auto
186 {
187 using namespace authorization_details;
188
189 auto token_to_v = []( std::string v ) -> param_value_t {
190 return { std::move(v), value_form_t::token };
191 };
192 auto qstring_to_v = []( std::string v ) -> param_value_t {
193 return { std::move(v), value_form_t::quoted_string };
194 };
195
196 // NOTE: token68 should consume all input.
197 // So there should not be any symbols after the value.
198 auto token68_seq = sequence(
199 token68_p() >> as_result(),
200 not_clause( any_symbol_p() >> skip() ) );
201 // Parameters list can be empty.
202 auto params_seq = maybe_empty_comma_separated_list_p< param_container_t >(
203 produce< param_t >(
204 token_p() >> to_lower() >> &param_t::name,
205 ows(),
206 symbol('='),
207 ows(),
208 produce< param_value_t >(
209 alternatives(
210 token_p() >> convert( token_to_v ) >> as_result(),
211 quoted_string_p() >> convert( qstring_to_v )
212 >> as_result()
213 )
214 ) >> &param_t::value
215 )
216 ) >> as_result();
217
218 return produce< authorization_value_t >(
219 token_p() >> to_lower() >> &authorization_value_t::auth_scheme,
220 maybe(
221 repeat( 1, N, space() ),
222 produce< auth_param_t >(
223 alternatives( token68_seq, params_seq )
224 ) >> &authorization_value_t::auth_param
225 )
226 );
227 }
228
229 /*!
230 * @brief An attempt to parse Authorization HTTP-field.
231 *
232 * @since v.0.6.7
233 */
234 [[nodiscard]]
235 static expected_t<
238 try_parse( string_view_t what )
239 {
240 return restinio::easy_parser::try_parse( what, make_parser() );
241 }
242};
243
244//
245// Various helpers for dumping values to std::ostream.
246//
247inline std::ostream &
248operator<<(
249 std::ostream & to,
251{
253 to << v.value;
254 else
255 to << '"' << v.value << '"';
256 return to;
257}
258
259inline std::ostream &
260operator<<(
261 std::ostream & to,
262 const authorization_value_t::param_t & v )
263{
264 return (to << v.name << '=' << v.value);
265}
266
267inline std::ostream &
268operator<<(
269 std::ostream & to,
270 const authorization_value_t::auth_param_t & p )
271{
272 struct printer_t
273 {
274 std::ostream & to;
275
276 void
277 operator()( const authorization_value_t::token68_t & t ) const
278 {
279 to << t;
280 }
281
282 void
283 operator()( const authorization_value_t::param_container_t & c ) const
284 {
285 bool first = true;
286 to << '{';
287 for( const auto & param : c )
288 {
289 if( !first )
290 to << ", ";
291 else
292 first = false;
293
294 to << param;
295 }
296 to << '}';
297 }
298 };
299
300 std::visit( printer_t{ to }, p );
301
302 return to;
303}
304
305inline std::ostream &
306operator<<(
307 std::ostream & to,
308 const authorization_value_t & v )
309{
310 return (to << v.auth_scheme << ' ' << v.auth_param);
311}
312
313} /* namespace http_field_parsers */
314
315} /* namespace restinio */
A preducate for symbol_producer_template that checks that a symbol can be used inside token68 from RF...
A structure for holding a value of token68 from RFC7235.
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?
Tools for working with the value of Authorization HTTP-field.
auth_param_t auth_param
A parameter for authorization.
std::string auth_scheme
A value of auth-scheme.
static auto make_parser()
A factory function for a parser of Authorization value.
static expected_t< authorization_value_t, restinio::easy_parser::parse_error_t > try_parse(string_view_t what)
An attempt to parse Authorization HTTP-field.
value_form_t
An indicator of the source form of the value of a parameter.
@ token
The value of a parameter was specified as token.
@ quoted_string
The value of a parameter was specified as quoted_string.
authorization_details::token68_t token68_t
Type for holding a value of token68 from RFC7235.
A preducate for symbol_producer_template that checks that a symbol is an alpha or numeric.
Definition basics.hpp:300
bool operator()(const char actual) const noexcept
Definition basics.hpp:303