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