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