GCC Code Coverage Report


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