GCC Code Coverage Report


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