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