GCC Code Coverage Report


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