GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/url_base.hpp
Date: 2025-04-22 15:26:26
Exec Total Coverage
Lines: 24 24 100.0%
Functions: 11 11 100.0%
Branches: 2 2 100.0%

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