GCC Code Coverage Report


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