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