100.00% Lines (24/24) 100.00% Functions (11/11)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) 3   // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4   // 4   //
5   // Distributed under the Boost Software License, Version 1.0. (See accompanying 5   // Distributed under the Boost Software License, Version 1.0. (See accompanying
6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7   // 7   //
8   // Official repository: https://github.com/boostorg/url 8   // Official repository: https://github.com/boostorg/url
9   // 9   //
10   10  
11   #ifndef BOOST_URL_URL_BASE_HPP 11   #ifndef BOOST_URL_URL_BASE_HPP
12   #define BOOST_URL_URL_BASE_HPP 12   #define BOOST_URL_URL_BASE_HPP
13   13  
14   #include <boost/url/detail/config.hpp> 14   #include <boost/url/detail/config.hpp>
15   #include <boost/url/ipv4_address.hpp> 15   #include <boost/url/ipv4_address.hpp>
16   #include <boost/url/ipv6_address.hpp> 16   #include <boost/url/ipv6_address.hpp>
17   #include <boost/url/params_encoded_ref.hpp> 17   #include <boost/url/params_encoded_ref.hpp>
18   #include <boost/url/params_ref.hpp> 18   #include <boost/url/params_ref.hpp>
19   #include <boost/url/pct_string_view.hpp> 19   #include <boost/url/pct_string_view.hpp>
20   #include <boost/url/scheme.hpp> 20   #include <boost/url/scheme.hpp>
21   #include <boost/url/segments_encoded_ref.hpp> 21   #include <boost/url/segments_encoded_ref.hpp>
22   #include <boost/url/segments_ref.hpp> 22   #include <boost/url/segments_ref.hpp>
23   #include <boost/url/url_view_base.hpp> 23   #include <boost/url/url_view_base.hpp>
24   #include <cstdint> 24   #include <cstdint>
25   #include <initializer_list> 25   #include <initializer_list>
26   #include <memory> 26   #include <memory>
27   #include <string> 27   #include <string>
28   #include <utility> 28   #include <utility>
29   29  
30   namespace boost { 30   namespace boost {
31   namespace urls { 31   namespace urls {
32   32  
33   namespace detail { 33   namespace detail {
34   struct any_params_iter; 34   struct any_params_iter;
35   struct any_segments_iter; 35   struct any_segments_iter;
36   struct params_iter_impl; 36   struct params_iter_impl;
37   struct segments_iter_impl; 37   struct segments_iter_impl;
38   struct pattern; 38   struct pattern;
39   } 39   }
40   40  
41   /** Common functionality for containers 41   /** Common functionality for containers
42   42  
43   This base class is used by the library 43   This base class is used by the library
44   to provide common member functions for 44   to provide common member functions for
45   containers. This cannot be instantiated 45   containers. This cannot be instantiated
46   directly; Instead, use one of the 46   directly; Instead, use one of the
47   containers or functions: 47   containers or functions:
48   48  
49   @par Containers 49   @par Containers
50   @li @ref url 50   @li @ref url
51   @li @ref url_view 51   @li @ref url_view
52   @li @ref static_url 52   @li @ref static_url
53   53  
54   @par Functions 54   @par Functions
55   @li @ref parse_absolute_uri 55   @li @ref parse_absolute_uri
56   @li @ref parse_origin_form 56   @li @ref parse_origin_form
57   @li @ref parse_relative_ref 57   @li @ref parse_relative_ref
58   @li @ref parse_uri 58   @li @ref parse_uri
59   @li @ref parse_uri_reference 59   @li @ref parse_uri_reference
60   */ 60   */
61   class BOOST_SYMBOL_VISIBLE url_base 61   class BOOST_SYMBOL_VISIBLE url_base
62   : public url_view_base 62   : public url_view_base
63   { 63   {
64   char* s_ = nullptr; 64   char* s_ = nullptr;
65   std::size_t cap_ = 0; 65   std::size_t cap_ = 0;
66   66  
67   friend class url; 67   friend class url;
68   friend class static_url_base; 68   friend class static_url_base;
69   friend class params_ref; 69   friend class params_ref;
70   friend class segments_ref; 70   friend class segments_ref;
71   friend class segments_encoded_ref; 71   friend class segments_encoded_ref;
72   friend class params_encoded_ref; 72   friend class params_encoded_ref;
73   friend struct detail::pattern; 73   friend struct detail::pattern;
74   74  
75   struct op_t 75   struct op_t
76   { 76   {
77   ~op_t(); 77   ~op_t();
78   op_t(url_base&, 78   op_t(url_base&,
79   core::string_view* = nullptr, 79   core::string_view* = nullptr,
80   core::string_view* = nullptr) noexcept; 80   core::string_view* = nullptr) noexcept;
81   void move(char*, char const*, 81   void move(char*, char const*,
82   std::size_t) noexcept; 82   std::size_t) noexcept;
83   83  
84   url_base& u; 84   url_base& u;
85   core::string_view* s0 = nullptr; 85   core::string_view* s0 = nullptr;
86   core::string_view* s1 = nullptr; 86   core::string_view* s1 = nullptr;
87   char* old = nullptr; 87   char* old = nullptr;
88   }; 88   };
89   89  
HITCBC 90   7297 virtual ~url_base() noexcept = default; 90   7302 virtual ~url_base() noexcept = default;
HITCBC 91   5650 url_base() noexcept = default; 91   5655 url_base() noexcept = default;
92   url_base(detail::url_impl const&) noexcept; 92   url_base(detail::url_impl const&) noexcept;
93   explicit url_base(core::string_view); 93   explicit url_base(core::string_view);
94   void reserve_impl(std::size_t n); 94   void reserve_impl(std::size_t n);
95   void copy(url_view_base const&); 95   void copy(url_view_base const&);
96   virtual void clear_impl() noexcept = 0; 96   virtual void clear_impl() noexcept = 0;
97   virtual void reserve_impl( 97   virtual void reserve_impl(
98   std::size_t, op_t&) = 0; 98   std::size_t, op_t&) = 0;
99   virtual void cleanup(op_t&) = 0; 99   virtual void cleanup(op_t&) = 0;
100   100  
101   public: 101   public:
102   //-------------------------------------------- 102   //--------------------------------------------
103   // 103   //
104   // Observers 104   // Observers
105   // 105   //
106   //-------------------------------------------- 106   //--------------------------------------------
107   107  
108   /** Return the url as a null-terminated string 108   /** Return the url as a null-terminated string
109   109  
110   This function returns a pointer to a null 110   This function returns a pointer to a null
111   terminated string representing the url, 111   terminated string representing the url,
112   which may contain percent escapes. 112   which may contain percent escapes.
113   113  
114   @return A pointer to a null-terminated string containing the URL. 114   @return A pointer to a null-terminated string containing the URL.
115   115  
116   @par Example 116   @par Example
117   @code 117   @code
118   assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 ); 118   assert( std::strlen( url( "http://www.example.com" ).c_str() ) == 22 );
119   @endcode 119   @endcode
120   120  
121   @par Complexity 121   @par Complexity
122   Constant. 122   Constant.
123   123  
124   @par Exception Safety 124   @par Exception Safety
125   Throws nothing. 125   Throws nothing.
126   */ 126   */
127   char const* 127   char const*
HITCBC 128   43554 c_str() const noexcept 128   43574 c_str() const noexcept
129   { 129   {
HITCBC 130   43554 return impl().cs_; 130   43574 return impl().cs_;
131   } 131   }
132   132  
133   /** Return the number of characters that can be stored without reallocating 133   /** Return the number of characters that can be stored without reallocating
134   134  
135   This does not include the null terminator, 135   This does not include the null terminator,
136   which is always present. 136   which is always present.
137   137  
138   @return `*this` 138   @return `*this`
139   139  
140   @par Complexity 140   @par Complexity
141   Constant. 141   Constant.
142   142  
143   @par Exception Safety 143   @par Exception Safety
144   Throws nothing. 144   Throws nothing.
145   */ 145   */
146   std::size_t 146   std::size_t
HITCBC 147   10 capacity() const noexcept 147   10 capacity() const noexcept
148   { 148   {
HITCBC 149   10 return cap_; 149   10 return cap_;
150   } 150   }
151   151  
152   /** Clear the contents while preserving the capacity 152   /** Clear the contents while preserving the capacity
153   153  
154   @par Postconditions 154   @par Postconditions
155   @code 155   @code
156   this->empty() == true 156   this->empty() == true
157   @endcode 157   @endcode
158   158  
159   @par Complexity 159   @par Complexity
160   Constant. 160   Constant.
161   161  
162   @par Exception Safety 162   @par Exception Safety
163   No-throw guarantee. 163   No-throw guarantee.
164   */ 164   */
165   void 165   void
HITCBC 166   273 clear() noexcept 166   273 clear() noexcept
167   { 167   {
HITCBC 168   273 this->clear_impl(); 168   273 this->clear_impl();
HITCBC 169   273 } 169   273 }
170   170  
171   /** Adjust the capacity without changing the size 171   /** Adjust the capacity without changing the size
172   172  
173   This function adjusts the capacity 173   This function adjusts the capacity
174   of the container in characters, without 174   of the container in characters, without
175   affecting the current contents. Has 175   affecting the current contents. Has
176   no effect if `n <= this->capacity()`. 176   no effect if `n <= this->capacity()`.
177   177  
178   @par Exception Safety 178   @par Exception Safety
179   Strong guarantee. 179   Strong guarantee.
180   Calls to allocate may throw. 180   Calls to allocate may throw.
181   181  
182   @throw bad_alloc Allocation failure 182   @throw bad_alloc Allocation failure
183   183  
184   @param n The capacity in characters, 184   @param n The capacity in characters,
185   excluding any null terminator. 185   excluding any null terminator.
186   */ 186   */
187   void 187   void
HITCBC 188   305 reserve(std::size_t n) 188   305 reserve(std::size_t n)
189   { 189   {
HITCBC 190   305 reserve_impl(n); 190   305 reserve_impl(n);
HITCBC 191   304 } 191   304 }
192   192  
193   //-------------------------------------------- 193   //--------------------------------------------
194   // 194   //
195   // Fluent API 195   // Fluent API
196   // 196   //
197   197  
198   //-------------------------------------------- 198   //--------------------------------------------
199   // 199   //
200   // Scheme 200   // Scheme
201   // 201   //
202   //-------------------------------------------- 202   //--------------------------------------------
203   203  
204   /** Set the scheme 204   /** Set the scheme
205   205  
206   The scheme is set to the specified 206   The scheme is set to the specified
207   string, which must contain a valid 207   string, which must contain a valid
208   scheme without any trailing colon 208   scheme without any trailing colon
209   (':'). 209   (':').
210   Note that schemes are case-insensitive, 210   Note that schemes are case-insensitive,
211   and the canonical form is lowercased. 211   and the canonical form is lowercased.
212   212  
213   @par Example 213   @par Example
214   @code 214   @code
215   assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https ); 215   assert( url( "http://www.example.com" ).set_scheme( "https" ).scheme_id() == scheme::https );
216   @endcode 216   @endcode
217   217  
218   @par Complexity 218   @par Complexity
219   Linear in `this->size() + s.size()`. 219   Linear in `this->size() + s.size()`.
220   220  
221   @par Exception Safety 221   @par Exception Safety
222   Strong guarantee. 222   Strong guarantee.
223   Calls to allocate may throw. 223   Calls to allocate may throw.
224   Exceptions thrown on invalid input. 224   Exceptions thrown on invalid input.
225   225  
226   @throw system_error 226   @throw system_error
227   `s` contains an invalid scheme. 227   `s` contains an invalid scheme.
228   228  
229   @param s The scheme to set. 229   @param s The scheme to set.
230   230  
231   @return `*this` 231   @return `*this`
232   232  
233   @par BNF 233   @par BNF
234   @code 234   @code
235   scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 235   scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
236   @endcode 236   @endcode
237   237  
238   @par Specification 238   @par Specification
239   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"> 239   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
240   3.1. Scheme (rfc3986)</a> 240   3.1. Scheme (rfc3986)</a>
241   241  
242   @see 242   @see
243   @ref remove_scheme. 243   @ref remove_scheme.
244   */ 244   */
245   url_base& 245   url_base&
246   set_scheme(core::string_view s); 246   set_scheme(core::string_view s);
247   247  
248   /** Set the scheme 248   /** Set the scheme
249   249  
250   This function sets the scheme to the specified 250   This function sets the scheme to the specified
251   known @ref urls::scheme id, which may not be 251   known @ref urls::scheme id, which may not be
252   @ref scheme::unknown or else an exception is 252   @ref scheme::unknown or else an exception is
253   thrown. If the id is @ref scheme::none, this 253   thrown. If the id is @ref scheme::none, this
254   function behaves as if @ref remove_scheme 254   function behaves as if @ref remove_scheme
255   were called. 255   were called.
256   256  
257   @par Example 257   @par Example
258   @code 258   @code
259   assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" ); 259   assert( url( "http://example.com/echo.cgi" ).set_scheme_id( scheme::wss ).buffer() == "wss://example.com/echo.cgi" );
260   @endcode 260   @endcode
261   261  
262   @par Complexity 262   @par Complexity
263   Linear in `this->size()`. 263   Linear in `this->size()`.
264   264  
265   @par Exception Safety 265   @par Exception Safety
266   Strong guarantee. 266   Strong guarantee.
267   Calls to allocate may throw. 267   Calls to allocate may throw.
268   Exceptions thrown on invalid input. 268   Exceptions thrown on invalid input.
269   269  
270   @throw system_error 270   @throw system_error
271   The scheme is invalid. 271   The scheme is invalid.
272   272  
273   @param id The scheme to set. 273   @param id The scheme to set.
274   @return `*this` 274   @return `*this`
275   275  
276   @par Specification 276   @par Specification
277   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"> 277   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
278   3.1. Scheme (rfc3986)</a> 278   3.1. Scheme (rfc3986)</a>
279   */ 279   */
280   url_base& 280   url_base&
281   set_scheme_id(urls::scheme id); 281   set_scheme_id(urls::scheme id);
282   282  
283   /** Remove the scheme 283   /** Remove the scheme
284   284  
285   This function removes the scheme if it 285   This function removes the scheme if it
286   is present. 286   is present.
287   287  
288   @par Example 288   @par Example
289   @code 289   @code
290   assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" ); 290   assert( url("http://www.example.com/index.htm" ).remove_scheme().buffer() == "//www.example.com/index.htm" );
291   @endcode 291   @endcode
292   292  
293   @par Postconditions 293   @par Postconditions
294   @code 294   @code
295   this->has_scheme() == false && this->scheme_id() == scheme::none 295   this->has_scheme() == false && this->scheme_id() == scheme::none
296   @endcode 296   @endcode
297   297  
298   @par Complexity 298   @par Complexity
299   Linear in `this->size()`. 299   Linear in `this->size()`.
300   300  
301   @par Exception Safety 301   @par Exception Safety
302   Throws nothing. 302   Throws nothing.
303   303  
304   @return `*this` 304   @return `*this`
305   305  
306   @par BNF 306   @par BNF
307   @code 307   @code
308   URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 308   URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
309   @endcode 309   @endcode
310   310  
311   @par Specification 311   @par Specification
312   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1"> 312   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1">
313   3.1. Scheme (rfc3986)</a> 313   3.1. Scheme (rfc3986)</a>
314   314  
315   @see 315   @see
316   @ref set_scheme. 316   @ref set_scheme.
317   */ 317   */
318   url_base& 318   url_base&
319   remove_scheme(); 319   remove_scheme();
320   320  
321   //-------------------------------------------- 321   //--------------------------------------------
322   // 322   //
323   // Authority 323   // Authority
324   // 324   //
325   //-------------------------------------------- 325   //--------------------------------------------
326   326  
327   /** Set the authority 327   /** Set the authority
328   328  
329   This function sets the authority 329   This function sets the authority
330   to the specified string. 330   to the specified string.
331   The string may contain percent-escapes. 331   The string may contain percent-escapes.
332   332  
333   @par Example 333   @par Example
334   @code 334   @code
335   assert( url().set_encoded_authority( "My%20Computer" ).has_authority() ); 335   assert( url().set_encoded_authority( "My%20Computer" ).has_authority() );
336   @endcode 336   @endcode
337   337  
338   @par Exception Safety 338   @par Exception Safety
339   Strong guarantee. 339   Strong guarantee.
340   Calls to allocate may throw. 340   Calls to allocate may throw.
341   Exceptions thrown on invalid input. 341   Exceptions thrown on invalid input.
342   342  
343   @throw system_eror 343   @throw system_eror
344   The string contains an invalid percent-encoding. 344   The string contains an invalid percent-encoding.
345   345  
346   @param s The authority string to set. 346   @param s The authority string to set.
347   @return `*this` 347   @return `*this`
348   348  
349   @par BNF 349   @par BNF
350   @code 350   @code
351   authority = [ userinfo "@" ] host [ ":" port ] 351   authority = [ userinfo "@" ] host [ ":" port ]
352   352  
353   userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 353   userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
354   host = IP-literal / IPv4address / reg-name 354   host = IP-literal / IPv4address / reg-name
355   port = *DIGIT 355   port = *DIGIT
356   @endcode 356   @endcode
357   357  
358   @par Specification 358   @par Specification
359   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"> 359   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
360   3.2. Authority (rfc3986)</a> 360   3.2. Authority (rfc3986)</a>
361   @see 361   @see
362   @ref remove_authority. 362   @ref remove_authority.
363   */ 363   */
364   url_base& 364   url_base&
365   set_encoded_authority( 365   set_encoded_authority(
366   pct_string_view s); 366   pct_string_view s);
367   367  
368   /** Remove the authority 368   /** Remove the authority
369   369  
370   This function removes the authority, 370   This function removes the authority,
371   which includes the userinfo, host, and 371   which includes the userinfo, host, and
372   a port if present. 372   a port if present.
373   373  
374   @par Example 374   @par Example
375   @code 375   @code
376   assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" ); 376   assert( url( "http://example.com/echo.cgi" ).remove_authority().buffer() == "http:/echo.cgi" );
377   @endcode 377   @endcode
378   378  
379   @par Postconditions 379   @par Postconditions
380   @code 380   @code
381   this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false 381   this->has_authority() == false && this->has_userinfo() == false && this->has_port() == false
382   @endcode 382   @endcode
383   383  
384   @par Complexity 384   @par Complexity
385   Linear in `this->size()`. 385   Linear in `this->size()`.
386   386  
387   @par Exception Safety 387   @par Exception Safety
388   Throws nothing. 388   Throws nothing.
389   389  
390   @return `*this` 390   @return `*this`
391   391  
392   @par BNF 392   @par BNF
393   @code 393   @code
394   authority = [ userinfo "@" ] host [ ":" port ] 394   authority = [ userinfo "@" ] host [ ":" port ]
395   395  
396   userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 396   userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
397   host = IP-literal / IPv4address / reg-name 397   host = IP-literal / IPv4address / reg-name
398   port = *DIGIT 398   port = *DIGIT
399   @endcode 399   @endcode
400   400  
401   @par Specification 401   @par Specification
402   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"> 402   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">
403   3.2. Authority (rfc3986)</a> 403   3.2. Authority (rfc3986)</a>
404   404  
405   @see 405   @see
406   @ref set_encoded_authority. 406   @ref set_encoded_authority.
407   */ 407   */
408   url_base& 408   url_base&
409   remove_authority(); 409   remove_authority();
410   410  
411   //-------------------------------------------- 411   //--------------------------------------------
412   // 412   //
413   // Userinfo 413   // Userinfo
414   // 414   //
415   //-------------------------------------------- 415   //--------------------------------------------
416   416  
417   /** Set the userinfo 417   /** Set the userinfo
418   418  
419   The userinfo is set to the given string, 419   The userinfo is set to the given string,
420   which may contain percent-escapes. 420   which may contain percent-escapes.
421   Any special or reserved characters in the 421   Any special or reserved characters in the
422   string are automatically percent-encoded. 422   string are automatically percent-encoded.
423   The effects on the user and password 423   The effects on the user and password
424   depend on the presence of a colon (':') 424   depend on the presence of a colon (':')
425   in the string: 425   in the string:
426   426  
427   @li If an unescaped colon exists, the 427   @li If an unescaped colon exists, the
428   characters up to the colon become 428   characters up to the colon become
429   the user and the rest of the characters 429   the user and the rest of the characters
430   after the colon become the password. 430   after the colon become the password.
431   In this case @ref has_password returns 431   In this case @ref has_password returns
432   true. Otherwise, 432   true. Otherwise,
433   433  
434   @li If there is no colon, the user is 434   @li If there is no colon, the user is
435   set to the string. The function 435   set to the string. The function
436   @ref has_password returns false. 436   @ref has_password returns false.
437   437  
438   @note 438   @note
439   The interpretation of the userinfo as 439   The interpretation of the userinfo as
440   individual user and password components 440   individual user and password components
441   is scheme-dependent. Transmitting 441   is scheme-dependent. Transmitting
442   passwords in URLs is deprecated. 442   passwords in URLs is deprecated.
443   443  
444   @par Example 444   @par Example
445   @code 445   @code
446   assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" ); 446   assert( url( "http://example.com" ).set_userinfo( "user:pass" ).encoded_user() == "user" );
447   @endcode 447   @endcode
448   448  
449   @par Complexity 449   @par Complexity
450   Linear in `this->size() + s.size()`. 450   Linear in `this->size() + s.size()`.
451   451  
452   @par Exception Safety 452   @par Exception Safety
453   Strong guarantee. 453   Strong guarantee.
454   Calls to allocate may throw. 454   Calls to allocate may throw.
455   455  
456   @param s The string to set. 456   @param s The string to set.
457   @return `*this` 457   @return `*this`
458   458  
459   @par BNF 459   @par BNF
460   @code 460   @code
461   userinfo = [ [ user ] [ ':' password ] ] 461   userinfo = [ [ user ] [ ':' password ] ]
462   462  
463   user = *( unreserved / pct-encoded / sub-delims ) 463   user = *( unreserved / pct-encoded / sub-delims )
464   password = *( unreserved / pct-encoded / sub-delims / ":" ) 464   password = *( unreserved / pct-encoded / sub-delims / ":" )
465   @endcode 465   @endcode
466   466  
467   @par Specification 467   @par Specification
468   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 468   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
469   3.2.1. User Information (rfc3986)</a> 469   3.2.1. User Information (rfc3986)</a>
470   470  
471   @see 471   @see
472   @ref remove_userinfo, 472   @ref remove_userinfo,
473   @ref set_encoded_userinfo. 473   @ref set_encoded_userinfo.
474   */ 474   */
475   url_base& 475   url_base&
476   set_userinfo( 476   set_userinfo(
477   core::string_view s); 477   core::string_view s);
478   478  
479   /** Set the userinfo. 479   /** Set the userinfo.
480   480  
481   The userinfo is set to the given string, 481   The userinfo is set to the given string,
482   which may contain percent-escapes. 482   which may contain percent-escapes.
483   Escapes in the string are preserved, 483   Escapes in the string are preserved,
484   and reserved characters in the string 484   and reserved characters in the string
485   are percent-escaped in the result. 485   are percent-escaped in the result.
486   The effects on the user and password 486   The effects on the user and password
487   depend on the presence of a colon (':') 487   depend on the presence of a colon (':')
488   in the string: 488   in the string:
489   489  
490   @li If an unescaped colon exists, the 490   @li If an unescaped colon exists, the
491   characters up to the colon become 491   characters up to the colon become
492   the user and the rest of the characters 492   the user and the rest of the characters
493   after the colon become the password. 493   after the colon become the password.
494   In this case @ref has_password returns 494   In this case @ref has_password returns
495   true. Otherwise, 495   true. Otherwise,
496   496  
497   @li If there is no colon, the user is 497   @li If there is no colon, the user is
498   set to the string. The function 498   set to the string. The function
499   @ref has_password returns false. 499   @ref has_password returns false.
500   500  
501   @note 501   @note
502   The interpretation of the userinfo as 502   The interpretation of the userinfo as
503   individual user and password components 503   individual user and password components
504   is scheme-dependent. Transmitting 504   is scheme-dependent. Transmitting
505   passwords in URLs is deprecated. 505   passwords in URLs is deprecated.
506   506  
507   @par Example 507   @par Example
508   @code 508   @code
509   assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" ); 509   assert( url( "http://example.com" ).set_encoded_userinfo( "john%20doe" ).user() == "john doe" );
510   @endcode 510   @endcode
511   511  
512   @par Complexity 512   @par Complexity
513   Linear in `this->size() + s.size()`. 513   Linear in `this->size() + s.size()`.
514   514  
515   @par Exception Safety 515   @par Exception Safety
516   Strong guarantee. 516   Strong guarantee.
517   Calls to allocate may throw. 517   Calls to allocate may throw.
518   Exceptions thrown on invalid input. 518   Exceptions thrown on invalid input.
519   519  
520   @throw system_error 520   @throw system_error
521   `s` contains an invalid percent-encoding. 521   `s` contains an invalid percent-encoding.
522   522  
523   @param s The string to set. 523   @param s The string to set.
524   @return `*this` 524   @return `*this`
525   525  
526   @par BNF 526   @par BNF
527   @code 527   @code
528   userinfo = [ [ user ] [ ':' password ] ] 528   userinfo = [ [ user ] [ ':' password ] ]
529   529  
530   user = *( unreserved / pct-encoded / sub-delims ) 530   user = *( unreserved / pct-encoded / sub-delims )
531   password = *( unreserved / pct-encoded / sub-delims / ":" ) 531   password = *( unreserved / pct-encoded / sub-delims / ":" )
532   @endcode 532   @endcode
533   533  
534   @par Specification 534   @par Specification
535   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 535   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
536   3.2.1. User Information (rfc3986)</a> 536   3.2.1. User Information (rfc3986)</a>
537   537  
538   @see 538   @see
539   @ref remove_userinfo, 539   @ref remove_userinfo,
540   @ref set_userinfo. 540   @ref set_userinfo.
541   */ 541   */
542   url_base& 542   url_base&
543   set_encoded_userinfo( 543   set_encoded_userinfo(
544   pct_string_view s); 544   pct_string_view s);
545   545  
546   /** Remove the userinfo 546   /** Remove the userinfo
547   547  
548   This function removes the userinfo if 548   This function removes the userinfo if
549   present, without removing any authority. 549   present, without removing any authority.
550   550  
551   @par Example 551   @par Example
552   @code 552   @code
553   assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false ); 553   assert( url( "http://user@example.com" ).remove_userinfo().has_userinfo() == false );
554   @endcode 554   @endcode
555   555  
556   @par Postconditions 556   @par Postconditions
557   @code 557   @code
558   this->has_userinfo() == false && this->encoded_userinfo().empty == true 558   this->has_userinfo() == false && this->encoded_userinfo().empty == true
559   @endcode 559   @endcode
560   560  
561   @par Complexity 561   @par Complexity
562   Linear in `this->size()`. 562   Linear in `this->size()`.
563   563  
564   @par Exception Safety 564   @par Exception Safety
565   Throws nothing. 565   Throws nothing.
566   566  
567   @return `*this` 567   @return `*this`
568   568  
569   @par BNF 569   @par BNF
570   @code 570   @code
571   userinfo = [ [ user ] [ ':' password ] ] 571   userinfo = [ [ user ] [ ':' password ] ]
572   572  
573   user = *( unreserved / pct-encoded / sub-delims ) 573   user = *( unreserved / pct-encoded / sub-delims )
574   password = *( unreserved / pct-encoded / sub-delims / ":" ) 574   password = *( unreserved / pct-encoded / sub-delims / ":" )
575   @endcode 575   @endcode
576   576  
577   @par Specification 577   @par Specification
578   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 578   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
579   3.2.1. User Information (rfc3986)</a> 579   3.2.1. User Information (rfc3986)</a>
580   580  
581   @see 581   @see
582   @ref set_encoded_userinfo, 582   @ref set_encoded_userinfo,
583   @ref set_userinfo. 583   @ref set_userinfo.
584   */ 584   */
585   url_base& 585   url_base&
586   remove_userinfo() noexcept; 586   remove_userinfo() noexcept;
587   587  
588   //-------------------------------------------- 588   //--------------------------------------------
589   589  
590   /** Set the user 590   /** Set the user
591   591  
592   This function sets the user part of the 592   This function sets the user part of the
593   userinfo to the string. 593   userinfo to the string.
594   Any special or reserved characters in the 594   Any special or reserved characters in the
595   string are automatically percent-encoded. 595   string are automatically percent-encoded.
596   596  
597   @par Example 597   @par Example
598   @code 598   @code
599   assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" ); 599   assert( url().set_user("john doe").encoded_userinfo() == "john%20doe" );
600   @endcode 600   @endcode
601   601  
602   @par Postconditions 602   @par Postconditions
603   @code 603   @code
604   this->has_authority() == true && this->has_userinfo() == true 604   this->has_authority() == true && this->has_userinfo() == true
605   @endcode 605   @endcode
606   606  
607   @par Complexity 607   @par Complexity
608   Linear in `this->size() + s.size()`. 608   Linear in `this->size() + s.size()`.
609   609  
610   @par Exception Safety 610   @par Exception Safety
611   Strong guarantee. 611   Strong guarantee.
612   Calls to allocate may throw. 612   Calls to allocate may throw.
613   613  
614   @param s The string to set. 614   @param s The string to set.
615   @return `*this` 615   @return `*this`
616   616  
617   @par BNF 617   @par BNF
618   @code 618   @code
619   userinfo = [ [ user ] [ ':' password ] ] 619   userinfo = [ [ user ] [ ':' password ] ]
620   620  
621   user = *( unreserved / pct-encoded / sub-delims ) 621   user = *( unreserved / pct-encoded / sub-delims )
622   password = *( unreserved / pct-encoded / sub-delims / ":" ) 622   password = *( unreserved / pct-encoded / sub-delims / ":" )
623   @endcode 623   @endcode
624   624  
625   @par Specification 625   @par Specification
626   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 626   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
627   3.2.1. User Information (rfc3986)</a> 627   3.2.1. User Information (rfc3986)</a>
628   628  
629   @see 629   @see
630   @ref remove_password, 630   @ref remove_password,
631   @ref set_encoded_password, 631   @ref set_encoded_password,
632   @ref set_encoded_user, 632   @ref set_encoded_user,
633   @ref set_password. 633   @ref set_password.
634   */ 634   */
635   url_base& 635   url_base&
636   set_user( 636   set_user(
637   core::string_view s); 637   core::string_view s);
638   638  
639   /** Set the user 639   /** Set the user
640   640  
641   This function sets the user part of the 641   This function sets the user part of the
642   userinfo the the string, which may 642   userinfo the the string, which may
643   contain percent-escapes. 643   contain percent-escapes.
644   Escapes in the string are preserved, 644   Escapes in the string are preserved,
645   and reserved characters in the string 645   and reserved characters in the string
646   are percent-escaped in the result. 646   are percent-escaped in the result.
647   647  
648   @par Example 648   @par Example
649   @code 649   @code
650   assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" ); 650   assert( url().set_encoded_user("john%20doe").userinfo() == "john doe" );
651   @endcode 651   @endcode
652   652  
653   @par Postconditions 653   @par Postconditions
654   @code 654   @code
655   this->has_authority() == true && this->has_userinfo() == true 655   this->has_authority() == true && this->has_userinfo() == true
656   @endcode 656   @endcode
657   657  
658   @par Complexity 658   @par Complexity
659   Linear in `this->size() + s.size()`. 659   Linear in `this->size() + s.size()`.
660   660  
661   @par Exception Safety 661   @par Exception Safety
662   Strong guarantee. 662   Strong guarantee.
663   Calls to allocate may throw. 663   Calls to allocate may throw.
664   664  
665   @throw system_error 665   @throw system_error
666   `s` contains an invalid percent-encoding. 666   `s` contains an invalid percent-encoding.
667   667  
668   @param s The string to set. 668   @param s The string to set.
669   669  
670   @return `*this` 670   @return `*this`
671   671  
672   @return `*this` 672   @return `*this`
673   673  
674   @par BNF 674   @par BNF
675   @code 675   @code
676   userinfo = [ [ user ] [ ':' password ] ] 676   userinfo = [ [ user ] [ ':' password ] ]
677   677  
678   user = *( unreserved / pct-encoded / sub-delims ) 678   user = *( unreserved / pct-encoded / sub-delims )
679   password = *( unreserved / pct-encoded / sub-delims / ":" ) 679   password = *( unreserved / pct-encoded / sub-delims / ":" )
680   @endcode 680   @endcode
681   681  
682   @par Specification 682   @par Specification
683   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 683   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
684   3.2.1. User Information (rfc3986)</a> 684   3.2.1. User Information (rfc3986)</a>
685   685  
686   @see 686   @see
687   @ref remove_password, 687   @ref remove_password,
688   @ref set_encoded_password, 688   @ref set_encoded_password,
689   @ref set_password, 689   @ref set_password,
690   @ref set_user. 690   @ref set_user.
691   */ 691   */
692   url_base& 692   url_base&
693   set_encoded_user( 693   set_encoded_user(
694   pct_string_view s); 694   pct_string_view s);
695   695  
696   /** Set the password. 696   /** Set the password.
697   697  
698   This function sets the password in 698   This function sets the password in
699   the userinfo to the string. 699   the userinfo to the string.
700   Reserved characters in the string are 700   Reserved characters in the string are
701   percent-escaped in the result. 701   percent-escaped in the result.
702   702  
703   @note 703   @note
704   The interpretation of the userinfo as 704   The interpretation of the userinfo as
705   individual user and password components 705   individual user and password components
706   is scheme-dependent. Transmitting 706   is scheme-dependent. Transmitting
707   passwords in URLs is deprecated. 707   passwords in URLs is deprecated.
708   708  
709   @par Example 709   @par Example
710   @code 710   @code
711   assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" ); 711   assert( url("http://user@example.com").set_password( "pass" ).encoded_userinfo() == "user:pass" );
712   @endcode 712   @endcode
713   713  
714   @par Postconditions 714   @par Postconditions
715   @code 715   @code
716   this->has_password() == true && this->password() == s 716   this->has_password() == true && this->password() == s
717   @endcode 717   @endcode
718   718  
719   @par Exception Safety 719   @par Exception Safety
720   Strong guarantee. 720   Strong guarantee.
721   Calls to allocate may throw. 721   Calls to allocate may throw.
722   722  
723   @param s The string to set. This string may 723   @param s The string to set. This string may
724   contain any characters, including nulls. 724   contain any characters, including nulls.
725   725  
726   @return `*this` 726   @return `*this`
727   727  
728   @par BNF 728   @par BNF
729   @code 729   @code
730   userinfo = [ [ user ] [ ':' password ] ] 730   userinfo = [ [ user ] [ ':' password ] ]
731   731  
732   user = *( unreserved / pct-encoded / sub-delims ) 732   user = *( unreserved / pct-encoded / sub-delims )
733   password = *( unreserved / pct-encoded / sub-delims / ":" ) 733   password = *( unreserved / pct-encoded / sub-delims / ":" )
734   @endcode 734   @endcode
735   735  
736   @par Specification 736   @par Specification
737   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 737   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
738   3.2.1. User Information (rfc3986)</a> 738   3.2.1. User Information (rfc3986)</a>
739   739  
740   @see 740   @see
741   @ref remove_password, 741   @ref remove_password,
742   @ref set_encoded_password, 742   @ref set_encoded_password,
743   @ref set_encoded_user, 743   @ref set_encoded_user,
744   @ref set_user. 744   @ref set_user.
745   */ 745   */
746   url_base& 746   url_base&
747   set_password( 747   set_password(
748   core::string_view s); 748   core::string_view s);
749   749  
750   /** Set the password. 750   /** Set the password.
751   751  
752   This function sets the password in 752   This function sets the password in
753   the userinfo to the string, which 753   the userinfo to the string, which
754   may contain percent-escapes. 754   may contain percent-escapes.
755   Escapes in the string are preserved, 755   Escapes in the string are preserved,
756   and reserved characters in the string 756   and reserved characters in the string
757   are percent-escaped in the result. 757   are percent-escaped in the result.
758   758  
759   @note 759   @note
760   The interpretation of the userinfo as 760   The interpretation of the userinfo as
761   individual user and password components 761   individual user and password components
762   is scheme-dependent. Transmitting 762   is scheme-dependent. Transmitting
763   passwords in URLs is deprecated. 763   passwords in URLs is deprecated.
764   764  
765   @par Example 765   @par Example
766   @code 766   @code
767   assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" ); 767   assert( url("http://user@example.com").set_encoded_password( "pass" ).encoded_userinfo() == "user:pass" );
768   @endcode 768   @endcode
769   769  
770   @par Postconditions 770   @par Postconditions
771   @code 771   @code
772   this->has_password() == true 772   this->has_password() == true
773   @endcode 773   @endcode
774   774  
775   @par Exception Safety 775   @par Exception Safety
776   Strong guarantee. 776   Strong guarantee.
777   Calls to allocate may throw. 777   Calls to allocate may throw.
778   778  
779   @throw system_error 779   @throw system_error
780   `s` contains an invalid percent-encoding. 780   `s` contains an invalid percent-encoding.
781   781  
782   @param s The string to set. This string may 782   @param s The string to set. This string may
783   contain any characters, including nulls. 783   contain any characters, including nulls.
784   @return `*this` 784   @return `*this`
785   785  
786   @par BNF 786   @par BNF
787   @code 787   @code
788   userinfo = [ [ user ] [ ':' password ] ] 788   userinfo = [ [ user ] [ ':' password ] ]
789   789  
790   user = *( unreserved / pct-encoded / sub-delims ) 790   user = *( unreserved / pct-encoded / sub-delims )
791   password = *( unreserved / pct-encoded / sub-delims / ":" ) 791   password = *( unreserved / pct-encoded / sub-delims / ":" )
792   @endcode 792   @endcode
793   793  
794   @par Specification 794   @par Specification
795   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 795   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
796   3.2.1. User Information (rfc3986)</a> 796   3.2.1. User Information (rfc3986)</a>
797   797  
798   @see 798   @see
799   @ref remove_password, 799   @ref remove_password,
800   @ref set_encoded_password, 800   @ref set_encoded_password,
801   @ref set_encoded_user, 801   @ref set_encoded_user,
802   @ref set_user. 802   @ref set_user.
803   */ 803   */
804   url_base& 804   url_base&
805   set_encoded_password( 805   set_encoded_password(
806   pct_string_view s); 806   pct_string_view s);
807   807  
808   /** Remove the password 808   /** Remove the password
809   809  
810   This function removes the password from 810   This function removes the password from
811   the userinfo if a password exists. If 811   the userinfo if a password exists. If
812   there is no userinfo or no authority, 812   there is no userinfo or no authority,
813   the call has no effect. 813   the call has no effect.
814   814  
815   @note 815   @note
816   The interpretation of the userinfo as 816   The interpretation of the userinfo as
817   individual user and password components 817   individual user and password components
818   is scheme-dependent. Transmitting 818   is scheme-dependent. Transmitting
819   passwords in URLs is deprecated. 819   passwords in URLs is deprecated.
820   820  
821   @par Example 821   @par Example
822   @code 822   @code
823   assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" ); 823   assert( url( "http://user:pass@example.com" ).remove_password().authority().buffer() == "user@example.com" );
824   @endcode 824   @endcode
825   825  
826   @par Postconditions 826   @par Postconditions
827   @code 827   @code
828   this->has_password() == false && this->encoded_password().empty() == true 828   this->has_password() == false && this->encoded_password().empty() == true
829   @endcode 829   @endcode
830   830  
831   @par Complexity 831   @par Complexity
832   Linear in `this->size()`. 832   Linear in `this->size()`.
833   833  
834   @par Exception Safety 834   @par Exception Safety
835   Throws nothing. 835   Throws nothing.
836   836  
837   @par BNF 837   @par BNF
838   @code 838   @code
839   userinfo = [ [ user ] [ ':' password ] ] 839   userinfo = [ [ user ] [ ':' password ] ]
840   840  
841   user = *( unreserved / pct-encoded / sub-delims ) 841   user = *( unreserved / pct-encoded / sub-delims )
842   password = *( unreserved / pct-encoded / sub-delims / ":" ) 842   password = *( unreserved / pct-encoded / sub-delims / ":" )
843   @endcode 843   @endcode
844   844  
845   @return `*this` 845   @return `*this`
846   846  
847   @par Specification 847   @par Specification
848   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"> 848   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1">
849   3.2.1. User Information (rfc3986)</a> 849   3.2.1. User Information (rfc3986)</a>
850   850  
851   @see 851   @see
852   @ref set_encoded_password, 852   @ref set_encoded_password,
853   @ref set_encoded_user, 853   @ref set_encoded_user,
854   @ref set_password, 854   @ref set_password,
855   @ref set_user. 855   @ref set_user.
856   */ 856   */
857   url_base& 857   url_base&
858   remove_password() noexcept; 858   remove_password() noexcept;
859   859  
860   //-------------------------------------------- 860   //--------------------------------------------
861   // 861   //
862   // Host 862   // Host
863   // 863   //
864   //-------------------------------------------- 864   //--------------------------------------------
865   865  
866   /** Set the host 866   /** Set the host
867   867  
868   Depending on the contents of the passed 868   Depending on the contents of the passed
869   string, this function sets the host: 869   string, this function sets the host:
870   870  
871   @li If the string is a valid IPv4 address, 871   @li If the string is a valid IPv4 address,
872   then the host is set to the address. 872   then the host is set to the address.
873   The host type is @ref host_type::ipv4. 873   The host type is @ref host_type::ipv4.
874   874  
875   @li If the string is a valid IPv6 address 875   @li If the string is a valid IPv6 address
876   enclosed in square brackets, then the 876   enclosed in square brackets, then the
877   host is set to that address. 877   host is set to that address.
878   The host type is @ref host_type::ipv6. 878   The host type is @ref host_type::ipv6.
879   879  
880   @li If the string is a valid IPvFuture 880   @li If the string is a valid IPvFuture
881   address enclosed in square brackets, then 881   address enclosed in square brackets, then
882   the host is set to that address. 882   the host is set to that address.
883   The host type is @ref host_type::ipvfuture. 883   The host type is @ref host_type::ipvfuture.
884   884  
885   @li Otherwise, the host name is set to 885   @li Otherwise, the host name is set to
886   the string, which may be empty. 886   the string, which may be empty.
887   Reserved characters in the string are 887   Reserved characters in the string are
888   percent-escaped in the result. 888   percent-escaped in the result.
889   The host type is @ref host_type::name. 889   The host type is @ref host_type::name.
890   890  
891   In all cases, when this function returns, 891   In all cases, when this function returns,
892   the URL contains an authority. 892   the URL contains an authority.
893   893  
894   @par Example 894   @par Example
895   @code 895   @code
896   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); 896   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
897   @endcode 897   @endcode
898   898  
899   @par Postconditions 899   @par Postconditions
900   @code 900   @code
901   this->has_authority() == true 901   this->has_authority() == true
902   @endcode 902   @endcode
903   903  
904   @par Complexity 904   @par Complexity
905   Linear in `this->size() + s.size()`. 905   Linear in `this->size() + s.size()`.
906   906  
907   @par Exception Safety 907   @par Exception Safety
908   Strong guarantee. 908   Strong guarantee.
909   Calls to allocate may throw. 909   Calls to allocate may throw.
910   910  
911   @par BNF 911   @par BNF
912   @code 912   @code
913   host = IP-literal / IPv4address / reg-name 913   host = IP-literal / IPv4address / reg-name
914   914  
915   IP-literal = "[" ( IPv6address / IPvFuture ) "]" 915   IP-literal = "[" ( IPv6address / IPvFuture ) "]"
916   916  
917   reg-name = *( unreserved / pct-encoded / "-" / ".") 917   reg-name = *( unreserved / pct-encoded / "-" / ".")
918   @endcode 918   @endcode
919   919  
920   @param s The string to set. 920   @param s The string to set.
921   @return `*this` 921   @return `*this`
922   922  
923   @par Specification 923   @par Specification
924   @li <a href="https://en.wikipedia.org/wiki/IPv4" 924   @li <a href="https://en.wikipedia.org/wiki/IPv4"
925   >IPv4 (Wikipedia)</a> 925   >IPv4 (Wikipedia)</a>
926   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291" 926   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
927   >IP Version 6 Addressing Architecture (rfc4291)</a> 927   >IP Version 6 Addressing Architecture (rfc4291)</a>
928   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 928   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
929   3.2.2. Host (rfc3986)</a> 929   3.2.2. Host (rfc3986)</a>
930   930  
931   @see 931   @see
932   @ref set_encoded_host, 932   @ref set_encoded_host,
933   @ref set_encoded_host_address, 933   @ref set_encoded_host_address,
934   @ref set_encoded_host_name, 934   @ref set_encoded_host_name,
935   @ref set_host_address, 935   @ref set_host_address,
936   @ref set_host_ipv4, 936   @ref set_host_ipv4,
937   @ref set_host_ipv6, 937   @ref set_host_ipv6,
938   @ref set_host_ipvfuture, 938   @ref set_host_ipvfuture,
939   @ref set_host_name. 939   @ref set_host_name.
940   */ 940   */
941   url_base& 941   url_base&
942   set_host( 942   set_host(
943   core::string_view s); 943   core::string_view s);
944   944  
945   /** Set the host 945   /** Set the host
946   946  
947   Depending on the contents of the passed 947   Depending on the contents of the passed
948   string, this function sets the host: 948   string, this function sets the host:
949   949  
950   @li If the string is a valid IPv4 address, 950   @li If the string is a valid IPv4 address,
951   then the host is set to the address. 951   then the host is set to the address.
952   The host type is @ref host_type::ipv4. 952   The host type is @ref host_type::ipv4.
953   953  
954   @li If the string is a valid IPv6 address 954   @li If the string is a valid IPv6 address
955   enclosed in square brackets, then the 955   enclosed in square brackets, then the
956   host is set to that address. 956   host is set to that address.
957   The host type is @ref host_type::ipv6. 957   The host type is @ref host_type::ipv6.
958   958  
959   @li If the string is a valid IPvFuture 959   @li If the string is a valid IPvFuture
960   address enclosed in square brackets, then 960   address enclosed in square brackets, then
961   the host is set to that address. 961   the host is set to that address.
962   The host type is @ref host_type::ipvfuture. 962   The host type is @ref host_type::ipvfuture.
963   963  
964   @li Otherwise, the host name is set to 964   @li Otherwise, the host name is set to
965   the string. This string can contain percent 965   the string. This string can contain percent
966   escapes, or can be empty. 966   escapes, or can be empty.
967   Escapes in the string are preserved, 967   Escapes in the string are preserved,
968   and reserved characters in the string 968   and reserved characters in the string
969   are percent-escaped in the result. 969   are percent-escaped in the result.
970   The host type is @ref host_type::name. 970   The host type is @ref host_type::name.
971   971  
972   In all cases, when this function returns, 972   In all cases, when this function returns,
973   the URL contains an authority. 973   the URL contains an authority.
974   974  
975   @par Example 975   @par Example
976   @code 976   @code
977   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); 977   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
978   @endcode 978   @endcode
979   979  
980   @par Postconditions 980   @par Postconditions
981   @code 981   @code
982   this->has_authority() == true 982   this->has_authority() == true
983   @endcode 983   @endcode
984   984  
985   @par Complexity 985   @par Complexity
986   Linear in `this->size() + s.size()`. 986   Linear in `this->size() + s.size()`.
987   987  
988   @par Exception Safety 988   @par Exception Safety
989   Strong guarantee. 989   Strong guarantee.
990   Calls to allocate may throw. 990   Calls to allocate may throw.
991   Exceptions thrown on invalid input. 991   Exceptions thrown on invalid input.
992   992  
993   @throw system_error 993   @throw system_error
994   `s` contains an invalid percent-encoding. 994   `s` contains an invalid percent-encoding.
995   995  
996   @param s The string to set. 996   @param s The string to set.
997   997  
998   @return `*this` 998   @return `*this`
999   999  
1000   @par BNF 1000   @par BNF
1001   @code 1001   @code
1002   host = IP-literal / IPv4address / reg-name 1002   host = IP-literal / IPv4address / reg-name
1003   1003  
1004   IP-literal = "[" ( IPv6address / IPvFuture ) "]" 1004   IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1005   1005  
1006   reg-name = *( unreserved / pct-encoded / "-" / ".") 1006   reg-name = *( unreserved / pct-encoded / "-" / ".")
1007   @endcode 1007   @endcode
1008   1008  
1009   @par Specification 1009   @par Specification
1010   @li <a href="https://en.wikipedia.org/wiki/IPv4" 1010   @li <a href="https://en.wikipedia.org/wiki/IPv4"
1011   >IPv4 (Wikipedia)</a> 1011   >IPv4 (Wikipedia)</a>
1012   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291" 1012   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1013   >IP Version 6 Addressing Architecture (rfc4291)</a> 1013   >IP Version 6 Addressing Architecture (rfc4291)</a>
1014   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1014   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1015   3.2.2. Host (rfc3986)</a> 1015   3.2.2. Host (rfc3986)</a>
1016   1016  
1017   @see 1017   @see
1018   @ref set_encoded_host_address, 1018   @ref set_encoded_host_address,
1019   @ref set_encoded_host_name, 1019   @ref set_encoded_host_name,
1020   @ref set_host, 1020   @ref set_host,
1021   @ref set_host_address, 1021   @ref set_host_address,
1022   @ref set_host_ipv4, 1022   @ref set_host_ipv4,
1023   @ref set_host_ipv6, 1023   @ref set_host_ipv6,
1024   @ref set_host_ipvfuture, 1024   @ref set_host_ipvfuture,
1025   @ref set_host_name. 1025   @ref set_host_name.
1026   */ 1026   */
1027   url_base& 1027   url_base&
1028   set_encoded_host(pct_string_view s); 1028   set_encoded_host(pct_string_view s);
1029   1029  
1030   /** Set the host to an address 1030   /** Set the host to an address
1031   1031  
1032   Depending on the contents of the passed 1032   Depending on the contents of the passed
1033   string, this function sets the host: 1033   string, this function sets the host:
1034   1034  
1035   @li If the string is a valid IPv4 address, 1035   @li If the string is a valid IPv4 address,
1036   then the host is set to the address. 1036   then the host is set to the address.
1037   The host type is @ref host_type::ipv4. 1037   The host type is @ref host_type::ipv4.
1038   1038  
1039   @li If the string is a valid IPv6 address, 1039   @li If the string is a valid IPv6 address,
1040   then the host is set to that address. 1040   then the host is set to that address.
1041   The host type is @ref host_type::ipv6. 1041   The host type is @ref host_type::ipv6.
1042   1042  
1043   @li If the string is a valid IPvFuture, 1043   @li If the string is a valid IPvFuture,
1044   then the host is set to that address. 1044   then the host is set to that address.
1045   The host type is @ref host_type::ipvfuture. 1045   The host type is @ref host_type::ipvfuture.
1046   1046  
1047   @li Otherwise, the host name is set to 1047   @li Otherwise, the host name is set to
1048   the string, which may be empty. 1048   the string, which may be empty.
1049   Reserved characters in the string are 1049   Reserved characters in the string are
1050   percent-escaped in the result. 1050   percent-escaped in the result.
1051   The host type is @ref host_type::name. 1051   The host type is @ref host_type::name.
1052   1052  
1053   In all cases, when this function returns, 1053   In all cases, when this function returns,
1054   the URL contains an authority. 1054   the URL contains an authority.
1055   1055  
1056   @par Example 1056   @par Example
1057   @code 1057   @code
1058   assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); 1058   assert( url( "http://www.example.com" ).set_host_address( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1059   @endcode 1059   @endcode
1060   1060  
1061   @par Postconditions 1061   @par Postconditions
1062   @code 1062   @code
1063   this->has_authority() == true 1063   this->has_authority() == true
1064   @endcode 1064   @endcode
1065   1065  
1066   @par Complexity 1066   @par Complexity
1067   Linear in `s.size()`. 1067   Linear in `s.size()`.
1068   1068  
1069   @par Exception Safety 1069   @par Exception Safety
1070   Strong guarantee. 1070   Strong guarantee.
1071   Calls to allocate may throw. 1071   Calls to allocate may throw.
1072   1072  
1073   @par BNF 1073   @par BNF
1074   @code 1074   @code
1075   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 1075   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1076   1076  
1077   dec-octet = DIGIT ; 0-9 1077   dec-octet = DIGIT ; 0-9
1078   / %x31-39 DIGIT ; 10-99 1078   / %x31-39 DIGIT ; 10-99
1079   / "1" 2DIGIT ; 100-199 1079   / "1" 2DIGIT ; 100-199
1080   / "2" %x30-34 DIGIT ; 200-249 1080   / "2" %x30-34 DIGIT ; 200-249
1081   / "25" %x30-35 ; 250-255 1081   / "25" %x30-35 ; 250-255
1082   1082  
1083   IPv6address = 6( h16 ":" ) ls32 1083   IPv6address = 6( h16 ":" ) ls32
1084   / "::" 5( h16 ":" ) ls32 1084   / "::" 5( h16 ":" ) ls32
1085   / [ h16 ] "::" 4( h16 ":" ) ls32 1085   / [ h16 ] "::" 4( h16 ":" ) ls32
1086   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 1086   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1087   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 1087   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1088   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 1088   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1089   / [ *4( h16 ":" ) h16 ] "::" ls32 1089   / [ *4( h16 ":" ) h16 ] "::" ls32
1090   / [ *5( h16 ":" ) h16 ] "::" h16 1090   / [ *5( h16 ":" ) h16 ] "::" h16
1091   / [ *6( h16 ":" ) h16 ] "::" 1091   / [ *6( h16 ":" ) h16 ] "::"
1092   1092  
1093   ls32 = ( h16 ":" h16 ) / IPv4address 1093   ls32 = ( h16 ":" h16 ) / IPv4address
1094   ; least-significant 32 bits of address 1094   ; least-significant 32 bits of address
1095   1095  
1096   h16 = 1*4HEXDIG 1096   h16 = 1*4HEXDIG
1097   ; 16 bits of address represented in hexadecimal 1097   ; 16 bits of address represented in hexadecimal
1098   1098  
1099   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) 1099   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1100   1100  
1101   reg-name = *( unreserved / pct-encoded / "-" / ".") 1101   reg-name = *( unreserved / pct-encoded / "-" / ".")
1102   @endcode 1102   @endcode
1103   1103  
1104   @param s The string to set. 1104   @param s The string to set.
1105   @return `*this` 1105   @return `*this`
1106   1106  
1107   @par Specification 1107   @par Specification
1108   @li <a href="https://en.wikipedia.org/wiki/IPv4" 1108   @li <a href="https://en.wikipedia.org/wiki/IPv4"
1109   >IPv4 (Wikipedia)</a> 1109   >IPv4 (Wikipedia)</a>
1110   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291" 1110   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1111   >IP Version 6 Addressing Architecture (rfc4291)</a> 1111   >IP Version 6 Addressing Architecture (rfc4291)</a>
1112   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1112   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1113   3.2.2. Host (rfc3986)</a> 1113   3.2.2. Host (rfc3986)</a>
1114   1114  
1115   @see 1115   @see
1116   @ref set_encoded_host, 1116   @ref set_encoded_host,
1117   @ref set_encoded_host_address, 1117   @ref set_encoded_host_address,
1118   @ref set_encoded_host_name, 1118   @ref set_encoded_host_name,
1119   @ref set_host, 1119   @ref set_host,
1120   @ref set_host_address, 1120   @ref set_host_address,
1121   @ref set_host_ipv4, 1121   @ref set_host_ipv4,
1122   @ref set_host_ipv6, 1122   @ref set_host_ipv6,
1123   @ref set_host_ipvfuture, 1123   @ref set_host_ipvfuture,
1124   @ref set_host_name. 1124   @ref set_host_name.
1125   */ 1125   */
1126   url_base& 1126   url_base&
1127   set_host_address(core::string_view s); 1127   set_host_address(core::string_view s);
1128   1128  
1129   /** Set the host to an address 1129   /** Set the host to an address
1130   1130  
1131   Depending on the contents of the passed 1131   Depending on the contents of the passed
1132   string, this function sets the host: 1132   string, this function sets the host:
1133   1133  
1134   @li If the string is a valid IPv4 address, 1134   @li If the string is a valid IPv4 address,
1135   then the host is set to the address. 1135   then the host is set to the address.
1136   The host type is @ref host_type::ipv4. 1136   The host type is @ref host_type::ipv4.
1137   1137  
1138   @li If the string is a valid IPv6 address, 1138   @li If the string is a valid IPv6 address,
1139   then the host is set to that address. 1139   then the host is set to that address.
1140   The host type is @ref host_type::ipv6. 1140   The host type is @ref host_type::ipv6.
1141   1141  
1142   @li If the string is a valid IPvFuture, 1142   @li If the string is a valid IPvFuture,
1143   then the host is set to that address. 1143   then the host is set to that address.
1144   The host type is @ref host_type::ipvfuture. 1144   The host type is @ref host_type::ipvfuture.
1145   1145  
1146   @li Otherwise, the host name is set to 1146   @li Otherwise, the host name is set to
1147   the string. This string can contain percent 1147   the string. This string can contain percent
1148   escapes, or can be empty. 1148   escapes, or can be empty.
1149   Escapes in the string are preserved, 1149   Escapes in the string are preserved,
1150   and reserved characters in the string 1150   and reserved characters in the string
1151   are percent-escaped in the result. 1151   are percent-escaped in the result.
1152   The host type is @ref host_type::name. 1152   The host type is @ref host_type::name.
1153   1153  
1154   In all cases, when this function returns, 1154   In all cases, when this function returns,
1155   the URL contains an authority. 1155   the URL contains an authority.
1156   1156  
1157   @par Example 1157   @par Example
1158   @code 1158   @code
1159   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" ); 1159   assert( url( "http://www.example.com" ).set_host( "127.0.0.1" ).buffer() == "http://127.0.0.1" );
1160   @endcode 1160   @endcode
1161   1161  
1162   @par Postconditions 1162   @par Postconditions
1163   @code 1163   @code
1164   this->has_authority() == true 1164   this->has_authority() == true
1165   @endcode 1165   @endcode
1166   1166  
1167   @par Complexity 1167   @par Complexity
1168   Linear in `this->size() + s.size()`. 1168   Linear in `this->size() + s.size()`.
1169   1169  
1170   @par Exception Safety 1170   @par Exception Safety
1171   Strong guarantee. 1171   Strong guarantee.
1172   Calls to allocate may throw. 1172   Calls to allocate may throw.
1173   Exceptions thrown on invalid input. 1173   Exceptions thrown on invalid input.
1174   1174  
1175   @throw system_error 1175   @throw system_error
1176   `s` contains an invalid percent-encoding. 1176   `s` contains an invalid percent-encoding.
1177   1177  
1178   @par BNF 1178   @par BNF
1179   @code 1179   @code
1180   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 1180   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1181   1181  
1182   dec-octet = DIGIT ; 0-9 1182   dec-octet = DIGIT ; 0-9
1183   / %x31-39 DIGIT ; 10-99 1183   / %x31-39 DIGIT ; 10-99
1184   / "1" 2DIGIT ; 100-199 1184   / "1" 2DIGIT ; 100-199
1185   / "2" %x30-34 DIGIT ; 200-249 1185   / "2" %x30-34 DIGIT ; 200-249
1186   / "25" %x30-35 ; 250-255 1186   / "25" %x30-35 ; 250-255
1187   1187  
1188   IPv6address = 6( h16 ":" ) ls32 1188   IPv6address = 6( h16 ":" ) ls32
1189   / "::" 5( h16 ":" ) ls32 1189   / "::" 5( h16 ":" ) ls32
1190   / [ h16 ] "::" 4( h16 ":" ) ls32 1190   / [ h16 ] "::" 4( h16 ":" ) ls32
1191   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 1191   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1192   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 1192   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1193   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 1193   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1194   / [ *4( h16 ":" ) h16 ] "::" ls32 1194   / [ *4( h16 ":" ) h16 ] "::" ls32
1195   / [ *5( h16 ":" ) h16 ] "::" h16 1195   / [ *5( h16 ":" ) h16 ] "::" h16
1196   / [ *6( h16 ":" ) h16 ] "::" 1196   / [ *6( h16 ":" ) h16 ] "::"
1197   1197  
1198   ls32 = ( h16 ":" h16 ) / IPv4address 1198   ls32 = ( h16 ":" h16 ) / IPv4address
1199   ; least-significant 32 bits of address 1199   ; least-significant 32 bits of address
1200   1200  
1201   h16 = 1*4HEXDIG 1201   h16 = 1*4HEXDIG
1202   ; 16 bits of address represented in hexadecimal 1202   ; 16 bits of address represented in hexadecimal
1203   1203  
1204   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) 1204   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1205   1205  
1206   reg-name = *( unreserved / pct-encoded / "-" / ".") 1206   reg-name = *( unreserved / pct-encoded / "-" / ".")
1207   @endcode 1207   @endcode
1208   1208  
1209   @param s The string to set. 1209   @param s The string to set.
1210   @return `*this` 1210   @return `*this`
1211   1211  
1212   @par Specification 1212   @par Specification
1213   @li <a href="https://en.wikipedia.org/wiki/IPv4" 1213   @li <a href="https://en.wikipedia.org/wiki/IPv4"
1214   >IPv4 (Wikipedia)</a> 1214   >IPv4 (Wikipedia)</a>
1215   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291" 1215   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1216   >IP Version 6 Addressing Architecture (rfc4291)</a> 1216   >IP Version 6 Addressing Architecture (rfc4291)</a>
1217   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1217   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1218   3.2.2. Host (rfc3986)</a> 1218   3.2.2. Host (rfc3986)</a>
1219   1219  
1220   @see 1220   @see
1221   @ref set_encoded_host, 1221   @ref set_encoded_host,
1222   @ref set_encoded_host_name, 1222   @ref set_encoded_host_name,
1223   @ref set_host, 1223   @ref set_host,
1224   @ref set_host_address, 1224   @ref set_host_address,
1225   @ref set_host_ipv4, 1225   @ref set_host_ipv4,
1226   @ref set_host_ipv6, 1226   @ref set_host_ipv6,
1227   @ref set_host_ipvfuture, 1227   @ref set_host_ipvfuture,
1228   @ref set_host_name. 1228   @ref set_host_name.
1229   */ 1229   */
1230   url_base& 1230   url_base&
1231   set_encoded_host_address( 1231   set_encoded_host_address(
1232   pct_string_view s); 1232   pct_string_view s);
1233   1233  
1234   /** Set the host to an address 1234   /** Set the host to an address
1235   1235  
1236   The host is set to the specified IPv4 1236   The host is set to the specified IPv4
1237   address. 1237   address.
1238   The host type is @ref host_type::ipv4. 1238   The host type is @ref host_type::ipv4.
1239   1239  
1240   @par Example 1240   @par Example
1241   @code 1241   @code
1242   assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" ); 1242   assert( url("http://www.example.com").set_host_ipv4( ipv4_address( "127.0.0.1" ) ).buffer() == "http://127.0.0.1" );
1243   @endcode 1243   @endcode
1244   1244  
1245   @par Complexity 1245   @par Complexity
1246   Linear in `this->size()`. 1246   Linear in `this->size()`.
1247   1247  
1248   @par Postconditions 1248   @par Postconditions
1249   @code 1249   @code
1250   this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4 1250   this->has_authority() == true && this->host_ipv4_address() == addr && this->host_type() == host_type::ipv4
1251   @endcode 1251   @endcode
1252   1252  
1253   @par Exception Safety 1253   @par Exception Safety
1254   Strong guarantee. 1254   Strong guarantee.
1255   Calls to allocate may throw. 1255   Calls to allocate may throw.
1256   1256  
1257   @param addr The address to set. 1257   @param addr The address to set.
1258   @return `*this` 1258   @return `*this`
1259   1259  
1260   @par BNF 1260   @par BNF
1261   @code 1261   @code
1262   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 1262   IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
1263   1263  
1264   dec-octet = DIGIT ; 0-9 1264   dec-octet = DIGIT ; 0-9
1265   / %x31-39 DIGIT ; 10-99 1265   / %x31-39 DIGIT ; 10-99
1266   / "1" 2DIGIT ; 100-199 1266   / "1" 2DIGIT ; 100-199
1267   / "2" %x30-34 DIGIT ; 200-249 1267   / "2" %x30-34 DIGIT ; 200-249
1268   / "25" %x30-35 ; 250-255 1268   / "25" %x30-35 ; 250-255
1269   @endcode 1269   @endcode
1270   1270  
1271   @par Specification 1271   @par Specification
1272   @li <a href="https://en.wikipedia.org/wiki/IPv4" 1272   @li <a href="https://en.wikipedia.org/wiki/IPv4"
1273   >IPv4 (Wikipedia)</a> 1273   >IPv4 (Wikipedia)</a>
1274   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1274   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1275   3.2.2. Host (rfc3986)</a> 1275   3.2.2. Host (rfc3986)</a>
1276   1276  
1277   @see 1277   @see
1278   @ref set_encoded_host, 1278   @ref set_encoded_host,
1279   @ref set_encoded_host_address, 1279   @ref set_encoded_host_address,
1280   @ref set_encoded_host_name, 1280   @ref set_encoded_host_name,
1281   @ref set_host, 1281   @ref set_host,
1282   @ref set_host_address, 1282   @ref set_host_address,
1283   @ref set_host_ipv6, 1283   @ref set_host_ipv6,
1284   @ref set_host_ipvfuture, 1284   @ref set_host_ipvfuture,
1285   @ref set_host_name. 1285   @ref set_host_name.
1286   */ 1286   */
1287   url_base& 1287   url_base&
1288   set_host_ipv4( 1288   set_host_ipv4(
1289   ipv4_address const& addr); 1289   ipv4_address const& addr);
1290   1290  
1291   /** Set the host to an address 1291   /** Set the host to an address
1292   1292  
1293   The host is set to the specified IPv6 1293   The host is set to the specified IPv6
1294   address. 1294   address.
1295   The host type is @ref host_type::ipv6. 1295   The host type is @ref host_type::ipv6.
1296   1296  
1297   @par Example 1297   @par Example
1298   @code 1298   @code
1299   assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" ); 1299   assert( url().set_host_ipv6( ipv6_address( "1::6:c0a8:1" ) ).authority().buffer() == "[1::6:c0a8:1]" );
1300   @endcode 1300   @endcode
1301   1301  
1302   @par Postconditions 1302   @par Postconditions
1303   @code 1303   @code
1304   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6 1304   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::ipv6
1305   @endcode 1305   @endcode
1306   1306  
1307   @par Complexity 1307   @par Complexity
1308   Linear in `this->size()`. 1308   Linear in `this->size()`.
1309   1309  
1310   @par Exception Safety 1310   @par Exception Safety
1311   Strong guarantee. 1311   Strong guarantee.
1312   Calls to allocate may throw. 1312   Calls to allocate may throw.
1313   1313  
1314   @param addr The address to set. 1314   @param addr The address to set.
1315   1315  
1316   @return `*this` 1316   @return `*this`
1317   1317  
1318   @par BNF 1318   @par BNF
1319   @code 1319   @code
1320   IPv6address = 6( h16 ":" ) ls32 1320   IPv6address = 6( h16 ":" ) ls32
1321   / "::" 5( h16 ":" ) ls32 1321   / "::" 5( h16 ":" ) ls32
1322   / [ h16 ] "::" 4( h16 ":" ) ls32 1322   / [ h16 ] "::" 4( h16 ":" ) ls32
1323   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 1323   / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
1324   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 1324   / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
1325   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 1325   / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
1326   / [ *4( h16 ":" ) h16 ] "::" ls32 1326   / [ *4( h16 ":" ) h16 ] "::" ls32
1327   / [ *5( h16 ":" ) h16 ] "::" h16 1327   / [ *5( h16 ":" ) h16 ] "::" h16
1328   / [ *6( h16 ":" ) h16 ] "::" 1328   / [ *6( h16 ":" ) h16 ] "::"
1329   1329  
1330   ls32 = ( h16 ":" h16 ) / IPv4address 1330   ls32 = ( h16 ":" h16 ) / IPv4address
1331   ; least-significant 32 bits of address 1331   ; least-significant 32 bits of address
1332   1332  
1333   h16 = 1*4HEXDIG 1333   h16 = 1*4HEXDIG
1334   ; 16 bits of address represented in hexadecimal 1334   ; 16 bits of address represented in hexadecimal
1335   @endcode 1335   @endcode
1336   1336  
1337   @par Specification 1337   @par Specification
1338   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291" 1338   @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
1339   >IP Version 6 Addressing Architecture (rfc4291)</a> 1339   >IP Version 6 Addressing Architecture (rfc4291)</a>
1340   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1340   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1341   3.2.2. Host (rfc3986)</a> 1341   3.2.2. Host (rfc3986)</a>
1342   1342  
1343   @see 1343   @see
1344   @ref set_encoded_host, 1344   @ref set_encoded_host,
1345   @ref set_encoded_host_address, 1345   @ref set_encoded_host_address,
1346   @ref set_encoded_host_name, 1346   @ref set_encoded_host_name,
1347   @ref set_host, 1347   @ref set_host,
1348   @ref set_host_address, 1348   @ref set_host_address,
1349   @ref set_host_ipv4, 1349   @ref set_host_ipv4,
1350   @ref set_host_ipvfuture, 1350   @ref set_host_ipvfuture,
1351   @ref set_host_name. 1351   @ref set_host_name.
1352   */ 1352   */
1353   url_base& 1353   url_base&
1354   set_host_ipv6( 1354   set_host_ipv6(
1355   ipv6_address const& addr); 1355   ipv6_address const& addr);
1356   1356  
1357   /** Set the zone ID for an IPv6 address. 1357   /** Set the zone ID for an IPv6 address.
1358   1358  
1359   This function sets the zone ID for the host if the host is an IPv6 address. 1359   This function sets the zone ID for the host if the host is an IPv6 address.
1360   Reserved characters in the string are percent-escaped in the result. 1360   Reserved characters in the string are percent-escaped in the result.
1361   1361  
1362   @par Example 1362   @par Example
1363   @code 1363   @code
1364   assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" ); 1364   assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1365   @endcode 1365   @endcode
1366   1366  
1367   @par Complexity 1367   @par Complexity
1368   Linear in `this->size()`. 1368   Linear in `this->size()`.
1369   1369  
1370   @par Exception Safety 1370   @par Exception Safety
1371   Strong guarantee. Calls to allocate may throw. 1371   Strong guarantee. Calls to allocate may throw.
1372   1372  
1373   @param s The zone ID to set. 1373   @param s The zone ID to set.
1374   @return `*this` 1374   @return `*this`
1375   1375  
1376   @par Specification 1376   @par Specification
1377   @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a> 1377   @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1378   1378  
1379   */ 1379   */
1380   url_base& 1380   url_base&
1381   set_zone_id(core::string_view s); 1381   set_zone_id(core::string_view s);
1382   1382  
1383   /** Set the zone ID for an IPv6 address (percent-encoded). 1383   /** Set the zone ID for an IPv6 address (percent-encoded).
1384   1384  
1385   This function sets the zone ID for the host if the host is an IPv6 address. 1385   This function sets the zone ID for the host if the host is an IPv6 address.
1386   Escapes in the string are preserved, and reserved characters in the string 1386   Escapes in the string are preserved, and reserved characters in the string
1387   are percent-escaped in the result. 1387   are percent-escaped in the result.
1388   1388  
1389   @par Example 1389   @par Example
1390   @code 1390   @code
1391   assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_encoded_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" ); 1391   assert( u.set_host_ipv6( ipv6_address( "fe80::1" ) ).set_encoded_zone_id( "eth0" ).buffer() == "https://[fe80::1%25eth0]" );
1392   @endcode 1392   @endcode
1393   1393  
1394   @par Complexity 1394   @par Complexity
1395   Linear in `this->size()`. 1395   Linear in `this->size()`.
1396   1396  
1397   @par Exception Safety 1397   @par Exception Safety
1398   Strong guarantee. Calls to allocate may throw. 1398   Strong guarantee. Calls to allocate may throw.
1399   Exceptions thrown on invalid input. 1399   Exceptions thrown on invalid input.
1400   1400  
1401   @throw system_error 1401   @throw system_error
1402   `s` contains an invalid percent-encoding. 1402   `s` contains an invalid percent-encoding.
1403   1403  
1404   @param s The zone ID to set. 1404   @param s The zone ID to set.
1405   @return `*this` 1405   @return `*this`
1406   1406  
1407   @par Specification 1407   @par Specification
1408   @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a> 1408   @li <a href="https://datatracker.ietf.org/doc/html/rfc6874">RFC 6874</a>
1409   1409  
1410   */ 1410   */
1411   url_base& 1411   url_base&
1412   set_encoded_zone_id(pct_string_view s); 1412   set_encoded_zone_id(pct_string_view s);
1413   1413  
1414   /** Set the host to an address 1414   /** Set the host to an address
1415   1415  
1416   The host is set to the specified IPvFuture 1416   The host is set to the specified IPvFuture
1417   string. 1417   string.
1418   The host type is @ref host_type::ipvfuture. 1418   The host type is @ref host_type::ipvfuture.
1419   1419  
1420   @par Example 1420   @par Example
1421   @code 1421   @code
1422   assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" ); 1422   assert( url().set_host_ipvfuture( "v42.bis" ).buffer() == "//[v42.bis]" );
1423   @endcode 1423   @endcode
1424   1424  
1425   @par Complexity 1425   @par Complexity
1426   Linear in `this->size() + s.size()`. 1426   Linear in `this->size() + s.size()`.
1427   1427  
1428   @par Postconditions 1428   @par Postconditions
1429   @code 1429   @code
1430   this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture 1430   this->has_authority() == true && this->host_ipvfuture) == s && this->host_type() == host_type::ipvfuture
1431   @endcode 1431   @endcode
1432   1432  
1433   @par Exception Safety 1433   @par Exception Safety
1434   Strong guarantee. 1434   Strong guarantee.
1435   Calls to allocate may throw. 1435   Calls to allocate may throw.
1436   Exceptions thrown on invalid input. 1436   Exceptions thrown on invalid input.
1437   1437  
1438   @throw system_error 1438   @throw system_error
1439   `s` contains an invalid percent-encoding. 1439   `s` contains an invalid percent-encoding.
1440   1440  
1441   @param s The string to set. 1441   @param s The string to set.
1442   1442  
1443   @return `*this` 1443   @return `*this`
1444   1444  
1445   @par BNF 1445   @par BNF
1446   @code 1446   @code
1447   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) 1447   IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1448   @endcode 1448   @endcode
1449   1449  
1450   @par Specification 1450   @par Specification
1451   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1451   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1452   3.2.2. Host (rfc3986)</a> 1452   3.2.2. Host (rfc3986)</a>
1453   1453  
1454   @see 1454   @see
1455   @ref set_encoded_host, 1455   @ref set_encoded_host,
1456   @ref set_encoded_host_address, 1456   @ref set_encoded_host_address,
1457   @ref set_encoded_host_name, 1457   @ref set_encoded_host_name,
1458   @ref set_host, 1458   @ref set_host,
1459   @ref set_host_address, 1459   @ref set_host_address,
1460   @ref set_host_ipv4, 1460   @ref set_host_ipv4,
1461   @ref set_host_ipv6, 1461   @ref set_host_ipv6,
1462   @ref set_host_name. 1462   @ref set_host_name.
1463   */ 1463   */
1464   url_base& 1464   url_base&
1465   set_host_ipvfuture( 1465   set_host_ipvfuture(
1466   core::string_view s); 1466   core::string_view s);
1467   1467  
1468   /** Set the host to a name 1468   /** Set the host to a name
1469   1469  
1470   The host is set to the specified string, 1470   The host is set to the specified string,
1471   which may be empty. 1471   which may be empty.
1472   Reserved characters in the string are 1472   Reserved characters in the string are
1473   percent-escaped in the result. 1473   percent-escaped in the result.
1474   The host type is @ref host_type::name. 1474   The host type is @ref host_type::name.
1475   1475  
1476   @par Example 1476   @par Example
1477   @code 1477   @code
1478   assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" ); 1478   assert( url( "http://www.example.com/index.htm").set_host_name( "localhost" ).host_address() == "localhost" );
1479   @endcode 1479   @endcode
1480   1480  
1481   @par Postconditions 1481   @par Postconditions
1482   @code 1482   @code
1483   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name 1483   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1484   @endcode 1484   @endcode
1485   1485  
1486   @par Exception Safety 1486   @par Exception Safety
1487   Strong guarantee. 1487   Strong guarantee.
1488   Calls to allocate may throw. 1488   Calls to allocate may throw.
1489   1489  
1490   @param s The string to set. 1490   @param s The string to set.
1491   @return `*this` 1491   @return `*this`
1492   1492  
1493   @par BNF 1493   @par BNF
1494   @code 1494   @code
1495   reg-name = *( unreserved / pct-encoded / "-" / ".") 1495   reg-name = *( unreserved / pct-encoded / "-" / ".")
1496   @endcode 1496   @endcode
1497   1497  
1498   @par Specification 1498   @par Specification
1499   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1499   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1500   3.2.2. Host (rfc3986)</a> 1500   3.2.2. Host (rfc3986)</a>
1501   1501  
1502   @see 1502   @see
1503   @ref set_encoded_host, 1503   @ref set_encoded_host,
1504   @ref set_encoded_host_address, 1504   @ref set_encoded_host_address,
1505   @ref set_encoded_host_name, 1505   @ref set_encoded_host_name,
1506   @ref set_host, 1506   @ref set_host,
1507   @ref set_host_address, 1507   @ref set_host_address,
1508   @ref set_host_ipv4, 1508   @ref set_host_ipv4,
1509   @ref set_host_ipv6, 1509   @ref set_host_ipv6,
1510   @ref set_host_ipvfuture. 1510   @ref set_host_ipvfuture.
1511   */ 1511   */
1512   url_base& 1512   url_base&
1513   set_host_name( 1513   set_host_name(
1514   core::string_view s); 1514   core::string_view s);
1515   1515  
1516   /** Set the host to a name 1516   /** Set the host to a name
1517   1517  
1518   The host is set to the specified string, 1518   The host is set to the specified string,
1519   which may contain percent-escapes and 1519   which may contain percent-escapes and
1520   can be empty. 1520   can be empty.
1521   Escapes in the string are preserved, 1521   Escapes in the string are preserved,
1522   and reserved characters in the string 1522   and reserved characters in the string
1523   are percent-escaped in the result. 1523   are percent-escaped in the result.
1524   The host type is @ref host_type::name. 1524   The host type is @ref host_type::name.
1525   1525  
1526   @par Example 1526   @par Example
1527   @code 1527   @code
1528   assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" ); 1528   assert( url( "http://www.example.com/index.htm").set_encoded_host_name( "localhost" ).host_address() == "localhost" );
1529   @endcode 1529   @endcode
1530   1530  
1531   @par Postconditions 1531   @par Postconditions
1532   @code 1532   @code
1533   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name 1533   this->has_authority() == true && this->host_ipv6_address() == addr && this->host_type() == host_type::name
1534   @endcode 1534   @endcode
1535   1535  
1536   @par Exception Safety 1536   @par Exception Safety
1537   Strong guarantee. 1537   Strong guarantee.
1538   Calls to allocate may throw. 1538   Calls to allocate may throw.
1539   Exceptions thrown on invalid input. 1539   Exceptions thrown on invalid input.
1540   1540  
1541   @throw system_error 1541   @throw system_error
1542   `s` contains an invalid percent-encoding. 1542   `s` contains an invalid percent-encoding.
1543   1543  
1544   @param s The string to set. 1544   @param s The string to set.
1545   @return `*this` 1545   @return `*this`
1546   1546  
1547   @par BNF 1547   @par BNF
1548   @code 1548   @code
1549   reg-name = *( unreserved / pct-encoded / "-" / ".") 1549   reg-name = *( unreserved / pct-encoded / "-" / ".")
1550   @endcode 1550   @endcode
1551   1551  
1552   @par Specification 1552   @par Specification
1553   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"> 1553   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2">
1554   3.2.2. Host (rfc3986)</a> 1554   3.2.2. Host (rfc3986)</a>
1555   1555  
1556   @see 1556   @see
1557   @ref set_encoded_host, 1557   @ref set_encoded_host,
1558   @ref set_encoded_host_address, 1558   @ref set_encoded_host_address,
1559   @ref set_host, 1559   @ref set_host,
1560   @ref set_host_address, 1560   @ref set_host_address,
1561   @ref set_host_ipv4, 1561   @ref set_host_ipv4,
1562   @ref set_host_ipv6, 1562   @ref set_host_ipv6,
1563   @ref set_host_ipvfuture, 1563   @ref set_host_ipvfuture,
1564   @ref set_host_name. 1564   @ref set_host_name.
1565   */ 1565   */
1566   url_base& 1566   url_base&
1567   set_encoded_host_name( 1567   set_encoded_host_name(
1568   pct_string_view s); 1568   pct_string_view s);
1569   1569  
1570   //-------------------------------------------- 1570   //--------------------------------------------
1571   1571  
1572   /** Set the port 1572   /** Set the port
1573   1573  
1574   The port is set to the specified integer. 1574   The port is set to the specified integer.
1575   1575  
1576   @par Example 1576   @par Example
1577   @code 1577   @code
1578   assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" ); 1578   assert( url( "http://www.example.com" ).set_port_number( 8080 ).authority().buffer() == "www.example.com:8080" );
1579   @endcode 1579   @endcode
1580   1580  
1581   @par Postconditions 1581   @par Postconditions
1582   @code 1582   @code
1583   this->has_authority() == true && this->has_port() == true && this->port_number() == n 1583   this->has_authority() == true && this->has_port() == true && this->port_number() == n
1584   @endcode 1584   @endcode
1585   1585  
1586   @par Complexity 1586   @par Complexity
1587   Linear in `this->size()`. 1587   Linear in `this->size()`.
1588   1588  
1589   @par Exception Safety 1589   @par Exception Safety
1590   Strong guarantee. 1590   Strong guarantee.
1591   Calls to allocate may throw. 1591   Calls to allocate may throw.
1592   1592  
1593   @param n The port number to set. 1593   @param n The port number to set.
1594   1594  
1595   @return `*this` 1595   @return `*this`
1596   1596  
1597   @par BNF 1597   @par BNF
1598   @code 1598   @code
1599   authority = [ userinfo "@" ] host [ ":" port ] 1599   authority = [ userinfo "@" ] host [ ":" port ]
1600   1600  
1601   port = *DIGIT 1601   port = *DIGIT
1602   @endcode 1602   @endcode
1603   1603  
1604   @par Specification 1604   @par Specification
1605   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"> 1605   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1606   3.2.3. Port (rfc3986)</a> 1606   3.2.3. Port (rfc3986)</a>
1607   1607  
1608   @see 1608   @see
1609   @ref remove_port, 1609   @ref remove_port,
1610   @ref set_port. 1610   @ref set_port.
1611   */ 1611   */
1612   url_base& 1612   url_base&
1613   set_port_number(std::uint16_t n); 1613   set_port_number(std::uint16_t n);
1614   1614  
1615   /** Set the port 1615   /** Set the port
1616   1616  
1617   This port is set to the string, which 1617   This port is set to the string, which
1618   must contain only digits or be empty. 1618   must contain only digits or be empty.
1619   An empty port string is distinct from 1619   An empty port string is distinct from
1620   having no port. 1620   having no port.
1621   1621  
1622   @par Example 1622   @par Example
1623   @code 1623   @code
1624   assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" ); 1624   assert( url( "http://www.example.com" ).set_port( "8080" ).authority().buffer() == "www.example.com:8080" );
1625   @endcode 1625   @endcode
1626   1626  
1627   @par Postconditions 1627   @par Postconditions
1628   @code 1628   @code
1629   this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n) 1629   this->has_port() == true && this->port_number() == n && this->port() == std::to_string(n)
1630   @endcode 1630   @endcode
1631   1631  
1632   @par Exception Safety 1632   @par Exception Safety
1633   Strong guarantee. 1633   Strong guarantee.
1634   Calls to allocate may throw. 1634   Calls to allocate may throw.
1635   Exceptions thrown on invalid input. 1635   Exceptions thrown on invalid input.
1636   1636  
1637   @throw system_error 1637   @throw system_error
1638   `s` does not contain a valid port. 1638   `s` does not contain a valid port.
1639   1639  
1640   @param s The port string to set. 1640   @param s The port string to set.
1641   @return `*this` 1641   @return `*this`
1642   1642  
1643   @par BNF 1643   @par BNF
1644   @code 1644   @code
1645   port = *DIGIT 1645   port = *DIGIT
1646   @endcode 1646   @endcode
1647   1647  
1648   @par Specification 1648   @par Specification
1649   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"> 1649   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1650   3.2.3. Port (rfc3986)</a> 1650   3.2.3. Port (rfc3986)</a>
1651   1651  
1652   @see 1652   @see
1653   @ref remove_port, 1653   @ref remove_port,
1654   @ref set_port. 1654   @ref set_port.
1655   */ 1655   */
1656   url_base& 1656   url_base&
1657   set_port(core::string_view s); 1657   set_port(core::string_view s);
1658   1658  
1659   /** Remove the port 1659   /** Remove the port
1660   1660  
1661   If a port exists, it is removed. The rest 1661   If a port exists, it is removed. The rest
1662   of the authority is unchanged. 1662   of the authority is unchanged.
1663   1663  
1664   @return `*this` 1664   @return `*this`
1665   1665  
1666   @par Example 1666   @par Example
1667   @code 1667   @code
1668   assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" ); 1668   assert( url( "http://www.example.com:80" ).remove_port().authority().buffer() == "www.example.com" );
1669   @endcode 1669   @endcode
1670   1670  
1671   @par Postconditions 1671   @par Postconditions
1672   @code 1672   @code
1673   this->has_port() == false && this->port_number() == 0 && this->port() == "" 1673   this->has_port() == false && this->port_number() == 0 && this->port() == ""
1674   @endcode 1674   @endcode
1675   1675  
1676   @par Complexity 1676   @par Complexity
1677   Linear in `this->size()`. 1677   Linear in `this->size()`.
1678   1678  
1679   @par Exception Safety 1679   @par Exception Safety
1680   Throws nothing. 1680   Throws nothing.
1681   1681  
1682   @par BNF 1682   @par BNF
1683   @code 1683   @code
1684   authority = [ userinfo "@" ] host [ ":" port ] 1684   authority = [ userinfo "@" ] host [ ":" port ]
1685   1685  
1686   port = *DIGIT 1686   port = *DIGIT
1687   @endcode 1687   @endcode
1688   1688  
1689   @par Specification 1689   @par Specification
1690   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"> 1690   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3">
1691   3.2.3. Port (rfc3986)</a> 1691   3.2.3. Port (rfc3986)</a>
1692   1692  
1693   @see 1693   @see
1694   @ref set_port. 1694   @ref set_port.
1695   */ 1695   */
1696   url_base& 1696   url_base&
1697   remove_port() noexcept; 1697   remove_port() noexcept;
1698   1698  
1699   //-------------------------------------------- 1699   //--------------------------------------------
1700   // 1700   //
1701   // Path 1701   // Path
1702   // 1702   //
1703   //-------------------------------------------- 1703   //--------------------------------------------
1704   1704  
1705   /** Set if the path is absolute 1705   /** Set if the path is absolute
1706   1706  
1707   This function adjusts the path to make 1707   This function adjusts the path to make
1708   it absolute or not, depending on the 1708   it absolute or not, depending on the
1709   parameter. 1709   parameter.
1710   1710  
1711   @note 1711   @note
1712   If an authority is present, the path 1712   If an authority is present, the path
1713   is always absolute. In this case, the 1713   is always absolute. In this case, the
1714   function has no effect. 1714   function has no effect.
1715   1715  
1716   @par Example 1716   @par Example
1717   @code 1717   @code
1718   url u( "path/to/file.txt" ); 1718   url u( "path/to/file.txt" );
1719   assert( u.set_path_absolute( true ) ); 1719   assert( u.set_path_absolute( true ) );
1720   assert( u.buffer() == "/path/to/file.txt" ); 1720   assert( u.buffer() == "/path/to/file.txt" );
1721   @endcode 1721   @endcode
1722   1722  
1723   @par Postconditions 1723   @par Postconditions
1724   @code 1724   @code
1725   this->is_path_absolute() == true && this->encoded_path().front() == '/' 1725   this->is_path_absolute() == true && this->encoded_path().front() == '/'
1726   @endcode 1726   @endcode
1727   1727  
1728   @param absolute If `true`, the path is made absolute. 1728   @param absolute If `true`, the path is made absolute.
1729   1729  
1730   @return true on success. 1730   @return true on success.
1731   1731  
1732   @par Complexity 1732   @par Complexity
1733   Linear in `this->size()`. 1733   Linear in `this->size()`.
1734   1734  
1735   @par BNF 1735   @par BNF
1736   @code 1736   @code
1737   path = path-abempty ; begins with "/" or is empty 1737   path = path-abempty ; begins with "/" or is empty
1738   / path-absolute ; begins with "/" but not "//" 1738   / path-absolute ; begins with "/" but not "//"
1739   / path-noscheme ; begins with a non-colon segment 1739   / path-noscheme ; begins with a non-colon segment
1740   / path-rootless ; begins with a segment 1740   / path-rootless ; begins with a segment
1741   / path-empty ; zero characters 1741   / path-empty ; zero characters
1742   1742  
1743   path-abempty = *( "/" segment ) 1743   path-abempty = *( "/" segment )
1744   path-absolute = "/" [ segment-nz *( "/" segment ) ] 1744   path-absolute = "/" [ segment-nz *( "/" segment ) ]
1745   path-noscheme = segment-nz-nc *( "/" segment ) 1745   path-noscheme = segment-nz-nc *( "/" segment )
1746   path-rootless = segment-nz *( "/" segment ) 1746   path-rootless = segment-nz *( "/" segment )
1747   path-empty = 0<pchar> 1747   path-empty = 0<pchar>
1748   @endcode 1748   @endcode
1749   1749  
1750   @par Specification 1750   @par Specification
1751   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" 1751   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1752   >3.3. Path (rfc3986)</a> 1752   >3.3. Path (rfc3986)</a>
1753   1753  
1754   @see 1754   @see
1755   @ref encoded_segments, 1755   @ref encoded_segments,
1756   @ref segments, 1756   @ref segments,
1757   @ref set_encoded_path, 1757   @ref set_encoded_path,
1758   @ref set_path. 1758   @ref set_path.
1759   */ 1759   */
1760   bool 1760   bool
1761   set_path_absolute(bool absolute); 1761   set_path_absolute(bool absolute);
1762   1762  
1763   /** Set the path. 1763   /** Set the path.
1764   1764  
1765   This function sets the path to the 1765   This function sets the path to the
1766   string, which may be empty. 1766   string, which may be empty.
1767   Reserved characters in the string are 1767   Reserved characters in the string are
1768   percent-escaped in the result. 1768   percent-escaped in the result.
1769   1769  
1770   @note 1770   @note
1771   The library may adjust the final result 1771   The library may adjust the final result
1772   to ensure that no other parts of the URL 1772   to ensure that no other parts of the URL
1773   are semantically affected. 1773   are semantically affected.
1774   1774  
1775   @note 1775   @note
1776   This function does not encode '/' chars, which 1776   This function does not encode '/' chars, which
1777   are unreserved for paths but reserved for 1777   are unreserved for paths but reserved for
1778   path segments. If a path segment should include 1778   path segments. If a path segment should include
1779   encoded '/'s to differentiate it from path separators, 1779   encoded '/'s to differentiate it from path separators,
1780   the functions @ref set_encoded_path or @ref segments 1780   the functions @ref set_encoded_path or @ref segments
1781   should be used instead. 1781   should be used instead.
1782   1782  
1783   @par Example 1783   @par Example
1784   @code 1784   @code
1785   url u( "http://www.example.com" ); 1785   url u( "http://www.example.com" );
1786   1786  
1787   u.set_path( "path/to/file.txt" ); 1787   u.set_path( "path/to/file.txt" );
1788   1788  
1789   assert( u.path() == "/path/to/file.txt" ); 1789   assert( u.path() == "/path/to/file.txt" );
1790   @endcode 1790   @endcode
1791   1791  
1792   @par Complexity 1792   @par Complexity
1793   Linear in `this->size() + s.size()`. 1793   Linear in `this->size() + s.size()`.
1794   1794  
1795   @par Exception Safety 1795   @par Exception Safety
1796   Strong guarantee. 1796   Strong guarantee.
1797   Calls to allocate may throw. 1797   Calls to allocate may throw.
1798   1798  
1799   @param s The string to set. 1799   @param s The string to set.
1800   @return `*this` 1800   @return `*this`
1801   1801  
1802   @par BNF 1802   @par BNF
1803   @code 1803   @code
1804   path = path-abempty ; begins with "/" or is empty 1804   path = path-abempty ; begins with "/" or is empty
1805   / path-absolute ; begins with "/" but not "//" 1805   / path-absolute ; begins with "/" but not "//"
1806   / path-noscheme ; begins with a non-colon segment 1806   / path-noscheme ; begins with a non-colon segment
1807   / path-rootless ; begins with a segment 1807   / path-rootless ; begins with a segment
1808   / path-empty ; zero characters 1808   / path-empty ; zero characters
1809   1809  
1810   path-abempty = *( "/" segment ) 1810   path-abempty = *( "/" segment )
1811   path-absolute = "/" [ segment-nz *( "/" segment ) ] 1811   path-absolute = "/" [ segment-nz *( "/" segment ) ]
1812   path-noscheme = segment-nz-nc *( "/" segment ) 1812   path-noscheme = segment-nz-nc *( "/" segment )
1813   path-rootless = segment-nz *( "/" segment ) 1813   path-rootless = segment-nz *( "/" segment )
1814   path-empty = 0<pchar> 1814   path-empty = 0<pchar>
1815   @endcode 1815   @endcode
1816   1816  
1817   @par Specification 1817   @par Specification
1818   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" 1818   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1819   >3.3. Path (rfc3986)</a> 1819   >3.3. Path (rfc3986)</a>
1820   1820  
1821   @see 1821   @see
1822   @ref encoded_segments, 1822   @ref encoded_segments,
1823   @ref segments, 1823   @ref segments,
1824   @ref set_encoded_path, 1824   @ref set_encoded_path,
1825   @ref set_path_absolute. 1825   @ref set_path_absolute.
1826   */ 1826   */
1827   url_base& 1827   url_base&
1828   set_path( 1828   set_path(
1829   core::string_view s); 1829   core::string_view s);
1830   1830  
1831   /** Set the path. 1831   /** Set the path.
1832   1832  
1833   This function sets the path to the 1833   This function sets the path to the
1834   string, which may contain percent-escapes 1834   string, which may contain percent-escapes
1835   and can be empty. 1835   and can be empty.
1836   Escapes in the string are preserved, 1836   Escapes in the string are preserved,
1837   and reserved characters in the string 1837   and reserved characters in the string
1838   are percent-escaped in the result. 1838   are percent-escaped in the result.
1839   1839  
1840   @note 1840   @note
1841   The library may adjust the final result 1841   The library may adjust the final result
1842   to ensure that no other parts of the url 1842   to ensure that no other parts of the url
1843   is semantically affected. 1843   is semantically affected.
1844   1844  
1845   @par Example 1845   @par Example
1846   @code 1846   @code
1847   url u( "http://www.example.com" ); 1847   url u( "http://www.example.com" );
1848   1848  
1849   u.set_encoded_path( "path/to/file.txt" ); 1849   u.set_encoded_path( "path/to/file.txt" );
1850   1850  
1851   assert( u.encoded_path() == "/path/to/file.txt" ); 1851   assert( u.encoded_path() == "/path/to/file.txt" );
1852   @endcode 1852   @endcode
1853   1853  
1854   @par Complexity 1854   @par Complexity
1855   Linear in `this->size() + s.size()`. 1855   Linear in `this->size() + s.size()`.
1856   1856  
1857   @par Exception Safety 1857   @par Exception Safety
1858   Strong guarantee. 1858   Strong guarantee.
1859   Calls to allocate may throw. 1859   Calls to allocate may throw.
1860   Exceptions thrown on invalid input. 1860   Exceptions thrown on invalid input.
1861   1861  
1862   @throw system_error 1862   @throw system_error
1863   `s` contains an invalid percent-encoding. 1863   `s` contains an invalid percent-encoding.
1864   1864  
1865   @param s The string to set. 1865   @param s The string to set.
1866   1866  
1867   @return `*this` 1867   @return `*this`
1868   1868  
1869   @par BNF 1869   @par BNF
1870   @code 1870   @code
1871   path = path-abempty ; begins with "/" or is empty 1871   path = path-abempty ; begins with "/" or is empty
1872   / path-absolute ; begins with "/" but not "//" 1872   / path-absolute ; begins with "/" but not "//"
1873   / path-noscheme ; begins with a non-colon segment 1873   / path-noscheme ; begins with a non-colon segment
1874   / path-rootless ; begins with a segment 1874   / path-rootless ; begins with a segment
1875   / path-empty ; zero characters 1875   / path-empty ; zero characters
1876   1876  
1877   path-abempty = *( "/" segment ) 1877   path-abempty = *( "/" segment )
1878   path-absolute = "/" [ segment-nz *( "/" segment ) ] 1878   path-absolute = "/" [ segment-nz *( "/" segment ) ]
1879   path-noscheme = segment-nz-nc *( "/" segment ) 1879   path-noscheme = segment-nz-nc *( "/" segment )
1880   path-rootless = segment-nz *( "/" segment ) 1880   path-rootless = segment-nz *( "/" segment )
1881   path-empty = 0<pchar> 1881   path-empty = 0<pchar>
1882   @endcode 1882   @endcode
1883   1883  
1884   @par Specification 1884   @par Specification
1885   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" 1885   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1886   >3.3. Path (rfc3986)</a> 1886   >3.3. Path (rfc3986)</a>
1887   1887  
1888   @see 1888   @see
1889   @ref encoded_segments, 1889   @ref encoded_segments,
1890   @ref segments, 1890   @ref segments,
1891   @ref set_path, 1891   @ref set_path,
1892   @ref set_path_absolute. 1892   @ref set_path_absolute.
1893   */ 1893   */
1894   url_base& 1894   url_base&
1895   set_encoded_path( 1895   set_encoded_path(
1896   pct_string_view s); 1896   pct_string_view s);
1897   1897  
1898   /** Return the path as a container of segments 1898   /** Return the path as a container of segments
1899   1899  
1900   This function returns a bidirectional 1900   This function returns a bidirectional
1901   view of segments over the path. 1901   view of segments over the path.
1902   The returned view references the same 1902   The returned view references the same
1903   underlying character buffer; ownership 1903   underlying character buffer; ownership
1904   is not transferred. 1904   is not transferred.
1905   Any percent-escapes in strings returned 1905   Any percent-escapes in strings returned
1906   when iterating the view are decoded first. 1906   when iterating the view are decoded first.
1907   The container is modifiable; changes 1907   The container is modifiable; changes
1908   to the container are reflected in the 1908   to the container are reflected in the
1909   underlying URL. 1909   underlying URL.
1910   1910  
1911   @return `*this` 1911   @return `*this`
1912   1912  
1913   @par Example 1913   @par Example
1914   @code 1914   @code
1915   url u( "http://example.com/path/to/file.txt" ); 1915   url u( "http://example.com/path/to/file.txt" );
1916   1916  
1917   segments sv = u.segments(); 1917   segments sv = u.segments();
1918   @endcode 1918   @endcode
1919   1919  
1920   @par Complexity 1920   @par Complexity
1921   Constant. 1921   Constant.
1922   1922  
1923   @par Exception Safety 1923   @par Exception Safety
1924   Throws nothing. 1924   Throws nothing.
1925   1925  
1926   @par BNF 1926   @par BNF
1927   @code 1927   @code
1928   path = path-abempty ; begins with "/" or is empty 1928   path = path-abempty ; begins with "/" or is empty
1929   / path-absolute ; begins with "/" but not "//" 1929   / path-absolute ; begins with "/" but not "//"
1930   / path-noscheme ; begins with a non-colon segment 1930   / path-noscheme ; begins with a non-colon segment
1931   / path-rootless ; begins with a segment 1931   / path-rootless ; begins with a segment
1932   / path-empty ; zero characters 1932   / path-empty ; zero characters
1933   1933  
1934   path-abempty = *( "/" segment ) 1934   path-abempty = *( "/" segment )
1935   path-absolute = "/" [ segment-nz *( "/" segment ) ] 1935   path-absolute = "/" [ segment-nz *( "/" segment ) ]
1936   path-noscheme = segment-nz-nc *( "/" segment ) 1936   path-noscheme = segment-nz-nc *( "/" segment )
1937   path-rootless = segment-nz *( "/" segment ) 1937   path-rootless = segment-nz *( "/" segment )
1938   path-empty = 0<pchar> 1938   path-empty = 0<pchar>
1939   @endcode 1939   @endcode
1940   1940  
1941   @par Specification 1941   @par Specification
1942   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" 1942   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
1943   >3.3. Path (rfc3986)</a> 1943   >3.3. Path (rfc3986)</a>
1944   1944  
1945   @see 1945   @see
1946   @ref encoded_segments, 1946   @ref encoded_segments,
1947   @ref set_encoded_path, 1947   @ref set_encoded_path,
1948   @ref set_path, 1948   @ref set_path,
1949   @ref set_path_absolute. 1949   @ref set_path_absolute.
1950   */ 1950   */
1951   urls::segments_ref 1951   urls::segments_ref
1952   segments() noexcept; 1952   segments() noexcept;
1953   1953  
1954   /// @copydoc url_view_base::segments 1954   /// @copydoc url_view_base::segments
1955   segments_view 1955   segments_view
HITCBC 1956   5725 segments() const noexcept 1956   5725 segments() const noexcept
1957   { 1957   {
HITCBC 1958   5725 return url_view_base::segments(); 1958   5725 return url_view_base::segments();
1959   } 1959   }
1960   1960  
1961   /** Return the path as a container of segments 1961   /** Return the path as a container of segments
1962   1962  
1963   This function returns a bidirectional 1963   This function returns a bidirectional
1964   view of segments over the path. 1964   view of segments over the path.
1965   The returned view references the same 1965   The returned view references the same
1966   underlying character buffer; ownership 1966   underlying character buffer; ownership
1967   is not transferred. 1967   is not transferred.
1968   Strings returned when iterating the 1968   Strings returned when iterating the
1969   range may contain percent escapes. 1969   range may contain percent escapes.
1970   The container is modifiable; changes 1970   The container is modifiable; changes
1971   to the container are reflected in the 1971   to the container are reflected in the
1972   underlying URL. 1972   underlying URL.
1973   1973  
1974   @return `*this` 1974   @return `*this`
1975   1975  
1976   @par Example 1976   @par Example
1977   @code 1977   @code
1978   url u( "http://example.com/path/to/file.txt" ); 1978   url u( "http://example.com/path/to/file.txt" );
1979   1979  
1980   segments_encoded_ref sv = u.encoded_segments(); 1980   segments_encoded_ref sv = u.encoded_segments();
1981   @endcode 1981   @endcode
1982   1982  
1983   @par Complexity 1983   @par Complexity
1984   Constant. 1984   Constant.
1985   1985  
1986   @par Exception Safety 1986   @par Exception Safety
1987   Throws nothing. 1987   Throws nothing.
1988   1988  
1989   @par BNF 1989   @par BNF
1990   @code 1990   @code
1991   path = path-abempty ; begins with "/" or is empty 1991   path = path-abempty ; begins with "/" or is empty
1992   / path-absolute ; begins with "/" but not "//" 1992   / path-absolute ; begins with "/" but not "//"
1993   / path-noscheme ; begins with a non-colon segment 1993   / path-noscheme ; begins with a non-colon segment
1994   / path-rootless ; begins with a segment 1994   / path-rootless ; begins with a segment
1995   / path-empty ; zero characters 1995   / path-empty ; zero characters
1996   1996  
1997   path-abempty = *( "/" segment ) 1997   path-abempty = *( "/" segment )
1998   path-absolute = "/" [ segment-nz *( "/" segment ) ] 1998   path-absolute = "/" [ segment-nz *( "/" segment ) ]
1999   path-noscheme = segment-nz-nc *( "/" segment ) 1999   path-noscheme = segment-nz-nc *( "/" segment )
2000   path-rootless = segment-nz *( "/" segment ) 2000   path-rootless = segment-nz *( "/" segment )
2001   path-empty = 0<pchar> 2001   path-empty = 0<pchar>
2002   @endcode 2002   @endcode
2003   2003  
2004   @par Specification 2004   @par Specification
2005   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" 2005   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3"
2006   >3.3. Path (rfc3986)</a> 2006   >3.3. Path (rfc3986)</a>
2007   2007  
2008   @see 2008   @see
2009   @ref encoded_segments, 2009   @ref encoded_segments,
2010   @ref set_encoded_path, 2010   @ref set_encoded_path,
2011   @ref set_path, 2011   @ref set_path,
2012   @ref set_path_absolute. 2012   @ref set_path_absolute.
2013   */ 2013   */
2014   segments_encoded_ref 2014   segments_encoded_ref
2015   encoded_segments() noexcept; 2015   encoded_segments() noexcept;
2016   2016  
2017   /// @copydoc url_view_base::encoded_segments 2017   /// @copydoc url_view_base::encoded_segments
2018   segments_encoded_view 2018   segments_encoded_view
HITCBC 2019   1 encoded_segments() const noexcept 2019   1 encoded_segments() const noexcept
2020   { 2020   {
HITCBC 2021   1 return url_view_base::encoded_segments(); 2021   1 return url_view_base::encoded_segments();
2022   } 2022   }
2023   2023  
2024   //-------------------------------------------- 2024   //--------------------------------------------
2025   // 2025   //
2026   // Query 2026   // Query
2027   // 2027   //
2028   //-------------------------------------------- 2028   //--------------------------------------------
2029   2029  
2030   /** Set the query 2030   /** Set the query
2031   2031  
2032   This sets the query to the string, which 2032   This sets the query to the string, which
2033   can be empty. 2033   can be empty.
2034   An empty query is distinct from having 2034   An empty query is distinct from having
2035   no query. 2035   no query.
2036   Reserved characters in the string are 2036   Reserved characters in the string are
2037   percent-escaped in the result. 2037   percent-escaped in the result.
2038   2038  
2039   @par Example 2039   @par Example
2040   @code 2040   @code
2041   assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" ); 2041   assert( url( "http://example.com" ).set_query( "id=42" ).query() == "id=42" );
2042   @endcode 2042   @endcode
2043   2043  
2044   @par Postconditions 2044   @par Postconditions
2045   @code 2045   @code
2046   this->has_query() == true && this->query() == s 2046   this->has_query() == true && this->query() == s
2047   @endcode 2047   @endcode
2048   2048  
2049   @par Exception Safety 2049   @par Exception Safety
2050   Strong guarantee. 2050   Strong guarantee.
2051   Calls to allocate may throw. 2051   Calls to allocate may throw.
2052   2052  
2053   @param s The string to set. 2053   @param s The string to set.
2054   @return `*this` 2054   @return `*this`
2055   2055  
2056   @par BNF 2056   @par BNF
2057   @code 2057   @code
2058   query = *( pchar / "/" / "?" ) 2058   query = *( pchar / "/" / "?" )
2059   2059  
2060   query-param = key [ "=" value ] 2060   query-param = key [ "=" value ]
2061   query-params = [ query-param ] *( "&" query-param ) 2061   query-params = [ query-param ] *( "&" query-param )
2062   @endcode 2062   @endcode
2063   2063  
2064   @par Specification 2064   @par Specification
2065   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2065   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2066   >3.4. Query (rfc3986)</a> 2066   >3.4. Query (rfc3986)</a>
2067   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2067   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2068   >Query string (Wikipedia)</a> 2068   >Query string (Wikipedia)</a>
2069   2069  
2070   @see 2070   @see
2071   @ref encoded_params, 2071   @ref encoded_params,
2072   @ref params, 2072   @ref params,
2073   @ref remove_query, 2073   @ref remove_query,
2074   @ref set_encoded_query. 2074   @ref set_encoded_query.
2075   */ 2075   */
2076   url_base& 2076   url_base&
2077   set_query( 2077   set_query(
2078   core::string_view s); 2078   core::string_view s);
2079   2079  
2080   /** Set the query 2080   /** Set the query
2081   2081  
2082   This sets the query to the string, which 2082   This sets the query to the string, which
2083   may contain percent-escapes and can be 2083   may contain percent-escapes and can be
2084   empty. 2084   empty.
2085   An empty query is distinct from having 2085   An empty query is distinct from having
2086   no query. 2086   no query.
2087   Escapes in the string are preserved, 2087   Escapes in the string are preserved,
2088   and reserved characters in the string 2088   and reserved characters in the string
2089   are percent-escaped in the result. 2089   are percent-escaped in the result.
2090   2090  
2091   @par Example 2091   @par Example
2092   @code 2092   @code
2093   assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" ); 2093   assert( url( "http://example.com" ).set_encoded_query( "id=42" ).encoded_query() == "id=42" );
2094   @endcode 2094   @endcode
2095   2095  
2096   @par Postconditions 2096   @par Postconditions
2097   @code 2097   @code
2098   this->has_query() == true && this->query() == decode_view( s ); 2098   this->has_query() == true && this->query() == decode_view( s );
2099   @endcode 2099   @endcode
2100   2100  
2101   @par Exception Safety 2101   @par Exception Safety
2102   Strong guarantee. 2102   Strong guarantee.
2103   Calls to allocate may throw. 2103   Calls to allocate may throw.
2104   Exceptions thrown on invalid input. 2104   Exceptions thrown on invalid input.
2105   2105  
2106   @param s The string to set. 2106   @param s The string to set.
2107   @return `*this` 2107   @return `*this`
2108   2108  
2109   @throws system_error 2109   @throws system_error
2110   `s` contains an invalid percent-encoding. 2110   `s` contains an invalid percent-encoding.
2111   2111  
2112   @par BNF 2112   @par BNF
2113   @code 2113   @code
2114   query = *( pchar / "/" / "?" ) 2114   query = *( pchar / "/" / "?" )
2115   2115  
2116   query-param = key [ "=" value ] 2116   query-param = key [ "=" value ]
2117   query-params = [ query-param ] *( "&" query-param ) 2117   query-params = [ query-param ] *( "&" query-param )
2118   @endcode 2118   @endcode
2119   2119  
2120   @par Specification 2120   @par Specification
2121   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2121   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2122   >3.4. Query (rfc3986)</a> 2122   >3.4. Query (rfc3986)</a>
2123   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2123   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2124   >Query string (Wikipedia)</a> 2124   >Query string (Wikipedia)</a>
2125   2125  
2126   @see 2126   @see
2127   @ref encoded_params, 2127   @ref encoded_params,
2128   @ref params, 2128   @ref params,
2129   @ref remove_query, 2129   @ref remove_query,
2130   @ref set_query. 2130   @ref set_query.
2131   */ 2131   */
2132   url_base& 2132   url_base&
2133   set_encoded_query( 2133   set_encoded_query(
2134   pct_string_view s); 2134   pct_string_view s);
2135   2135  
2136   /** Return the query as a container of parameters 2136   /** Return the query as a container of parameters
2137   2137  
2138   This function returns a bidirectional 2138   This function returns a bidirectional
2139   view of key/value pairs over the query. 2139   view of key/value pairs over the query.
2140   The returned view references the same 2140   The returned view references the same
2141   underlying character buffer; ownership 2141   underlying character buffer; ownership
2142   is not transferred. 2142   is not transferred.
2143   Any percent-escapes in strings returned 2143   Any percent-escapes in strings returned
2144   when iterating the view are decoded first. 2144   when iterating the view are decoded first.
2145   The container is modifiable; changes 2145   The container is modifiable; changes
2146   to the container are reflected in the 2146   to the container are reflected in the
2147   underlying URL. 2147   underlying URL.
2148   2148  
2149   @return `*this` 2149   @return `*this`
2150   2150  
2151   @par Example 2151   @par Example
2152   @code 2152   @code
2153   params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params(); 2153   params_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params();
2154   @endcode 2154   @endcode
2155   2155  
2156   @par Complexity 2156   @par Complexity
2157   Constant. 2157   Constant.
2158   2158  
2159   @par Exception Safety 2159   @par Exception Safety
2160   Throws nothing. 2160   Throws nothing.
2161   2161  
2162   @par BNF 2162   @par BNF
2163   @code 2163   @code
2164   query = *( pchar / "/" / "?" ) 2164   query = *( pchar / "/" / "?" )
2165   2165  
2166   query-param = key [ "=" value ] 2166   query-param = key [ "=" value ]
2167   query-params = [ query-param ] *( "&" query-param ) 2167   query-params = [ query-param ] *( "&" query-param )
2168   @endcode 2168   @endcode
2169   2169  
2170   @par Specification 2170   @par Specification
2171   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2171   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2172   >3.4. Query (rfc3986)</a> 2172   >3.4. Query (rfc3986)</a>
2173   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2173   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2174   >Query string (Wikipedia)</a> 2174   >Query string (Wikipedia)</a>
2175   2175  
2176   @see 2176   @see
2177   @ref encoded_params, 2177   @ref encoded_params,
2178   @ref remove_query, 2178   @ref remove_query,
2179   @ref set_encoded_query, 2179   @ref set_encoded_query,
2180   @ref set_query. 2180   @ref set_query.
2181   */ 2181   */
2182   params_ref 2182   params_ref
2183   params() noexcept; 2183   params() noexcept;
2184   2184  
2185   /// @copydoc url_view_base::params 2185   /// @copydoc url_view_base::params
2186   params_view 2186   params_view
HITCBC 2187   5725 params() const noexcept 2187   5725 params() const noexcept
2188   { 2188   {
HITCBC 2189   5725 return url_view_base::params(); 2189   5725 return url_view_base::params();
2190   } 2190   }
2191   2191  
2192   /** Return the query as a container of parameters 2192   /** Return the query as a container of parameters
2193   2193  
2194   This function returns a bidirectional 2194   This function returns a bidirectional
2195   view of key/value pairs over the query. 2195   view of key/value pairs over the query.
2196   The returned view references the same 2196   The returned view references the same
2197   underlying character buffer; ownership 2197   underlying character buffer; ownership
2198   is not transferred. 2198   is not transferred.
2199   Any percent-escapes in strings returned 2199   Any percent-escapes in strings returned
2200   when iterating the view are decoded first. 2200   when iterating the view are decoded first.
2201   The container is modifiable; changes 2201   The container is modifiable; changes
2202   to the container are reflected in the 2202   to the container are reflected in the
2203   underlying URL. 2203   underlying URL.
2204   2204  
2205   @par Example 2205   @par Example
2206   @code 2206   @code
2207   encoding_opts opt; 2207   encoding_opts opt;
2208   opt.space_as_plus = true; 2208   opt.space_as_plus = true;
2209   params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt); 2209   params_ref pv = url( "/sql?id=42&name=jane+doe&page+size=20" ).params(opt);
2210   @endcode 2210   @endcode
2211   2211  
2212   @par Complexity 2212   @par Complexity
2213   Constant. 2213   Constant.
2214   2214  
2215   @par Exception Safety 2215   @par Exception Safety
2216   Throws nothing. 2216   Throws nothing.
2217   2217  
2218   @param opt The options for decoding. If 2218   @param opt The options for decoding. If
2219   this parameter is omitted, the `space_as_plus` 2219   this parameter is omitted, the `space_as_plus`
2220   is used. 2220   is used.
2221   2221  
2222   @return A range of references to the parameters. 2222   @return A range of references to the parameters.
2223   2223  
2224   @par BNF 2224   @par BNF
2225   @code 2225   @code
2226   query = *( pchar / "/" / "?" ) 2226   query = *( pchar / "/" / "?" )
2227   2227  
2228   query-param = key [ "=" value ] 2228   query-param = key [ "=" value ]
2229   query-params = [ query-param ] *( "&" query-param ) 2229   query-params = [ query-param ] *( "&" query-param )
2230   @endcode 2230   @endcode
2231   2231  
2232   @par Specification 2232   @par Specification
2233   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2233   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2234   >3.4. Query (rfc3986)</a> 2234   >3.4. Query (rfc3986)</a>
2235   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2235   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2236   >Query string (Wikipedia)</a> 2236   >Query string (Wikipedia)</a>
2237   2237  
2238   @see 2238   @see
2239   @ref encoded_params, 2239   @ref encoded_params,
2240   @ref remove_query, 2240   @ref remove_query,
2241   @ref set_encoded_query, 2241   @ref set_encoded_query,
2242   @ref set_query. 2242   @ref set_query.
2243   */ 2243   */
2244   params_ref 2244   params_ref
2245   params(encoding_opts opt) noexcept; 2245   params(encoding_opts opt) noexcept;
2246   2246  
2247   /// @copydoc url_view_base::encoded_params 2247   /// @copydoc url_view_base::encoded_params
2248   params_encoded_view 2248   params_encoded_view
HITCBC 2249   1 encoded_params() const noexcept 2249   1 encoded_params() const noexcept
2250   { 2250   {
HITCBC 2251   1 return url_view_base::encoded_params(); 2251   1 return url_view_base::encoded_params();
2252   } 2252   }
2253   2253  
2254   /** Return the query as a container of parameters 2254   /** Return the query as a container of parameters
2255   2255  
2256   This function returns a bidirectional 2256   This function returns a bidirectional
2257   view of key/value pairs over the query. 2257   view of key/value pairs over the query.
2258   The returned view references the same 2258   The returned view references the same
2259   underlying character buffer; ownership 2259   underlying character buffer; ownership
2260   is not transferred. 2260   is not transferred.
2261   Strings returned when iterating the 2261   Strings returned when iterating the
2262   range may contain percent escapes. 2262   range may contain percent escapes.
2263   The container is modifiable; changes 2263   The container is modifiable; changes
2264   to the container are reflected in the 2264   to the container are reflected in the
2265   underlying URL. 2265   underlying URL.
2266   2266  
2267   @return `*this` 2267   @return `*this`
2268   2268  
2269   @par Example 2269   @par Example
2270   @code 2270   @code
2271   params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params(); 2271   params_encoded_ref pv = url( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params();
2272   @endcode 2272   @endcode
2273   2273  
2274   @par Complexity 2274   @par Complexity
2275   Constant. 2275   Constant.
2276   2276  
2277   @par Exception Safety 2277   @par Exception Safety
2278   Throws nothing. 2278   Throws nothing.
2279   2279  
2280   @par BNF 2280   @par BNF
2281   @code 2281   @code
2282   query = *( pchar / "/" / "?" ) 2282   query = *( pchar / "/" / "?" )
2283   2283  
2284   query-param = key [ "=" value ] 2284   query-param = key [ "=" value ]
2285   query-params = [ query-param ] *( "&" query-param ) 2285   query-params = [ query-param ] *( "&" query-param )
2286   @endcode 2286   @endcode
2287   2287  
2288   @par Specification 2288   @par Specification
2289   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2289   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2290   >3.4. Query (rfc3986)</a> 2290   >3.4. Query (rfc3986)</a>
2291   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2291   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2292   >Query string (Wikipedia)</a> 2292   >Query string (Wikipedia)</a>
2293   2293  
2294   @see 2294   @see
2295   @ref params, 2295   @ref params,
2296   @ref remove_query, 2296   @ref remove_query,
2297   @ref set_encoded_query, 2297   @ref set_encoded_query,
2298   @ref set_query. 2298   @ref set_query.
2299   */ 2299   */
2300   params_encoded_ref 2300   params_encoded_ref
2301   encoded_params() noexcept; 2301   encoded_params() noexcept;
2302   2302  
2303   /** Set the query params 2303   /** Set the query params
2304   2304  
2305   This sets the query params to the list 2305   This sets the query params to the list
2306   of param_view, which can be empty. 2306   of param_view, which can be empty.
2307   2307  
2308   An empty list of params is distinct from 2308   An empty list of params is distinct from
2309   having no params. 2309   having no params.
2310   2310  
2311   Reserved characters in the string are 2311   Reserved characters in the string are
2312   percent-escaped in the result. 2312   percent-escaped in the result.
2313   2313  
2314   @par Example 2314   @par Example
2315   @code 2315   @code
2316   assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" ); 2316   assert( url( "http://example.com" ).set_params( {"id", "42"} ).query() == "id=42" );
2317   @endcode 2317   @endcode
2318   2318  
2319   @par Postconditions 2319   @par Postconditions
2320   @code 2320   @code
2321   this->has_query() == true 2321   this->has_query() == true
2322   @endcode 2322   @endcode
2323   2323  
2324   @par Exception Safety 2324   @par Exception Safety
2325   Strong guarantee. 2325   Strong guarantee.
2326   Calls to allocate may throw. 2326   Calls to allocate may throw.
2327   2327  
2328   @par Complexity 2328   @par Complexity
2329   Linear. 2329   Linear.
2330   2330  
2331   @param ps The params to set. 2331   @param ps The params to set.
2332   @param opts The options for encoding. 2332   @param opts The options for encoding.
2333   @return `*this` 2333   @return `*this`
2334   2334  
2335   @par BNF 2335   @par BNF
2336   @code 2336   @code
2337   query = *( pchar / "/" / "?" ) 2337   query = *( pchar / "/" / "?" )
2338   2338  
2339   query-param = key [ "=" value ] 2339   query-param = key [ "=" value ]
2340   query-params = [ query-param ] *( "&" query-param ) 2340   query-params = [ query-param ] *( "&" query-param )
2341   @endcode 2341   @endcode
2342   2342  
2343   @par Specification 2343   @par Specification
2344   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 2344   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
2345   >3.4. Query (rfc3986)</a> 2345   >3.4. Query (rfc3986)</a>
2346   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2346   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2347   >Query string (Wikipedia)</a> 2347   >Query string (Wikipedia)</a>
2348   2348  
2349   @see 2349   @see
2350   @ref encoded_params, 2350   @ref encoded_params,
2351   @ref remove_query, 2351   @ref remove_query,
2352   @ref set_encoded_query, 2352   @ref set_encoded_query,
2353   @ref set_query. 2353   @ref set_query.
2354   */ 2354   */
2355   url_base& 2355   url_base&
2356   set_params( 2356   set_params(
2357   std::initializer_list<param_view> ps, 2357   std::initializer_list<param_view> ps,
2358   encoding_opts opts = {}) noexcept; 2358   encoding_opts opts = {}) noexcept;
2359   2359  
2360   /** Set the query params 2360   /** Set the query params
2361   2361  
2362   This sets the query params to the elements 2362   This sets the query params to the elements
2363   in the list, which may contain 2363   in the list, which may contain
2364   percent-escapes and can be empty. 2364   percent-escapes and can be empty.
2365   2365  
2366   An empty list of params is distinct from 2366   An empty list of params is distinct from
2367   having no query. 2367   having no query.
2368   2368  
2369   Escapes in the string are preserved, 2369   Escapes in the string are preserved,
2370   and reserved characters in the string 2370   and reserved characters in the string
2371   are percent-escaped in the result. 2371   are percent-escaped in the result.
2372   2372  
2373   @par Example 2373   @par Example
2374   @code 2374   @code
2375   assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" ); 2375   assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
2376   @endcode 2376   @endcode
2377   2377  
2378   @par Postconditions 2378   @par Postconditions
2379   @code 2379   @code
2380   this->has_query() == true 2380   this->has_query() == true
2381   @endcode 2381   @endcode
2382   2382  
2383   @par Complexity 2383   @par Complexity
2384   Linear. 2384   Linear.
2385   2385  
2386   @par Exception Safety 2386   @par Exception Safety
2387   Strong guarantee. 2387   Strong guarantee.
2388   Calls to allocate may throw. 2388   Calls to allocate may throw.
2389   Exceptions thrown on invalid input. 2389   Exceptions thrown on invalid input.
2390   2390  
2391   @param ps The params to set. 2391   @param ps The params to set.
2392   2392  
2393   @return `*this` 2393   @return `*this`
2394   2394  
2395   @throws system_error 2395   @throws system_error
2396   some element in `ps` contains an invalid percent-encoding. 2396   some element in `ps` contains an invalid percent-encoding.
2397   2397  
2398   @par BNF 2398   @par BNF
2399   @code 2399   @code
2400   query = *( pchar / "/" / "?" ) 2400   query = *( pchar / "/" / "?" )
2401   2401  
2402   query-param = key [ "=" value ] 2402   query-param = key [ "=" value ]
2403   query-params = [ query-param ] *( "&" query-param ) 2403   query-params = [ query-param ] *( "&" query-param )
2404   @endcode 2404   @endcode
2405   2405  
2406   @par Specification 2406   @par Specification
2407   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2407   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2408   >3.4. Query (rfc3986)</a> 2408   >3.4. Query (rfc3986)</a>
2409   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2409   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2410   >Query string (Wikipedia)</a> 2410   >Query string (Wikipedia)</a>
2411   2411  
2412   @see 2412   @see
2413   @ref set_params, 2413   @ref set_params,
2414   @ref params, 2414   @ref params,
2415   @ref remove_query, 2415   @ref remove_query,
2416   @ref set_encoded_query, 2416   @ref set_encoded_query,
2417   @ref set_query. 2417   @ref set_query.
2418   */ 2418   */
2419   url_base& 2419   url_base&
2420   set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept; 2420   set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
2421   2421  
2422   /** Remove the query 2422   /** Remove the query
2423   2423  
2424   If a query is present, it is removed. 2424   If a query is present, it is removed.
2425   An empty query is distinct from having 2425   An empty query is distinct from having
2426   no query. 2426   no query.
2427   2427  
2428   @return `*this` 2428   @return `*this`
2429   2429  
2430   @par Example 2430   @par Example
2431   @code 2431   @code
2432   assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" ); 2432   assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
2433   @endcode 2433   @endcode
2434   2434  
2435   @par Postconditions 2435   @par Postconditions
2436   @code 2436   @code
2437   this->has_query() == false && this->params().empty() 2437   this->has_query() == false && this->params().empty()
2438   @endcode 2438   @endcode
2439   2439  
2440   @par Exception Safety 2440   @par Exception Safety
2441   Throws nothing. 2441   Throws nothing.
2442   2442  
2443   @par BNF 2443   @par BNF
2444   @code 2444   @code
2445   query = *( pchar / "/" / "?" ) 2445   query = *( pchar / "/" / "?" )
2446   2446  
2447   query-param = key [ "=" value ] 2447   query-param = key [ "=" value ]
2448   query-params = [ query-param ] *( "&" query-param ) 2448   query-params = [ query-param ] *( "&" query-param )
2449   @endcode 2449   @endcode
2450   2450  
2451   @par Specification 2451   @par Specification
2452   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" 2452   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2453   >3.4. Query (rfc3986)</a> 2453   >3.4. Query (rfc3986)</a>
2454   @li <a href="https://en.wikipedia.org/wiki/Query_string" 2454   @li <a href="https://en.wikipedia.org/wiki/Query_string"
2455   >Query string (Wikipedia)</a> 2455   >Query string (Wikipedia)</a>
2456   2456  
2457   @see 2457   @see
2458   @ref encoded_params, 2458   @ref encoded_params,
2459   @ref params, 2459   @ref params,
2460   @ref set_encoded_query, 2460   @ref set_encoded_query,
2461   @ref set_query. 2461   @ref set_query.
2462   */ 2462   */
2463   url_base& 2463   url_base&
2464   remove_query() noexcept; 2464   remove_query() noexcept;
2465   2465  
2466   //-------------------------------------------- 2466   //--------------------------------------------
2467   // 2467   //
2468   // Fragment 2468   // Fragment
2469   // 2469   //
2470   //-------------------------------------------- 2470   //--------------------------------------------
2471   2471  
2472   /** Remove the fragment 2472   /** Remove the fragment
2473   2473  
2474   This function removes the fragment. 2474   This function removes the fragment.
2475   An empty fragment is distinct from 2475   An empty fragment is distinct from
2476   having no fragment. 2476   having no fragment.
2477   2477  
2478   @return `*this` 2478   @return `*this`
2479   2479  
2480   @par Example 2480   @par Example
2481   @code 2481   @code
2482   assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" ); 2482   assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
2483   @endcode 2483   @endcode
2484   2484  
2485   @par Postconditions 2485   @par Postconditions
2486   @code 2486   @code
2487   this->has_fragment() == false && this->encoded_fragment() == "" 2487   this->has_fragment() == false && this->encoded_fragment() == ""
2488   @endcode 2488   @endcode
2489   2489  
2490   @par Complexity 2490   @par Complexity
2491   Constant. 2491   Constant.
2492   2492  
2493   @par Exception Safety 2493   @par Exception Safety
2494   Throws nothing. 2494   Throws nothing.
2495   2495  
2496   @par BNF 2496   @par BNF
2497   @code 2497   @code
2498   fragment = *( pchar / "/" / "?" ) 2498   fragment = *( pchar / "/" / "?" )
2499   @endcode 2499   @endcode
2500   2500  
2501   @par Specification 2501   @par Specification
2502   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" 2502   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2503   >3.5. Fragment</a> 2503   >3.5. Fragment</a>
2504   2504  
2505   @see 2505   @see
2506   @ref remove_fragment, 2506   @ref remove_fragment,
2507   @ref set_encoded_fragment, 2507   @ref set_encoded_fragment,
2508   @ref set_fragment. 2508   @ref set_fragment.
2509   */ 2509   */
2510   url_base& 2510   url_base&
2511   remove_fragment() noexcept; 2511   remove_fragment() noexcept;
2512   2512  
2513   /** Set the fragment. 2513   /** Set the fragment.
2514   2514  
2515   This function sets the fragment to the 2515   This function sets the fragment to the
2516   specified string, which may be empty. 2516   specified string, which may be empty.
2517   An empty fragment is distinct from 2517   An empty fragment is distinct from
2518   having no fragment. 2518   having no fragment.
2519   Reserved characters in the string are 2519   Reserved characters in the string are
2520   percent-escaped in the result. 2520   percent-escaped in the result.
2521   2521  
2522   @par Example 2522   @par Example
2523   @code 2523   @code
2524   assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" ); 2524   assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
2525   @endcode 2525   @endcode
2526   2526  
2527   @par Postconditions 2527   @par Postconditions
2528   @code 2528   @code
2529   this->has_fragment() == true && this->fragment() == s 2529   this->has_fragment() == true && this->fragment() == s
2530   @endcode 2530   @endcode
2531   2531  
2532   @par Complexity 2532   @par Complexity
2533   Linear in `this->size() + s.size()`. 2533   Linear in `this->size() + s.size()`.
2534   2534  
2535   @par Exception Safety 2535   @par Exception Safety
2536   Strong guarantee. 2536   Strong guarantee.
2537   Calls to allocate may throw. 2537   Calls to allocate may throw.
2538   2538  
2539   @param s The string to set. 2539   @param s The string to set.
2540   2540  
2541   @return `*this` 2541   @return `*this`
2542   2542  
2543   @par BNF 2543   @par BNF
2544   @code 2544   @code
2545   fragment = *( pchar / "/" / "?" ) 2545   fragment = *( pchar / "/" / "?" )
2546   @endcode 2546   @endcode
2547   2547  
2548   @par Specification 2548   @par Specification
2549   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" 2549   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2550   >3.5. Fragment</a> 2550   >3.5. Fragment</a>
2551   2551  
2552   @see 2552   @see
2553   @ref remove_fragment, 2553   @ref remove_fragment,
2554   @ref set_encoded_fragment. 2554   @ref set_encoded_fragment.
2555   */ 2555   */
2556   url_base& 2556   url_base&
2557   set_fragment( 2557   set_fragment(
2558   core::string_view s); 2558   core::string_view s);
2559   2559  
2560   /** Set the fragment. 2560   /** Set the fragment.
2561   2561  
2562   This function sets the fragment to the 2562   This function sets the fragment to the
2563   specified string, which may contain 2563   specified string, which may contain
2564   percent-escapes and which may be empty. 2564   percent-escapes and which may be empty.
2565   An empty fragment is distinct from 2565   An empty fragment is distinct from
2566   having no fragment. 2566   having no fragment.
2567   Escapes in the string are preserved, 2567   Escapes in the string are preserved,
2568   and reserved characters in the string 2568   and reserved characters in the string
2569   are percent-escaped in the result. 2569   are percent-escaped in the result.
2570   2570  
2571   @return `*this` 2571   @return `*this`
2572   2572  
2573   @par Example 2573   @par Example
2574   @code 2574   @code
2575   assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" ); 2575   assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
2576   @endcode 2576   @endcode
2577   2577  
2578   @par Postconditions 2578   @par Postconditions
2579   @code 2579   @code
2580   this->has_fragment() == true && this->fragment() == decode_view( s ) 2580   this->has_fragment() == true && this->fragment() == decode_view( s )
2581   @endcode 2581   @endcode
2582   2582  
2583   @par Complexity 2583   @par Complexity
2584   Linear in `this->size() + s.size()`. 2584   Linear in `this->size() + s.size()`.
2585   2585  
2586   @par Exception Safety 2586   @par Exception Safety
2587   Strong guarantee. 2587   Strong guarantee.
2588   Calls to allocate may throw. 2588   Calls to allocate may throw.
2589   Exceptions thrown on invalid input. 2589   Exceptions thrown on invalid input.
2590   2590  
2591   @throw system_error 2591   @throw system_error
2592   `s` contains an invalid percent-encoding. 2592   `s` contains an invalid percent-encoding.
2593   2593  
2594   @param s The string to set. 2594   @param s The string to set.
2595   2595  
2596   @return `*this` 2596   @return `*this`
2597   2597  
2598   @par BNF 2598   @par BNF
2599   @code 2599   @code
2600   fragment = *( pchar / "/" / "?" ) 2600   fragment = *( pchar / "/" / "?" )
2601   @endcode 2601   @endcode
2602   2602  
2603   @par Specification 2603   @par Specification
2604   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" 2604   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2605   >3.5. Fragment</a> 2605   >3.5. Fragment</a>
2606   2606  
2607   @see 2607   @see
2608   @ref remove_fragment, 2608   @ref remove_fragment,
2609   @ref set_fragment. 2609   @ref set_fragment.
2610   */ 2610   */
2611   url_base& 2611   url_base&
2612   set_encoded_fragment( 2612   set_encoded_fragment(
2613   pct_string_view s); 2613   pct_string_view s);
2614   2614  
2615   //-------------------------------------------- 2615   //--------------------------------------------
2616   // 2616   //
2617   // Compound Fields 2617   // Compound Fields
2618   // 2618   //
2619   //-------------------------------------------- 2619   //--------------------------------------------
2620   2620  
2621   /** Remove the origin component 2621   /** Remove the origin component
2622   2622  
2623   This function removes the origin, which 2623   This function removes the origin, which
2624   consists of the scheme and authority. 2624   consists of the scheme and authority.
2625   2625  
2626   @return `*this` 2626   @return `*this`
2627   2627  
2628   @par Example 2628   @par Example
2629   @code 2629   @code
2630   assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" ); 2630   assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
2631   @endcode 2631   @endcode
2632   2632  
2633   @par Postconditions 2633   @par Postconditions
2634   @code 2634   @code
2635   this->scheme_id() == scheme::none && this->has_authority() == false 2635   this->scheme_id() == scheme::none && this->has_authority() == false
2636   @endcode 2636   @endcode
2637   2637  
2638   @par Complexity 2638   @par Complexity
2639   Linear in `this->size()`. 2639   Linear in `this->size()`.
2640   2640  
2641   @par Exception Safety 2641   @par Exception Safety
2642   Throws nothing. 2642   Throws nothing.
2643   */ 2643   */
2644   url_base& 2644   url_base&
2645   remove_origin(); 2645   remove_origin();
2646   2646  
2647   //-------------------------------------------- 2647   //--------------------------------------------
2648   // 2648   //
2649   // Normalization 2649   // Normalization
2650   // 2650   //
2651   //-------------------------------------------- 2651   //--------------------------------------------
2652   2652  
2653   /** Normalize the URL components 2653   /** Normalize the URL components
2654   2654  
2655   Applies Syntax-based normalization to 2655   Applies Syntax-based normalization to
2656   all components of the URL. 2656   all components of the URL.
2657   2657  
2658   The scheme is normalized to lowercase. 2658   The scheme is normalized to lowercase.
2659   2659  
2660   @code 2660   @code
2661   assert( url( "HTTP://www.example.com" ).normalize().buffer() == "http://www.example.com" ); 2661   assert( url( "HTTP://www.example.com" ).normalize().buffer() == "http://www.example.com" );
2662   @endcode 2662   @endcode
2663   2663  
2664   The host is normalized to lowercase. 2664   The host is normalized to lowercase.
2665   Percent-encoding triplets are normalized 2665   Percent-encoding triplets are normalized
2666   to uppercase letters. Percent-encoded 2666   to uppercase letters. Percent-encoded
2667   octets that correspond to unreserved 2667   octets that correspond to unreserved
2668   characters are decoded. 2668   characters are decoded.
2669   2669  
2670   @code 2670   @code
2671   assert( url( "http://www.Example.com" ).normalize().buffer() == "http://www.example.com" ); 2671   assert( url( "http://www.Example.com" ).normalize().buffer() == "http://www.example.com" );
2672   assert( url( "http://www.%65xample.com" ).normalize().buffer() == "http://www.example.com" ); 2672   assert( url( "http://www.%65xample.com" ).normalize().buffer() == "http://www.example.com" );
2673   @endcode 2673   @endcode
2674   2674  
2675   Percent-encoding triplets in the path 2675   Percent-encoding triplets in the path
2676   are normalized to uppercase letters. 2676   are normalized to uppercase letters.
2677   Percent-encoded octets that correspond 2677   Percent-encoded octets that correspond
2678   to unreserved characters are decoded. 2678   to unreserved characters are decoded.
2679   Redundant path-segments "." and ".." 2679   Redundant path-segments "." and ".."
2680   are removed. 2680   are removed.
2681   2681  
2682   @code 2682   @code
2683   assert( url( "http://www.example.com/a/b/../c" ).normalize().buffer() == "http://www.example.com/a/c" ); 2683   assert( url( "http://www.example.com/a/b/../c" ).normalize().buffer() == "http://www.example.com/a/c" );
2684   assert( url( "http://www.example.com/a/./b" ).normalize().buffer() == "http://www.example.com/a/b" ); 2684   assert( url( "http://www.example.com/a/./b" ).normalize().buffer() == "http://www.example.com/a/b" );
2685   assert( url( "http://www.example.com/%63ss" ).normalize().buffer() == "http://www.example.com/css" ); 2685   assert( url( "http://www.example.com/%63ss" ).normalize().buffer() == "http://www.example.com/css" );
2686   @endcode 2686   @endcode
2687   2687  
2688   Percent-encoding triplets in the query 2688   Percent-encoding triplets in the query
2689   are normalized to uppercase letters. 2689   are normalized to uppercase letters.
2690   Percent-encoded octets that correspond 2690   Percent-encoded octets that correspond
2691   to unreserved characters are decoded. 2691   to unreserved characters are decoded.
2692   2692  
2693   @code 2693   @code
2694   assert( url( "http://www.example.com?a=%62" ).normalize().buffer() == "http://www.example.com?a=b" ); 2694   assert( url( "http://www.example.com?a=%62" ).normalize().buffer() == "http://www.example.com?a=b" );
2695   @endcode 2695   @endcode
2696   2696  
2697   Percent-encoding triplets in the fragment 2697   Percent-encoding triplets in the fragment
2698   are normalized to uppercase letters. 2698   are normalized to uppercase letters.
2699   Percent-encoded octets that correspond 2699   Percent-encoded octets that correspond
2700   to unreserved characters are decoded. 2700   to unreserved characters are decoded.
2701   2701  
2702   @code 2702   @code
2703   assert( url( "http://www.example.com#%61bc" ).normalize().buffer() == "http://www.example.com#abc" ); 2703   assert( url( "http://www.example.com#%61bc" ).normalize().buffer() == "http://www.example.com#abc" );
2704   @endcode 2704   @endcode
2705   2705  
2706   Applying normalization to a URL with all 2706   Applying normalization to a URL with all
2707   components percent-encoded: 2707   components percent-encoded:
2708   2708  
2709   @code 2709   @code
2710   assert( url( "HTTP://www.Example.com/%70ath?%71uery#%66rag" ).normalize().buffer() == "http://www.example.com/path?query#frag" ); 2710   assert( url( "HTTP://www.Example.com/%70ath?%71uery#%66rag" ).normalize().buffer() == "http://www.example.com/path?query#frag" );
2711   @endcode 2711   @endcode
2712   2712  
2713   @return `*this` 2713   @return `*this`
2714   2714  
2715   @par Exception Safety 2715   @par Exception Safety
2716   Strong guarantee. 2716   Strong guarantee.
2717   Calls to allocate may throw. 2717   Calls to allocate may throw.
2718   2718  
2719   @par Specification 2719   @par Specification
2720   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2720   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2721   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2721   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2722   2722  
2723   @see 2723   @see
2724   @ref normalize_scheme, 2724   @ref normalize_scheme,
2725   @ref normalize_authority, 2725   @ref normalize_authority,
2726   @ref normalize_path, 2726   @ref normalize_path,
2727   @ref normalize_query, 2727   @ref normalize_query,
2728   @ref normalize_fragment 2728   @ref normalize_fragment
2729   2729  
2730   */ 2730   */
2731   url_base& 2731   url_base&
2732   normalize(); 2732   normalize();
2733   2733  
2734   /** Normalize the URL scheme 2734   /** Normalize the URL scheme
2735   2735  
2736   Applies Syntax-based normalization to the 2736   Applies Syntax-based normalization to the
2737   URL scheme. 2737   URL scheme.
2738   2738  
2739   The scheme is normalized to lowercase. 2739   The scheme is normalized to lowercase.
2740   2740  
2741   @code 2741   @code
2742   assert( url( "HTTP://www.example.com" ).normalize_scheme().buffer() == "http://www.example.com" ); 2742   assert( url( "HTTP://www.example.com" ).normalize_scheme().buffer() == "http://www.example.com" );
2743   @endcode 2743   @endcode
2744   2744  
2745   @return `*this` 2745   @return `*this`
2746   2746  
2747   @par Exception Safety 2747   @par Exception Safety
2748   Strong guarantee. 2748   Strong guarantee.
2749   Calls to allocate may throw. 2749   Calls to allocate may throw.
2750   2750  
2751   @par Specification 2751   @par Specification
2752   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2752   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2753   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2753   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2754   2754  
2755   */ 2755   */
2756   url_base& 2756   url_base&
2757   normalize_scheme(); 2757   normalize_scheme();
2758   2758  
2759   /** Normalize the URL authority 2759   /** Normalize the URL authority
2760   2760  
2761   Applies Syntax-based normalization to the 2761   Applies Syntax-based normalization to the
2762   URL authority. 2762   URL authority.
2763   2763  
2764   The host is normalized to lowercase. 2764   The host is normalized to lowercase.
2765   Percent-encoding triplets are normalized 2765   Percent-encoding triplets are normalized
2766   to uppercase letters. Percent-encoded 2766   to uppercase letters. Percent-encoded
2767   octets that correspond to unreserved 2767   octets that correspond to unreserved
2768   characters are decoded. 2768   characters are decoded.
2769   2769  
2770   @code 2770   @code
2771   assert( url( "http://www.Example.com" ).normalize_authority().buffer() == "http://www.example.com" ); 2771   assert( url( "http://www.Example.com" ).normalize_authority().buffer() == "http://www.example.com" );
2772   assert( url( "http://www.%65xample.com" ).normalize_authority().buffer() == "http://www.example.com" ); 2772   assert( url( "http://www.%65xample.com" ).normalize_authority().buffer() == "http://www.example.com" );
2773   @endcode 2773   @endcode
2774   2774  
2775   @return `*this` 2775   @return `*this`
2776   2776  
2777   @par Exception Safety 2777   @par Exception Safety
2778   Strong guarantee. 2778   Strong guarantee.
2779   Calls to allocate may throw. 2779   Calls to allocate may throw.
2780   2780  
2781   @par Specification 2781   @par Specification
2782   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2782   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2783   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2783   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2784   2784  
2785   */ 2785   */
2786   url_base& 2786   url_base&
2787   normalize_authority(); 2787   normalize_authority();
2788   2788  
2789   /** Normalize the URL path 2789   /** Normalize the URL path
2790   2790  
2791   Applies Syntax-based normalization to the 2791   Applies Syntax-based normalization to the
2792   URL path. 2792   URL path.
2793   2793  
2794   Percent-encoding triplets are normalized 2794   Percent-encoding triplets are normalized
2795   to uppercase letters. Percent-encoded 2795   to uppercase letters. Percent-encoded
2796   octets that correspond to unreserved 2796   octets that correspond to unreserved
2797   characters are decoded. Redundant 2797   characters are decoded. Redundant
2798   path-segments "." and ".." are removed. 2798   path-segments "." and ".." are removed.
2799   2799  
2800   @code 2800   @code
2801   assert( url( "http://www.example.com/a/b/../c" ).normalize_path().buffer() == "http://www.example.com/a/c" ); 2801   assert( url( "http://www.example.com/a/b/../c" ).normalize_path().buffer() == "http://www.example.com/a/c" );
2802   assert( url( "http://www.example.com/a/./b" ).normalize_path().buffer() == "http://www.example.com/a/b" ); 2802   assert( url( "http://www.example.com/a/./b" ).normalize_path().buffer() == "http://www.example.com/a/b" );
2803   assert( url( "http://www.example.com/%63ss" ).normalize_path().buffer() == "http://www.example.com/css" ); 2803   assert( url( "http://www.example.com/%63ss" ).normalize_path().buffer() == "http://www.example.com/css" );
2804   @endcode 2804   @endcode
2805   2805  
2806   @return `*this` 2806   @return `*this`
2807   2807  
2808   @par Exception Safety 2808   @par Exception Safety
2809   Strong guarantee. 2809   Strong guarantee.
2810   Calls to allocate may throw. 2810   Calls to allocate may throw.
2811   2811  
2812   @par Specification 2812   @par Specification
2813   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2813   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2814   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2814   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2815   2815  
2816   */ 2816   */
2817   url_base& 2817   url_base&
2818   normalize_path(); 2818   normalize_path();
2819   2819  
2820   /** Normalize the URL query 2820   /** Normalize the URL query
2821   2821  
2822   Applies Syntax-based normalization to the 2822   Applies Syntax-based normalization to the
2823   URL query. 2823   URL query.
2824   2824  
2825   Percent-encoding triplets are normalized 2825   Percent-encoding triplets are normalized
2826   to uppercase letters. Percent-encoded 2826   to uppercase letters. Percent-encoded
2827   octets that correspond to unreserved 2827   octets that correspond to unreserved
2828   characters are decoded. 2828   characters are decoded.
2829   2829  
2830   @code 2830   @code
2831   assert( url( "http://www.example.com?a=%62" ).normalize_query().buffer() == "http://www.example.com?a=b" ); 2831   assert( url( "http://www.example.com?a=%62" ).normalize_query().buffer() == "http://www.example.com?a=b" );
2832   @endcode 2832   @endcode
2833   2833  
2834   @return `*this` 2834   @return `*this`
2835   2835  
2836   @par Exception Safety 2836   @par Exception Safety
2837   Strong guarantee. 2837   Strong guarantee.
2838   Calls to allocate may throw. 2838   Calls to allocate may throw.
2839   2839  
2840   @par Specification 2840   @par Specification
2841   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2841   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2842   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2842   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2843   2843  
2844   */ 2844   */
2845   url_base& 2845   url_base&
2846   normalize_query(); 2846   normalize_query();
2847   2847  
2848   /** Normalize the URL fragment 2848   /** Normalize the URL fragment
2849   2849  
2850   Applies Syntax-based normalization to the 2850   Applies Syntax-based normalization to the
2851   URL fragment. 2851   URL fragment.
2852   2852  
2853   Percent-encoding triplets are normalized 2853   Percent-encoding triplets are normalized
2854   to uppercase letters. Percent-encoded 2854   to uppercase letters. Percent-encoded
2855   octets that correspond to unreserved 2855   octets that correspond to unreserved
2856   characters are decoded. 2856   characters are decoded.
2857   2857  
2858   @code 2858   @code
2859   assert( url( "http://www.example.com#%61bc" ).normalize_fragment().buffer() == "http://www.example.com#abc" ); 2859   assert( url( "http://www.example.com#%61bc" ).normalize_fragment().buffer() == "http://www.example.com#abc" );
2860   @endcode 2860   @endcode
2861   2861  
2862   @return `*this` 2862   @return `*this`
2863   2863  
2864   @par Exception Safety 2864   @par Exception Safety
2865   Strong guarantee. 2865   Strong guarantee.
2866   Calls to allocate may throw. 2866   Calls to allocate may throw.
2867   2867  
2868   @par Specification 2868   @par Specification
2869   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" 2869   @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2870   >6.2.2 Syntax-Based Normalization (rfc3986)</a> 2870   >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2871   2871  
2872   */ 2872   */
2873   url_base& 2873   url_base&
2874   normalize_fragment(); 2874   normalize_fragment();
2875   2875  
2876   // 2876   //
2877   // (end of fluent API) 2877   // (end of fluent API)
2878   // 2878   //
2879   //-------------------------------------------- 2879   //--------------------------------------------
2880   2880  
2881   //-------------------------------------------- 2881   //--------------------------------------------
2882   // 2882   //
2883   // Resolution 2883   // Resolution
2884   // 2884   //
2885   //-------------------------------------------- 2885   //--------------------------------------------
2886   2886  
2887   /** Resolve a URL reference against this base URL 2887   /** Resolve a URL reference against this base URL
2888   2888  
2889   This function attempts to resolve a URL 2889   This function attempts to resolve a URL
2890   reference `ref` against this base URL 2890   reference `ref` against this base URL
2891   in a manner similar to that of a web browser 2891   in a manner similar to that of a web browser
2892   resolving an anchor tag. 2892   resolving an anchor tag.
2893   2893  
2894   This URL must satisfy the <em>URI</em> 2894   This URL must satisfy the <em>URI</em>
2895   grammar. In other words, it must contain 2895   grammar. In other words, it must contain
2896   a scheme. 2896   a scheme.
2897   2897  
2898   Relative references are only usable when 2898   Relative references are only usable when
2899   in the context of a base absolute URI. 2899   in the context of a base absolute URI.
2900   This process of resolving a relative 2900   This process of resolving a relative
2901   <em>reference</em> within the context of 2901   <em>reference</em> within the context of
2902   a <em>base</em> URI is defined in detail 2902   a <em>base</em> URI is defined in detail
2903   in rfc3986 (see below). 2903   in rfc3986 (see below).
2904   2904  
2905   The resolution process works as if the 2905   The resolution process works as if the
2906   relative reference is appended to the base 2906   relative reference is appended to the base
2907   URI and the result is normalized. 2907   URI and the result is normalized.
2908   2908  
2909   Given the input base URL, this function 2909   Given the input base URL, this function
2910   resolves the relative reference 2910   resolves the relative reference
2911   as if performing the following steps: 2911   as if performing the following steps:
2912   2912  
2913   @li Ensure the base URI has at least a scheme 2913   @li Ensure the base URI has at least a scheme
2914   @li Normalizing the reference path 2914   @li Normalizing the reference path
2915   @li Merge base and reference paths 2915   @li Merge base and reference paths
2916   @li Normalize the merged path 2916   @li Normalize the merged path
2917   2917  
2918   This function places the result of the 2918   This function places the result of the
2919   resolution into this URL in place. 2919   resolution into this URL in place.
2920   2920  
2921   If an error occurs, the contents of 2921   If an error occurs, the contents of
2922   this URL are unspecified and a `boost::system::result` 2922   this URL are unspecified and a `boost::system::result`
2923   with an `system::error_code` is returned. 2923   with an `system::error_code` is returned.
2924   2924  
2925   @note Abnormal hrefs where the number of ".." 2925   @note Abnormal hrefs where the number of ".."
2926   segments exceeds the number of segments in 2926   segments exceeds the number of segments in
2927   the base path are handled by including the 2927   the base path are handled by including the
2928   unmatched ".." segments in the result, as described 2928   unmatched ".." segments in the result, as described
2929   in <a href="https://www.rfc-editor.org/errata/eid4547" 2929   in <a href="https://www.rfc-editor.org/errata/eid4547"
2930   >Errata 4547</a>. 2930   >Errata 4547</a>.
2931   2931  
2932   @par Example 2932   @par Example
2933   @code 2933   @code
2934   url base1( "/one/two/three" ); 2934   url base1( "/one/two/three" );
2935   base1.resolve("four"); 2935   base1.resolve("four");
2936   assert( base1.buffer() == "/one/two/four" ); 2936   assert( base1.buffer() == "/one/two/four" );
2937   2937  
2938   url base2( "http://example.com/" ) 2938   url base2( "http://example.com/" )
2939   base2.resolve("/one"); 2939   base2.resolve("/one");
2940   assert( base2.buffer() == "http://example.com/one" ); 2940   assert( base2.buffer() == "http://example.com/one" );
2941   2941  
2942   url base3( "http://example.com/one" ); 2942   url base3( "http://example.com/one" );
2943   base3.resolve("/two"); 2943   base3.resolve("/two");
2944   assert( base3.buffer() == "http://example.com/two" ); 2944   assert( base3.buffer() == "http://example.com/two" );
2945   2945  
2946   url base4( "http://a/b/c/d;p?q" ); 2946   url base4( "http://a/b/c/d;p?q" );
2947   base4.resolve("g#s"); 2947   base4.resolve("g#s");
2948   assert( base4.buffer() == "http://a/b/c/g#s" ); 2948   assert( base4.buffer() == "http://a/b/c/g#s" );
2949   @endcode 2949   @endcode
2950   2950  
2951   @par BNF 2951   @par BNF
2952   @code 2952   @code
2953   absolute-URI = scheme ":" hier-part [ "?" query ] 2953   absolute-URI = scheme ":" hier-part [ "?" query ]
2954   @endcode 2954   @endcode
2955   2955  
2956   @par Exception Safety 2956   @par Exception Safety
2957   Basic guarantee. 2957   Basic guarantee.
2958   Calls to allocate may throw. 2958   Calls to allocate may throw.
2959   2959  
2960   @return An empty `boost::system::result` upon success, 2960   @return An empty `boost::system::result` upon success,
2961   otherwise an error code if `!base.has_scheme()`. 2961   otherwise an error code if `!base.has_scheme()`.
2962   2962  
2963   @param ref The URL reference to resolve. 2963   @param ref The URL reference to resolve.
2964   2964  
2965   @par Specification 2965   @par Specification
2966   <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5" 2966   <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
2967   >5. Reference Resolution (rfc3986)</a> 2967   >5. Reference Resolution (rfc3986)</a>
2968   2968  
2969   @see 2969   @see
2970   @ref url, 2970   @ref url,
2971   @ref url_view. 2971   @ref url_view.
2972   */ 2972   */
2973   system::result<void> 2973   system::result<void>
2974   resolve( 2974   resolve(
2975   url_view_base const& ref); 2975   url_view_base const& ref);
2976   2976  
2977   friend 2977   friend
2978   system::result<void> 2978   system::result<void>
2979   resolve( 2979   resolve(
2980   url_view_base const& base, 2980   url_view_base const& base,
2981   url_view_base const& ref, 2981   url_view_base const& ref,
2982   url_base& dest); 2982   url_base& dest);
2983   2983  
2984   private: 2984   private:
2985   //-------------------------------------------- 2985   //--------------------------------------------
2986   // 2986   //
2987   // implementation 2987   // implementation
2988   // 2988   //
2989   //-------------------------------------------- 2989   //--------------------------------------------
2990   2990  
2991   void check_invariants() const noexcept; 2991   void check_invariants() const noexcept;
2992   2992  
2993   char* resize_impl(int, std::size_t, op_t&); 2993   char* resize_impl(int, std::size_t, op_t&);
2994   char* resize_impl(int, int, std::size_t, op_t&); 2994   char* resize_impl(int, int, std::size_t, op_t&);
2995   char* shrink_impl(int, std::size_t, op_t&); 2995   char* shrink_impl(int, std::size_t, op_t&);
2996   char* shrink_impl(int, int, std::size_t, op_t&); 2996   char* shrink_impl(int, int, std::size_t, op_t&);
2997   2997  
2998   void set_scheme_impl(core::string_view, urls::scheme); 2998   void set_scheme_impl(core::string_view, urls::scheme);
2999   char* set_user_impl(std::size_t n, op_t& op); 2999   char* set_user_impl(std::size_t n, op_t& op);
3000   char* set_password_impl(std::size_t n, op_t& op); 3000   char* set_password_impl(std::size_t n, op_t& op);
3001   char* set_userinfo_impl(std::size_t n, op_t& op); 3001   char* set_userinfo_impl(std::size_t n, op_t& op);
3002   char* set_host_impl(std::size_t n, op_t& op); 3002   char* set_host_impl(std::size_t n, op_t& op);
3003   char* set_port_impl(std::size_t n, op_t& op); 3003   char* set_port_impl(std::size_t n, op_t& op);
3004   char* set_path_impl(std::size_t n, op_t& op); 3004   char* set_path_impl(std::size_t n, op_t& op);
3005   3005  
3006   void 3006   void
3007   set_host_ipv6_and_zone_id( 3007   set_host_ipv6_and_zone_id(
3008   ipv6_address const& addr, 3008   ipv6_address const& addr,
3009   core::string_view zone_id); 3009   core::string_view zone_id);
3010   3010  
3011   void 3011   void
3012   set_host_ipv6_and_encoded_zone_id( 3012   set_host_ipv6_and_encoded_zone_id(
3013   ipv6_address const& addr, 3013   ipv6_address const& addr,
3014   pct_string_view zone_id); 3014   pct_string_view zone_id);
3015   3015  
3016   core::string_view 3016   core::string_view
3017   first_segment() const noexcept; 3017   first_segment() const noexcept;
3018   3018  
3019   detail::segments_iter_impl 3019   detail::segments_iter_impl
3020   edit_segments( 3020   edit_segments(
3021   detail::segments_iter_impl const&, 3021   detail::segments_iter_impl const&,
3022   detail::segments_iter_impl const&, 3022   detail::segments_iter_impl const&,
3023   detail::any_segments_iter&& it0, 3023   detail::any_segments_iter&& it0,
3024   int absolute = -1); 3024   int absolute = -1);
3025   3025  
3026   auto 3026   auto
3027   edit_params( 3027   edit_params(
3028   detail::params_iter_impl const&, 3028   detail::params_iter_impl const&,
3029   detail::params_iter_impl const&, 3029   detail::params_iter_impl const&,
3030   detail::any_params_iter&&) -> 3030   detail::any_params_iter&&) ->
3031   detail::params_iter_impl; 3031   detail::params_iter_impl;
3032   3032  
3033   // Decode any unnecessary percent-escapes 3033   // Decode any unnecessary percent-escapes
3034   // and ensures hexadecimals are uppercase. 3034   // and ensures hexadecimals are uppercase.
3035   // The encoding of ignored characters is 3035   // The encoding of ignored characters is
3036   // preserved. 3036   // preserved.
3037   template 3037   template
3038   <class AllowedCharSet, 3038   <class AllowedCharSet,
3039   class IgnoredCharSet> 3039   class IgnoredCharSet>
3040   void 3040   void
3041   normalize_octets_impl( 3041   normalize_octets_impl(
3042   int, 3042   int,
3043   AllowedCharSet const& allowed, 3043   AllowedCharSet const& allowed,
3044   IgnoredCharSet const& ignored, 3044   IgnoredCharSet const& ignored,
3045   op_t&) noexcept; 3045   op_t&) noexcept;
3046   3046  
3047   template<class CharSet> 3047   template<class CharSet>
3048   void 3048   void
3049   normalize_octets_impl( 3049   normalize_octets_impl(
3050   int, 3050   int,
3051   CharSet const& allowed, 3051   CharSet const& allowed,
3052   op_t&) noexcept; 3052   op_t&) noexcept;
3053   3053  
3054   void decoded_to_lower_impl(int id) noexcept; 3054   void decoded_to_lower_impl(int id) noexcept;
3055   void to_lower_impl(int id) noexcept; 3055   void to_lower_impl(int id) noexcept;
3056   }; 3056   };
3057   3057  
3058   //------------------------------------------------ 3058   //------------------------------------------------
3059   3059  
3060   /** Resolve a URL reference against a base URL 3060   /** Resolve a URL reference against a base URL
3061   3061  
3062   This function attempts to resolve a URL 3062   This function attempts to resolve a URL
3063   reference `ref` against the base URL `base` 3063   reference `ref` against the base URL `base`
3064   in a manner similar to that of a web browser 3064   in a manner similar to that of a web browser
3065   resolving an anchor tag. 3065   resolving an anchor tag.
3066   3066  
3067   The base URL must satisfy the <em>URI</em> 3067   The base URL must satisfy the <em>URI</em>
3068   grammar. In other words, it must contain 3068   grammar. In other words, it must contain
3069   a scheme. 3069   a scheme.
3070   3070  
3071   Relative references are only usable when 3071   Relative references are only usable when
3072   in the context of a base absolute URI. 3072   in the context of a base absolute URI.
3073   This process of resolving a relative 3073   This process of resolving a relative
3074   <em>reference</em> within the context of 3074   <em>reference</em> within the context of
3075   a <em>base</em> URI is defined in detail 3075   a <em>base</em> URI is defined in detail
3076   in rfc3986 (see below). 3076   in rfc3986 (see below).
3077   3077  
3078   The resolution process works as if the 3078   The resolution process works as if the
3079   relative reference is appended to the base 3079   relative reference is appended to the base
3080   URI and the result is normalized. 3080   URI and the result is normalized.
3081   3081  
3082   Given the input base URL, this function 3082   Given the input base URL, this function
3083   resolves the relative reference 3083   resolves the relative reference
3084   as if performing the following steps: 3084   as if performing the following steps:
3085   3085  
3086   @li Ensure the base URI has at least a scheme 3086   @li Ensure the base URI has at least a scheme
3087   @li Normalizing the reference path 3087   @li Normalizing the reference path
3088   @li Merge base and reference paths 3088   @li Merge base and reference paths
3089   @li Normalize the merged path 3089   @li Normalize the merged path
3090   3090  
3091   This function places the result of the 3091   This function places the result of the
3092   resolution into `dest`, which can be 3092   resolution into `dest`, which can be
3093   any of the url containers that inherit 3093   any of the url containers that inherit
3094   from @ref url_base. 3094   from @ref url_base.
3095   3095  
3096   If an error occurs, the contents of 3096   If an error occurs, the contents of
3097   `dest` is unspecified and `ec` is set. 3097   `dest` is unspecified and `ec` is set.
3098   3098  
3099   @note Abnormal hrefs where the number of ".." 3099   @note Abnormal hrefs where the number of ".."
3100   segments exceeds the number of segments in 3100   segments exceeds the number of segments in
3101   the base path are handled by including the 3101   the base path are handled by including the
3102   unmatched ".." segments in the result, as described 3102   unmatched ".." segments in the result, as described
3103   in <a href="https://www.rfc-editor.org/errata/eid4547" 3103   in <a href="https://www.rfc-editor.org/errata/eid4547"
3104   >Errata 4547</a>. 3104   >Errata 4547</a>.
3105   3105  
3106   @par Example 3106   @par Example
3107   @code 3107   @code
3108   url dest; 3108   url dest;
3109   system::error_code ec; 3109   system::error_code ec;
3110   3110  
3111   resolve("/one/two/three", "four", dest, ec); 3111   resolve("/one/two/three", "four", dest, ec);
3112   assert( dest.str() == "/one/two/four" ); 3112   assert( dest.str() == "/one/two/four" );
3113   3113  
3114   resolve("http://example.com/", "/one", dest, ec); 3114   resolve("http://example.com/", "/one", dest, ec);
3115   assert( dest.str() == "http://example.com/one" ); 3115   assert( dest.str() == "http://example.com/one" );
3116   3116  
3117   resolve("http://example.com/one", "/two", dest, ec); 3117   resolve("http://example.com/one", "/two", dest, ec);
3118   assert( dest.str() == "http://example.com/two" ); 3118   assert( dest.str() == "http://example.com/two" );
3119   3119  
3120   resolve("http://a/b/c/d;p?q", "g#s", dest, ec); 3120   resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
3121   assert( dest.str() == "http://a/b/c/g#s" ); 3121   assert( dest.str() == "http://a/b/c/g#s" );
3122   @endcode 3122   @endcode
3123   3123  
3124   @par BNF 3124   @par BNF
3125   @code 3125   @code
3126   absolute-URI = scheme ":" hier-part [ "?" query ] 3126   absolute-URI = scheme ":" hier-part [ "?" query ]
3127   @endcode 3127   @endcode
3128   3128  
3129   @par Exception Safety 3129   @par Exception Safety
3130   Basic guarantee. 3130   Basic guarantee.
3131   Calls to allocate may throw. 3131   Calls to allocate may throw.
3132   3132  
3133   @return An empty `boost::system::result` upon success, 3133   @return An empty `boost::system::result` upon success,
3134   otherwise an error code if `!base.has_scheme()`. 3134   otherwise an error code if `!base.has_scheme()`.
3135   3135  
3136   @param base The base URL to resolve against. 3136   @param base The base URL to resolve against.
3137   3137  
3138   @param ref The URL reference to resolve. 3138   @param ref The URL reference to resolve.
3139   3139  
3140   @param dest The container where the result 3140   @param dest The container where the result
3141   is written, upon success. 3141   is written, upon success.
3142   3142  
3143   @par Specification 3143   @par Specification
3144   <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5" 3144   <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
3145   >5. Reference Resolution (rfc3986)</a> 3145   >5. Reference Resolution (rfc3986)</a>
3146   3146  
3147   @see 3147   @see
3148   @ref url, 3148   @ref url,
3149   @ref url_view. 3149   @ref url_view.
3150   */ 3150   */
3151   inline 3151   inline
3152   system::result<void> 3152   system::result<void>
HITCBC 3153   457 resolve( 3153   457 resolve(
3154   url_view_base const& base, 3154   url_view_base const& base,
3155   url_view_base const& ref, 3155   url_view_base const& ref,
3156   url_base& dest) 3156   url_base& dest)
3157   { 3157   {
HITCBC 3158   457 if (&dest != &base) 3158   457 if (&dest != &base)
HITCBC 3159   456 dest.copy(base); 3159   456 dest.copy(base);
HITCBC 3160   457 return dest.resolve(ref); 3160   457 return dest.resolve(ref);
3161   } 3161   }
3162   3162  
3163   } // urls 3163   } // urls
3164   } // boost 3164   } // boost
3165   3165  
3166   // These are here because of circular references 3166   // These are here because of circular references
3167   #include <boost/url/impl/url_base.hpp> 3167   #include <boost/url/impl/url_base.hpp>
3168   #include <boost/url/impl/params_ref.hpp> 3168   #include <boost/url/impl/params_ref.hpp>
3169   #include <boost/url/impl/params_encoded_ref.hpp> 3169   #include <boost/url/impl/params_encoded_ref.hpp>
3170   #include <boost/url/impl/segments_ref.hpp> 3170   #include <boost/url/impl/segments_ref.hpp>
3171   #include <boost/url/impl/segments_encoded_ref.hpp> 3171   #include <boost/url/impl/segments_encoded_ref.hpp>
3172   3172  
3173   #endif 3173   #endif