1 // 2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // Official repository: https://github.com/boostorg/beast 8 // 9 10 #ifndef BOOST_BEAST_HTTP_RFC7230_HPP 11 #define BOOST_BEAST_HTTP_RFC7230_HPP 12 13 #include <boost/beast/core/detail/config.hpp> 14 #include <boost/beast/http/detail/rfc7230.hpp> 15 #include <boost/beast/http/detail/basic_parsed_list.hpp> 16 17 namespace boost { 18 namespace beast { 19 namespace http { 20 21 /** A list of parameters in an HTTP extension field value. 22 23 This container allows iteration of the parameter list in an HTTP 24 extension. The parameter list is a series of name/value pairs 25 with each pair starting with a semicolon. The value is optional. 26 27 If a parsing error is encountered while iterating the string, 28 the behavior of the container will be as if a string containing 29 only characters up to but excluding the first invalid character 30 was used to construct the list. 31 32 @par BNF 33 @code 34 param-list = *( OWS ";" OWS param ) 35 param = token OWS [ "=" OWS ( token / quoted-string ) ] 36 @endcode 37 38 To use this class, construct with the string to be parsed and 39 then use @ref begin and @ref end, or range-for to iterate each 40 item: 41 42 @par Example 43 @code 44 for(auto const& param : param_list{";level=9;no_context_takeover;bits=15"}) 45 { 46 std::cout << ";" << param.first; 47 if(! param.second.empty()) 48 std::cout << "=" << param.second; 49 std::cout << "\n"; 50 } 51 @endcode 52 */ 53 class param_list 54 { 55 string_view s_; 56 57 public: 58 /** The type of each element in the list. 59 60 The first string in the pair is the name of the parameter, 61 and the second string in the pair is its value (which may 62 be empty). 63 */ 64 using value_type = 65 std::pair<string_view, string_view>; 66 67 /// A constant iterator to the list 68 #if BOOST_BEAST_DOXYGEN 69 using const_iterator = __implementation_defined__; 70 #else 71 class const_iterator; 72 #endif 73 74 /// Default constructor. 75 param_list() = default; 76 77 /** Construct a list. 78 79 @param s A string containing the list contents. The string 80 must remain valid for the lifetime of the container. 81 */ 82 explicit param_list(string_view s)83 param_list(string_view s) 84 : s_(s) 85 { 86 } 87 88 /// Return a const iterator to the beginning of the list 89 const_iterator begin() const; 90 91 /// Return a const iterator to the end of the list 92 const_iterator end() const; 93 94 /// Return a const iterator to the beginning of the list 95 const_iterator cbegin() const; 96 97 /// Return a const iterator to the end of the list 98 const_iterator cend() const; 99 }; 100 101 //------------------------------------------------------------------------------ 102 103 /** A list of extensions in a comma separated HTTP field value. 104 105 This container allows iteration of the extensions in an HTTP 106 field value. The extension list is a comma separated list of 107 token parameter list pairs. 108 109 If a parsing error is encountered while iterating the string, 110 the behavior of the container will be as if a string containing 111 only characters up to but excluding the first invalid character 112 was used to construct the list. 113 114 @par BNF 115 @code 116 ext-list = *( "," OWS ) ext *( OWS "," [ OWS ext ] ) 117 ext = token param-list 118 param-list = *( OWS ";" OWS param ) 119 param = token OWS [ "=" OWS ( token / quoted-string ) ] 120 @endcode 121 122 To use this class, construct with the string to be parsed and 123 then use @ref begin and @ref end, or range-for to iterate each 124 item: 125 126 @par Example 127 @code 128 for(auto const& ext : ext_list{"none, 7z;level=9, zip;no_context_takeover;bits=15"}) 129 { 130 std::cout << ext.first << "\n"; 131 for(auto const& param : ext.second) 132 { 133 std::cout << ";" << param.first; 134 if(! param.second.empty()) 135 std::cout << "=" << param.second; 136 std::cout << "\n"; 137 } 138 } 139 @endcode 140 */ 141 class ext_list 142 { 143 using iter_type = string_view::const_iterator; 144 145 string_view s_; 146 147 public: 148 /** The type of each element in the list. 149 150 The first element of the pair is the extension token, and the 151 second element of the pair is an iterable container holding the 152 extension's name/value parameters. 153 */ 154 using value_type = std::pair<string_view, param_list>; 155 156 /// A constant iterator to the list 157 #if BOOST_BEAST_DOXYGEN 158 using const_iterator = __implementation_defined__; 159 #else 160 class const_iterator; 161 #endif 162 163 /** Construct a list. 164 165 @param s A string containing the list contents. The string 166 must remain valid for the lifetime of the container. 167 */ 168 explicit ext_list(string_view s)169 ext_list(string_view s) 170 : s_(s) 171 { 172 } 173 174 /// Return a const iterator to the beginning of the list 175 const_iterator begin() const; 176 177 /// Return a const iterator to the end of the list 178 const_iterator end() const; 179 180 /// Return a const iterator to the beginning of the list 181 const_iterator cbegin() const; 182 183 /// Return a const iterator to the end of the list 184 const_iterator cend() const; 185 186 /** Find a token in the list. 187 188 @param s The token to find. A case-insensitive comparison is used. 189 190 @return An iterator to the matching token, or `end()` if no 191 token exists. 192 */ 193 BOOST_BEAST_DECL 194 const_iterator 195 find(string_view const& s); 196 197 /** Return `true` if a token is present in the list. 198 199 @param s The token to find. A case-insensitive comparison is used. 200 */ 201 BOOST_BEAST_DECL 202 bool 203 exists(string_view const& s); 204 }; 205 206 //------------------------------------------------------------------------------ 207 208 /** A list of tokens in a comma separated HTTP field value. 209 210 This container allows iteration of a list of items in a 211 header field value. The input is a comma separated list of 212 tokens. 213 214 If a parsing error is encountered while iterating the string, 215 the behavior of the container will be as if a string containing 216 only characters up to but excluding the first invalid character 217 was used to construct the list. 218 219 @par BNF 220 @code 221 token-list = *( "," OWS ) token *( OWS "," [ OWS token ] ) 222 @endcode 223 224 To use this class, construct with the string to be parsed and 225 then use @ref begin and @ref end, or range-for to iterate each 226 item: 227 228 @par Example 229 @code 230 for(auto const& token : token_list{"apple, pear, banana"}) 231 std::cout << token << "\n"; 232 @endcode 233 */ 234 class token_list 235 { 236 using iter_type = string_view::const_iterator; 237 238 string_view s_; 239 240 public: 241 /// The type of each element in the token list. 242 using value_type = string_view; 243 244 /// A constant iterator to the list 245 #if BOOST_BEAST_DOXYGEN 246 using const_iterator = __implementation_defined__; 247 #else 248 class const_iterator; 249 #endif 250 251 /** Construct a list. 252 253 @param s A string containing the list contents. The string 254 must remain valid for the lifetime of the container. 255 */ 256 explicit token_list(string_view s)257 token_list(string_view s) 258 : s_(s) 259 { 260 } 261 262 /// Return a const iterator to the beginning of the list 263 const_iterator begin() const; 264 265 /// Return a const iterator to the end of the list 266 const_iterator end() const; 267 268 /// Return a const iterator to the beginning of the list 269 const_iterator cbegin() const; 270 271 /// Return a const iterator to the end of the list 272 const_iterator cend() const; 273 274 /** Return `true` if a token is present in the list. 275 276 @param s The token to find. A case-insensitive comparison is used. 277 */ 278 BOOST_BEAST_DECL 279 bool 280 exists(string_view const& s); 281 }; 282 283 /** A list of tokens in a comma separated HTTP field value. 284 285 This container allows iteration of a list of items in a 286 header field value. The input is a comma separated list of 287 tokens. 288 289 If a parsing error is encountered while iterating the string, 290 the behavior of the container will be as if a string containing 291 only characters up to but excluding the first invalid character 292 was used to construct the list. 293 294 @par BNF 295 @code 296 token-list = *( "," OWS ) token *( OWS "," [ OWS token ] ) 297 @endcode 298 299 To use this class, construct with the string to be parsed and 300 then use `begin` and `end`, or range-for to iterate each item: 301 302 @par Example 303 @code 304 for(auto const& token : token_list{"apple, pear, banana"}) 305 std::cout << token << "\n"; 306 @endcode 307 */ 308 using opt_token_list = 309 detail::basic_parsed_list< 310 detail::opt_token_list_policy>; 311 312 /** Returns `true` if a parsed list is parsed without errors. 313 314 This function iterates a single pass through a parsed list 315 and returns `true` if there were no parsing errors, else 316 returns `false`. 317 */ 318 template<class Policy> 319 bool 320 validate_list(detail::basic_parsed_list< 321 Policy> const& list); 322 323 } // http 324 } // beast 325 } // boost 326 327 #include <boost/beast/http/impl/rfc7230.hpp> 328 329 #endif 330