GCC Code Coverage Report


Directory: libs/url/
File: boost/url/url_base.hpp
Date: 2024-07-11 04:01:35
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
2257 @par BNF
2258 @code
2259 query = *( pchar / "/" / "?" )
2260
2261 query-param = key [ "=" value ]
2262 query-params = [ query-param ] *( "&" query-param )
2263 @endcode
2264
2265 @par Specification
2266 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
2267 >3.4. Query (rfc3986)</a>
2268 @li <a href="https://en.wikipedia.org/wiki/Query_string"
2269 >Query string (Wikipedia)</a>
2270
2271 @see
2272 @ref encoded_params,
2273 @ref remove_query,
2274 @ref set_encoded_query,
2275 @ref set_query.
2276 */
2277 url_base&
2278 set_params( std::initializer_list<param_view> ps ) noexcept;
2279
2280 /** Set the query params
2281
2282 This sets the query params to the elements
2283 in the list, which may contain
2284 percent-escapes and can be empty.
2285
2286 An empty list of params is distinct from
2287 having no query.
2288
2289 Escapes in the string are preserved,
2290 and reserved characters in the string
2291 are percent-escaped in the result.
2292
2293 @par Example
2294 @code
2295 assert( url( "http://example.com" ).set_encoded_params( {"id", "42"} ).encoded_query() == "id=42" );
2296 @endcode
2297
2298 @par Postconditions
2299 @code
2300 this->has_query() == true
2301 @endcode
2302
2303 @par Complexity
2304 Linear.
2305
2306 @par Exception Safety
2307 Strong guarantee.
2308 Calls to allocate may throw.
2309 Exceptions thrown on invalid input.
2310
2311 @param ps The params to set.
2312
2313 @throws system_error
2314 some element in `ps` contains an invalid percent-encoding.
2315
2316 @par BNF
2317 @code
2318 query = *( pchar / "/" / "?" )
2319
2320 query-param = key [ "=" value ]
2321 query-params = [ query-param ] *( "&" query-param )
2322 @endcode
2323
2324 @par Specification
2325 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2326 >3.4. Query (rfc3986)</a>
2327 @li <a href="https://en.wikipedia.org/wiki/Query_string"
2328 >Query string (Wikipedia)</a>
2329
2330 @see
2331 @ref set_params,
2332 @ref params,
2333 @ref remove_query,
2334 @ref set_encoded_query,
2335 @ref set_query.
2336 */
2337 url_base&
2338 set_encoded_params( std::initializer_list< param_pct_view > ps ) noexcept;
2339
2340 /** Remove the query
2341
2342 If a query is present, it is removed.
2343 An empty query is distinct from having
2344 no query.
2345
2346 @par Example
2347 @code
2348 assert( url( "http://www.example.com?id=42" ).remove_query().buffer() == "http://www.example.com" );
2349 @endcode
2350
2351 @par Postconditions
2352 @code
2353 this->has_query() == false && this->params().empty()
2354 @endcode
2355
2356 @par Exception Safety
2357 Throws nothing.
2358
2359 @par BNF
2360 @code
2361 query = *( pchar / "/" / "?" )
2362
2363 query-param = key [ "=" value ]
2364 query-params = [ query-param ] *( "&" query-param )
2365 @endcode
2366
2367 @par Specification
2368 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
2369 >3.4. Query (rfc3986)</a>
2370 @li <a href="https://en.wikipedia.org/wiki/Query_string"
2371 >Query string (Wikipedia)</a>
2372
2373 @see
2374 @ref encoded_params,
2375 @ref params,
2376 @ref set_encoded_query,
2377 @ref set_query.
2378 */
2379 url_base&
2380 remove_query() noexcept;
2381
2382 //--------------------------------------------
2383 //
2384 // Fragment
2385 //
2386 //--------------------------------------------
2387
2388 /** Remove the fragment
2389
2390 This function removes the fragment.
2391 An empty fragment is distinct from
2392 having no fragment.
2393
2394 @par Example
2395 @code
2396 assert( url( "?first=john&last=doe#anchor" ).remove_fragment().buffer() == "?first=john&last=doe" );
2397 @endcode
2398
2399 @par Postconditions
2400 @code
2401 this->has_fragment() == false && this->encoded_fragment() == ""
2402 @endcode
2403
2404 @par Complexity
2405 Constant.
2406
2407 @par Exception Safety
2408 Throws nothing.
2409
2410 @par BNF
2411 @code
2412 fragment = *( pchar / "/" / "?" )
2413 @endcode
2414
2415 @par Specification
2416 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2417 >3.5. Fragment</a>
2418
2419 @see
2420 @ref remove_fragment,
2421 @ref set_encoded_fragment,
2422 @ref set_fragment.
2423 */
2424 url_base&
2425 remove_fragment() noexcept;
2426
2427 /** Set the fragment.
2428
2429 This function sets the fragment to the
2430 specified string, which may be empty.
2431 An empty fragment is distinct from
2432 having no fragment.
2433 Reserved characters in the string are
2434 percent-escaped in the result.
2435
2436 @par Example
2437 @code
2438 assert( url("?first=john&last=doe" ).set_encoded_fragment( "john doe" ).encoded_fragment() == "john%20doe" );
2439 @endcode
2440
2441 @par Postconditions
2442 @code
2443 this->has_fragment() == true && this->fragment() == s
2444 @endcode
2445
2446 @par Complexity
2447 Linear in `this->size() + s.size()`.
2448
2449 @par Exception Safety
2450 Strong guarantee.
2451 Calls to allocate may throw.
2452
2453 @param s The string to set.
2454
2455 @par BNF
2456 @code
2457 fragment = *( pchar / "/" / "?" )
2458 @endcode
2459
2460 @par Specification
2461 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2462 >3.5. Fragment</a>
2463
2464 @see
2465 @ref remove_fragment,
2466 @ref set_encoded_fragment.
2467 */
2468 url_base&
2469 set_fragment(
2470 core::string_view s);
2471
2472 /** Set the fragment.
2473
2474 This function sets the fragment to the
2475 specified string, which may contain
2476 percent-escapes and which may be empty.
2477 An empty fragment is distinct from
2478 having no fragment.
2479 Escapes in the string are preserved,
2480 and reserved characters in the string
2481 are percent-escaped in the result.
2482
2483 @par Example
2484 @code
2485 assert( url("?first=john&last=doe" ).set_encoded_fragment( "john%2Ddoe" ).fragment() == "john-doe" );
2486 @endcode
2487
2488 @par Postconditions
2489 @code
2490 this->has_fragment() == true && this->fragment() == decode_view( s )
2491 @endcode
2492
2493 @par Complexity
2494 Linear in `this->size() + s.size()`.
2495
2496 @par Exception Safety
2497 Strong guarantee.
2498 Calls to allocate may throw.
2499 Exceptions thrown on invalid input.
2500
2501 @throw system_error
2502 `s` contains an invalid percent-encoding.
2503
2504 @param s The string to set.
2505
2506 @par BNF
2507 @code
2508 fragment = *( pchar / "/" / "?" )
2509 @endcode
2510
2511 @par Specification
2512 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5"
2513 >3.5. Fragment</a>
2514
2515 @see
2516 @ref remove_fragment,
2517 @ref set_fragment.
2518 */
2519 url_base&
2520 set_encoded_fragment(
2521 pct_string_view s);
2522
2523 //--------------------------------------------
2524 //
2525 // Compound Fields
2526 //
2527 //--------------------------------------------
2528
2529 /** Remove the origin component
2530
2531 This function removes the origin, which
2532 consists of the scheme and authority.
2533
2534 @par Example
2535 @code
2536 assert( url( "http://www.example.com/index.htm" ).remove_origin().buffer() == "/index.htm" );
2537 @endcode
2538
2539 @par Postconditions
2540 @code
2541 this->scheme_id() == scheme::none && this->has_authority() == false
2542 @endcode
2543
2544 @par Complexity
2545 Linear in `this->size()`.
2546
2547 @par Exception Safety
2548 Throws nothing.
2549 */
2550 url_base&
2551 remove_origin();
2552
2553 //--------------------------------------------
2554 //
2555 // Normalization
2556 //
2557 //--------------------------------------------
2558
2559 /** Normalize the URL components
2560
2561 Applies Syntax-based normalization to
2562 all components of the URL.
2563
2564 @par Exception Safety
2565 Strong guarantee.
2566 Calls to allocate may throw.
2567
2568 @par Specification
2569 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2570 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2571
2572 */
2573 url_base&
2574 normalize();
2575
2576 /** Normalize the URL scheme
2577
2578 Applies Syntax-based normalization to the
2579 URL scheme.
2580
2581 The scheme is normalized to lowercase.
2582
2583 @par Exception Safety
2584 Strong guarantee.
2585 Calls to allocate may throw.
2586
2587 @par Specification
2588 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2589 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2590
2591 */
2592 url_base&
2593 normalize_scheme();
2594
2595 /** Normalize the URL authority
2596
2597 Applies Syntax-based normalization to the
2598 URL authority.
2599
2600 Percent-encoding triplets are normalized
2601 to uppercase letters. Percent-encoded
2602 octets that correspond to unreserved
2603 characters are decoded.
2604
2605 @par Exception Safety
2606 Strong guarantee.
2607 Calls to allocate may throw.
2608
2609 @par Specification
2610 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2611 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2612
2613 */
2614 url_base&
2615 normalize_authority();
2616
2617 /** Normalize the URL path
2618
2619 Applies Syntax-based normalization to the
2620 URL path.
2621
2622 Percent-encoding triplets are normalized
2623 to uppercase letters. Percent-encoded
2624 octets that correspond to unreserved
2625 characters are decoded. Redundant
2626 path-segments are removed.
2627
2628 @par Exception Safety
2629 Strong guarantee.
2630 Calls to allocate may throw.
2631
2632 @par Specification
2633 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2634 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2635
2636 */
2637 url_base&
2638 normalize_path();
2639
2640 /** Normalize the URL query
2641
2642 Applies Syntax-based normalization to the
2643 URL query.
2644
2645 Percent-encoding triplets are normalized
2646 to uppercase letters. Percent-encoded
2647 octets that correspond to unreserved
2648 characters are decoded.
2649
2650 @par Exception Safety
2651 Strong guarantee.
2652 Calls to allocate may throw.
2653
2654 @par Specification
2655 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2656 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2657
2658 */
2659 url_base&
2660 normalize_query();
2661
2662 /** Normalize the URL fragment
2663
2664 Applies Syntax-based normalization to the
2665 URL fragment.
2666
2667 Percent-encoding triplets are normalized
2668 to uppercase letters. Percent-encoded
2669 octets that correspond to unreserved
2670 characters are decoded.
2671
2672 @par Exception Safety
2673 Strong guarantee.
2674 Calls to allocate may throw.
2675
2676 @par Specification
2677 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
2678 >6.2.2 Syntax-Based Normalization (rfc3986)</a>
2679
2680 */
2681 url_base&
2682 normalize_fragment();
2683
2684 //
2685 // (end of fluent API)
2686 //
2687 //--------------------------------------------
2688
2689 //--------------------------------------------
2690 //
2691 // Resolution
2692 //
2693 //--------------------------------------------
2694
2695 /** Resolve a URL reference against this base URL
2696
2697 This function attempts to resolve a URL
2698 reference `ref` against this base URL
2699 in a manner similar to that of a web browser
2700 resolving an anchor tag.
2701
2702 This URL must satisfy the <em>URI</em>
2703 grammar. In other words, it must contain
2704 a scheme.
2705
2706 Relative references are only usable when
2707 in the context of a base absolute URI.
2708 This process of resolving a relative
2709 <em>reference</em> within the context of
2710 a <em>base</em> URI is defined in detail
2711 in rfc3986 (see below).
2712
2713 The resolution process works as if the
2714 relative reference is appended to the base
2715 URI and the result is normalized.
2716
2717 Given the input base URL, this function
2718 resolves the relative reference
2719 as if performing the following steps:
2720
2721 @li Ensure the base URI has at least a scheme
2722 @li Normalizing the reference path
2723 @li Merge base and reference paths
2724 @li Normalize the merged path
2725
2726 This function places the result of the
2727 resolution into this URL in place.
2728
2729 If an error occurs, the contents of
2730 this URL are unspecified and a @ref result
2731 with an `system::error_code` is returned.
2732
2733 @note Abnormal hrefs where the number of ".."
2734 segments exceeds the number of segments in
2735 the base path are handled by including the
2736 unmatched ".." segments in the result, as described
2737 in <a href="https://www.rfc-editor.org/errata/eid4547"
2738 >Errata 4547</a>.
2739
2740 @par Example
2741 @code
2742 url base1( "/one/two/three" );
2743 base1.resolve("four");
2744 assert( base1.buffer() == "/one/two/four" );
2745
2746 url base2( "http://example.com/" )
2747 base2.resolve("/one");
2748 assert( base2.buffer() == "http://example.com/one" );
2749
2750 url base3( "http://example.com/one" );
2751 base3.resolve("/two");
2752 assert( base3.buffer() == "http://example.com/two" );
2753
2754 url base4( "http://a/b/c/d;p?q" );
2755 base4.resolve("g#s");
2756 assert( base4.buffer() == "http://a/b/c/g#s" );
2757 @endcode
2758
2759 @par BNF
2760 @code
2761 absolute-URI = scheme ":" hier-part [ "?" query ]
2762 @endcode
2763
2764 @par Exception Safety
2765 Basic guarantee.
2766 Calls to allocate may throw.
2767
2768 @return An empty @ref result upon success,
2769 otherwise an error code if `!base.has_scheme()`.
2770
2771 @param ref The URL reference to resolve.
2772
2773 @par Specification
2774 <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
2775 >5. Reference Resolution (rfc3986)</a>
2776
2777 @see
2778 @ref url,
2779 @ref url_view.
2780 */
2781 system::result<void>
2782 resolve(
2783 url_view_base const& ref);
2784
2785 /** Resolve a URL reference against a base URL
2786
2787 This function attempts to resolve a URL
2788 reference `ref` against the base URL `base`
2789 in a manner similar to that of a web browser
2790 resolving an anchor tag.
2791
2792 The base URL must satisfy the <em>URI</em>
2793 grammar. In other words, it must contain
2794 a scheme.
2795
2796 Relative references are only usable when
2797 in the context of a base absolute URI.
2798 This process of resolving a relative
2799 <em>reference</em> within the context of
2800 a <em>base</em> URI is defined in detail
2801 in rfc3986 (see below).
2802
2803 The resolution process works as if the
2804 relative reference is appended to the base
2805 URI and the result is normalized.
2806
2807 Given the input base URL, this function
2808 resolves the relative reference
2809 as if performing the following steps:
2810
2811 @li Ensure the base URI has at least a scheme
2812 @li Normalizing the reference path
2813 @li Merge base and reference paths
2814 @li Normalize the merged path
2815
2816 This function places the result of the
2817 resolution into `dest`, which can be
2818 any of the url containers that inherit
2819 from @ref url_base.
2820
2821 If an error occurs, the contents of
2822 `dest` is unspecified and `ec` is set.
2823
2824 @note Abnormal hrefs where the number of ".."
2825 segments exceeds the number of segments in
2826 the base path are handled by including the
2827 unmatched ".." segments in the result, as described
2828 in <a href="https://www.rfc-editor.org/errata/eid4547"
2829 >Errata 4547</a>.
2830
2831 @par Example
2832 @code
2833 url dest;
2834 system::error_code ec;
2835
2836 resolve("/one/two/three", "four", dest, ec);
2837 assert( dest.str() == "/one/two/four" );
2838
2839 resolve("http://example.com/", "/one", dest, ec);
2840 assert( dest.str() == "http://example.com/one" );
2841
2842 resolve("http://example.com/one", "/two", dest, ec);
2843 assert( dest.str() == "http://example.com/two" );
2844
2845 resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
2846 assert( dest.str() == "http://a/b/c/g#s" );
2847 @endcode
2848
2849 @par BNF
2850 @code
2851 absolute-URI = scheme ":" hier-part [ "?" query ]
2852 @endcode
2853
2854 @par Exception Safety
2855 Basic guarantee.
2856 Calls to allocate may throw.
2857
2858 @return An empty @ref result upon success,
2859 otherwise an error code if `!base.has_scheme()`.
2860
2861 @param base The base URL to resolve against.
2862
2863 @param ref The URL reference to resolve.
2864
2865 @param dest The container where the result
2866 is written, upon success.
2867
2868 @par Specification
2869 <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
2870 >5. Reference Resolution (rfc3986)</a>
2871
2872 @see
2873 @ref url,
2874 @ref url_view.
2875 */
2876 friend
2877 system::result<void>
2878 resolve(
2879 url_view_base const& base,
2880 url_view_base const& ref,
2881 url_base& dest);
2882
2883 private:
2884 //--------------------------------------------
2885 //
2886 // implementation
2887 //
2888 //--------------------------------------------
2889
2890 void check_invariants() const noexcept;
2891
2892 char* resize_impl(int, std::size_t, op_t&);
2893 char* resize_impl(int, int, std::size_t, op_t&);
2894 char* shrink_impl(int, std::size_t, op_t&);
2895 char* shrink_impl(int, int, std::size_t, op_t&);
2896
2897 void set_scheme_impl(core::string_view, urls::scheme);
2898 char* set_user_impl(std::size_t n, op_t& op);
2899 char* set_password_impl(std::size_t n, op_t& op);
2900 char* set_userinfo_impl(std::size_t n, op_t& op);
2901 char* set_host_impl(std::size_t n, op_t& op);
2902 char* set_port_impl(std::size_t n, op_t& op);
2903 char* set_path_impl(std::size_t n, op_t& op);
2904
2905 core::string_view
2906 first_segment() const noexcept;
2907
2908 detail::segments_iter_impl
2909 edit_segments(
2910 detail::segments_iter_impl const&,
2911 detail::segments_iter_impl const&,
2912 detail::any_segments_iter&& it0,
2913 int absolute = -1);
2914
2915 auto
2916 edit_params(
2917 detail::params_iter_impl const&,
2918 detail::params_iter_impl const&,
2919 detail::any_params_iter&&) ->
2920 detail::params_iter_impl;
2921
2922 system::result<void>
2923 resolve_impl(
2924 url_view_base const& base,
2925 url_view_base const& ref);
2926
2927 template<class CharSet>
2928 void normalize_octets_impl(int,
2929 CharSet const& allowed, op_t&) noexcept;
2930 void decoded_to_lower_impl(int id) noexcept;
2931 void to_lower_impl(int id) noexcept;
2932 };
2933
2934 //------------------------------------------------
2935
2936 /** Resolve a URL reference against a base URL
2937
2938 This function attempts to resolve a URL
2939 reference `ref` against the base URL `base`
2940 in a manner similar to that of a web browser
2941 resolving an anchor tag.
2942
2943 The base URL must satisfy the <em>URI</em>
2944 grammar. In other words, it must contain
2945 a scheme.
2946
2947 Relative references are only usable when
2948 in the context of a base absolute URI.
2949 This process of resolving a relative
2950 <em>reference</em> within the context of
2951 a <em>base</em> URI is defined in detail
2952 in rfc3986 (see below).
2953
2954 The resolution process works as if the
2955 relative reference is appended to the base
2956 URI and the result is normalized.
2957
2958 Given the input base URL, this function
2959 resolves the relative reference
2960 as if performing the following steps:
2961
2962 @li Ensure the base URI has at least a scheme
2963 @li Normalizing the reference path
2964 @li Merge base and reference paths
2965 @li Normalize the merged path
2966
2967 This function places the result of the
2968 resolution into `dest`, which can be
2969 any of the url containers that inherit
2970 from @ref url_base.
2971
2972 If an error occurs, the contents of
2973 `dest` is unspecified and `ec` is set.
2974
2975 @note Abnormal hrefs where the number of ".."
2976 segments exceeds the number of segments in
2977 the base path are handled by including the
2978 unmatched ".." segments in the result, as described
2979 in <a href="https://www.rfc-editor.org/errata/eid4547"
2980 >Errata 4547</a>.
2981
2982 @par Example
2983 @code
2984 url dest;
2985 system::error_code ec;
2986
2987 resolve("/one/two/three", "four", dest, ec);
2988 assert( dest.str() == "/one/two/four" );
2989
2990 resolve("http://example.com/", "/one", dest, ec);
2991 assert( dest.str() == "http://example.com/one" );
2992
2993 resolve("http://example.com/one", "/two", dest, ec);
2994 assert( dest.str() == "http://example.com/two" );
2995
2996 resolve("http://a/b/c/d;p?q", "g#s", dest, ec);
2997 assert( dest.str() == "http://a/b/c/g#s" );
2998 @endcode
2999
3000 @par BNF
3001 @code
3002 absolute-URI = scheme ":" hier-part [ "?" query ]
3003 @endcode
3004
3005 @par Exception Safety
3006 Basic guarantee.
3007 Calls to allocate may throw.
3008
3009 @return An empty @ref result upon success,
3010 otherwise an error code if `!base.has_scheme()`.
3011
3012 @param base The base URL to resolve against.
3013
3014 @param ref The URL reference to resolve.
3015
3016 @param dest The container where the result
3017 is written, upon success.
3018
3019 @par Specification
3020 <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-5"
3021 >5. Reference Resolution (rfc3986)</a>
3022
3023 @see
3024 @ref url,
3025 @ref url_view.
3026 */
3027 inline
3028 system::result<void>
3029 404 resolve(
3030 url_view_base const& base,
3031 url_view_base const& ref,
3032 url_base& dest)
3033 {
3034
2/2
✓ Branch 0 taken 403 times.
✓ Branch 1 taken 1 times.
404 if (&dest != &base)
3035 403 dest.copy(base);
3036 404 return dest.resolve(ref);
3037 }
3038
3039 } // urls
3040 } // boost
3041
3042 // These are here because of circular references
3043 #include <boost/url/impl/params_ref.hpp>
3044 #include <boost/url/impl/params_encoded_ref.hpp>
3045 #include <boost/url/impl/segments_ref.hpp>
3046 #include <boost/url/impl/segments_encoded_ref.hpp>
3047
3048 #endif
3049