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