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