Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 : #ifndef BOOST_URL_AUTHORITY_VIEW_HPP
11 : #define BOOST_URL_AUTHORITY_VIEW_HPP
12 :
13 : #include <boost/url/detail/config.hpp>
14 : #include <boost/url/host_type.hpp>
15 : #include <boost/url/ipv4_address.hpp>
16 : #include <boost/url/ipv6_address.hpp>
17 : #include <boost/url/pct_string_view.hpp>
18 : #include <boost/url/detail/except.hpp>
19 : #include <boost/url/detail/url_impl.hpp>
20 : #include <boost/assert.hpp>
21 : #include <cstddef>
22 : #include <iosfwd>
23 : #include <utility>
24 :
25 : namespace boost {
26 : namespace urls {
27 :
28 : /** A non-owning reference to a valid authority
29 :
30 : Objects of this type represent valid authority
31 : strings constructed from a parsed, external
32 : character buffer whose storage is managed
33 : by the caller. That is, it acts like a
34 : `core::string_view` in terms of ownership.
35 : The caller is responsible for ensuring
36 : that the lifetime of the underlying
37 : character buffer extends until it is no
38 : longer referenced.
39 :
40 : @par Example 1
41 : Construction from a string parses the input
42 : as an <em>authority</em> and throws an
43 : exception on error. Upon success, the
44 : constructed object points to the passed
45 : character buffer; ownership is not
46 : transferred.
47 : @code
48 : authority_view a( "user:pass@www.example.com:8080" );
49 : @endcode
50 :
51 : @par Example 2
52 : The parsing function @ref parse_authority returns
53 : a `boost::system::result` containing either a valid
54 : @ref authority_view upon succcess, otherwise it
55 : contain an error. The error can be converted to
56 : an exception by the caller if desired:
57 : @code
58 : system::result< authority_view > rv = parse_authority( "user:pass@www.example.com:8080" );
59 : @endcode
60 :
61 : @par BNF
62 : @code
63 : authority = [ userinfo "@" ] host [ ":" port ]
64 :
65 : userinfo = user [ ":" [ password ] ]
66 :
67 : user = *( unreserved / pct-encoded / sub-delims )
68 : password = *( unreserved / pct-encoded / sub-delims / ":" )
69 :
70 : host = IP-literal / IPv4address / reg-name
71 :
72 : port = *DIGIT
73 : @endcode
74 :
75 : @par Specification
76 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
77 : >3.2. Authority (rfc3986)</a>
78 :
79 : @see
80 : @ref parse_authority.
81 : */
82 : class BOOST_URL_DECL
83 : authority_view
84 : : private detail::parts_base
85 : {
86 : detail::url_impl u_;
87 :
88 : #ifndef BOOST_URL_DOCS
89 : // VFALCO docca emits this erroneously
90 : friend struct detail::url_impl;
91 : #endif
92 :
93 : explicit
94 : authority_view(
95 : detail::url_impl const& u) noexcept;
96 :
97 : public:
98 : //--------------------------------------------
99 : //
100 : // Special Members
101 : //
102 : //--------------------------------------------
103 :
104 : /** Destructor
105 : */
106 : virtual
107 : ~authority_view();
108 :
109 : /** Constructor
110 :
111 : Default constructed authorities
112 : refer to a string with zero length,
113 : which is always valid. This matches
114 : the grammar for a zero-length host.
115 :
116 : @par Exception Safety
117 : Throws nothing.
118 :
119 : @par Specification
120 : */
121 : authority_view() noexcept;
122 :
123 : /** Construct from a string.
124 :
125 : This function attempts to construct
126 : an authority from the string `s`,
127 : which must be a valid ['authority] or
128 : else an exception is thrown. Upon
129 : successful construction, the view
130 : refers to the characters in the
131 : buffer pointed to by `s`.
132 : Ownership is not transferred; The
133 : caller is responsible for ensuring
134 : that the lifetime of the buffer
135 : extends until the view is destroyed.
136 :
137 : @param s The string to parse
138 :
139 : @par BNF
140 : @code
141 : authority = [ userinfo "@" ] host [ ":" port ]
142 :
143 : userinfo = user [ ":" [ password ] ]
144 :
145 : user = *( unreserved / pct-encoded / sub-delims )
146 : password = *( unreserved / pct-encoded / sub-delims / ":" )
147 :
148 : host = IP-literal / IPv4address / reg-name
149 :
150 : port = *DIGIT
151 : @endcode
152 :
153 : @par Specification
154 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
155 : >3.2. Authority (rfc3986)</a>
156 :
157 : @see
158 : @ref parse_authority.
159 : */
160 : explicit
161 : authority_view(core::string_view s);
162 :
163 : /** Constructor
164 : */
165 : authority_view(
166 : authority_view const&) noexcept;
167 :
168 : /** Assignment
169 :
170 : This function assigns the contents of
171 : `other` to this object.
172 :
173 : @param other The object to assign
174 : @return A reference to this object
175 :
176 : @par Exception Safety
177 : Throws nothing.
178 : */
179 : authority_view&
180 : operator=(
181 : authority_view const& other) noexcept;
182 :
183 : //--------------------------------------------
184 : //
185 : // Observers
186 : //
187 : //--------------------------------------------
188 :
189 : /** Return the number of characters in the authority
190 :
191 : This function returns the number of
192 : characters in the authority.
193 :
194 : @return The number of characters in the authority
195 :
196 : @par Example
197 : @code
198 : assert( authority_view( "user:pass@www.example.com:8080" ).size() == 30 );
199 : @endcode
200 :
201 : @par Exception Safety
202 : Throws nothing.
203 : */
204 : std::size_t
205 24 : size() const noexcept
206 : {
207 24 : return u_.offset(id_end);
208 : }
209 :
210 : /** Return true if the authority is empty
211 :
212 : An empty authority has an empty host,
213 : no userinfo, and no port.
214 :
215 : @return `true` if the authority is empty
216 :
217 : @par Example
218 : @code
219 : assert( authority_view( "" ).empty() );
220 : @endcode
221 :
222 : @par Exception Safety
223 : Throws nothing.
224 : */
225 : bool
226 3 : empty() const noexcept
227 : {
228 3 : return size() == 0;
229 : }
230 :
231 : /** Return a pointer to the first character
232 :
233 : This function returns a pointer to the
234 : beginning of the view, which is not
235 : guaranteed to be null-terminated.
236 :
237 : @return A pointer to the first character
238 :
239 : @par Exception Safety
240 : Throws nothing.
241 : */
242 : char const*
243 20 : data() const noexcept
244 : {
245 20 : return u_.cs_;
246 : }
247 :
248 : /** Return the complete authority
249 :
250 : This function returns the authority
251 : as a percent-encoded string.
252 :
253 : @return The complete authority
254 :
255 : @par Example
256 : @code
257 : assert( parse_authority( "www.example.com" ).value().buffer() == "www.example.com" );
258 : @endcode
259 :
260 : @par BNF
261 : @code
262 : authority = [ userinfo "@" ] host [ ":" port ]
263 : @endcode
264 :
265 : @par Exception Safety
266 : Throws nothing.
267 :
268 : @par Specification
269 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
270 : >3.2. Authority (rfc3986)</a>
271 : */
272 : core::string_view
273 18 : buffer() const noexcept
274 : {
275 18 : return core::string_view(data(), size());
276 : }
277 :
278 : //--------------------------------------------
279 : //
280 : // Userinfo
281 : //
282 : //--------------------------------------------
283 :
284 : /** Return true if a userinfo is present
285 :
286 : This function returns true if this
287 : contains a userinfo.
288 :
289 : @return `true` if a userinfo is present
290 :
291 : @par Example
292 : @code
293 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() );
294 : @endcode
295 :
296 : @par Complexity
297 : Constant.
298 :
299 : @par Exception Safety
300 : Throws nothing.
301 :
302 : @par BNF
303 : @code
304 : userinfo = user [ ":" [ password ] ]
305 :
306 : authority = [ userinfo "@" ] host [ ":" port ]
307 : @endcode
308 :
309 : @par Specification
310 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
311 : >3.2.1. User Information (rfc3986)</a>
312 :
313 : @see
314 : @ref has_password,
315 : @ref encoded_password,
316 : @ref encoded_user,
317 : @ref encoded_userinfo,
318 : @ref password,
319 : @ref user,
320 : @ref userinfo.
321 :
322 : */
323 : bool
324 : has_userinfo() const noexcept;
325 :
326 : /** Return the userinfo
327 :
328 : If present, this function returns a
329 : string representing the userinfo (which
330 : may be empty).
331 : Otherwise it returns an empty string.
332 : Any percent-escapes in the string are
333 : decoded first.
334 :
335 : @param token A string token to receive the result.
336 : @return The userinfo
337 :
338 : @par Example
339 : @code
340 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" );
341 : @endcode
342 :
343 : @par Complexity
344 : Linear in `this->userinfo().size()`.
345 :
346 : @par Exception Safety
347 : Calls to allocate may throw.
348 :
349 : @par BNF
350 : @code
351 : userinfo = user [ ":" [ password ] ]
352 :
353 : authority = [ userinfo "@" ] host [ ":" port ]
354 : @endcode
355 :
356 : @par Specification
357 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
358 : >3.2.1. User Information (rfc3986)</a>
359 :
360 : @see
361 : @ref has_password,
362 : @ref has_userinfo,
363 : @ref encoded_password,
364 : @ref encoded_user,
365 : @ref encoded_userinfo,
366 : @ref password,
367 : @ref user.
368 : */
369 : template<BOOST_URL_STRTOK_TPARAM>
370 : BOOST_URL_STRTOK_RETURN
371 23 : userinfo(
372 : BOOST_URL_STRTOK_ARG(token)) const
373 : {
374 23 : encoding_opts opt;
375 23 : opt.space_as_plus = false;
376 46 : return encoded_userinfo().decode(
377 46 : opt, std::move(token));
378 : }
379 :
380 : /** Return the userinfo
381 :
382 : If present, this function returns a
383 : string representing the userinfo (which
384 : may be empty).
385 : Otherwise it returns an empty string.
386 : The returned string may contain
387 : percent escapes.
388 :
389 : @return The userinfo
390 :
391 : @par Example
392 : @code
393 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" );
394 : @endcode
395 :
396 : @par Complexity
397 : Constant.
398 :
399 : @par Exception Safety
400 : Throws nothing
401 :
402 : @par BNF
403 : @code
404 : userinfo = user [ ":" [ password ] ]
405 :
406 : authority = [ userinfo "@" ] host [ ":" port ]
407 : @endcode
408 :
409 : @par Specification
410 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
411 : >3.2.1. User Information (rfc3986)</a>
412 :
413 : @see
414 : @ref has_password,
415 : @ref has_userinfo,
416 : @ref encoded_password,
417 : @ref encoded_user,
418 : @ref password,
419 : @ref user,
420 : @ref userinfo.
421 : */
422 : pct_string_view
423 : encoded_userinfo() const noexcept;
424 :
425 : //--------------------------------------------
426 :
427 : /** Return the user
428 :
429 : If present, this function returns a
430 : string representing the user (which
431 : may be empty).
432 : Otherwise it returns an empty string.
433 : Any percent-escapes in the string are
434 : decoded first.
435 :
436 : @param token A string token to receive the result.
437 : @return The user
438 :
439 : @par Example
440 : @code
441 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" );
442 : @endcode
443 :
444 : @par Complexity
445 : Linear in `this->user().size()`.
446 :
447 : @par Exception Safety
448 : Calls to allocate may throw.
449 :
450 : @par BNF
451 : @code
452 : userinfo = user [ ":" [ password ] ]
453 :
454 : user = *( unreserved / pct-encoded / sub-delims )
455 : password = *( unreserved / pct-encoded / sub-delims / ":" )
456 : @endcode
457 :
458 : @par Specification
459 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
460 : >3.2.1. User Information (rfc3986)</a>
461 :
462 : @see
463 : @ref has_password,
464 : @ref has_userinfo,
465 : @ref encoded_password,
466 : @ref encoded_user,
467 : @ref encoded_userinfo,
468 : @ref password,
469 : @ref userinfo.
470 : */
471 : template<BOOST_URL_STRTOK_TPARAM>
472 : BOOST_URL_STRTOK_RETURN
473 12 : user(
474 : BOOST_URL_STRTOK_ARG(token)) const
475 : {
476 12 : encoding_opts opt;
477 12 : opt.space_as_plus = false;
478 24 : return encoded_user().decode(
479 24 : opt, std::move(token));
480 : }
481 :
482 : /** Return the user
483 :
484 : If present, this function returns a
485 : string representing the user (which
486 : may be empty).
487 : Otherwise it returns an empty string.
488 : The returned string may contain
489 : percent escapes.
490 :
491 : @return The user
492 :
493 : @par Example
494 : @code
495 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" );
496 : @endcode
497 :
498 : @par Complexity
499 : Constant.
500 :
501 : @par Exception Safety
502 : Throws nothing.
503 :
504 : @par BNF
505 : @code
506 : userinfo = user [ ":" [ password ] ]
507 :
508 : user = *( unreserved / pct-encoded / sub-delims )
509 : password = *( unreserved / pct-encoded / sub-delims / ":" )
510 : @endcode
511 :
512 : @par Specification
513 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
514 : >3.2.1. User Information (rfc3986)</a>
515 :
516 : @see
517 : @ref has_password,
518 : @ref has_userinfo,
519 : @ref encoded_password,
520 : @ref encoded_userinfo,
521 : @ref password,
522 : @ref user,
523 : @ref userinfo.
524 : */
525 : pct_string_view
526 : encoded_user() const noexcept;
527 :
528 : /** Return true if a password is present
529 :
530 : This function returns true if the
531 : userinfo is present and contains
532 : a password.
533 :
534 : @return `true` if a password is present
535 :
536 : @par Example
537 : @code
538 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() );
539 : @endcode
540 :
541 : @par Complexity
542 : Constant.
543 :
544 : @par Exception Safety
545 : Throws nothing.
546 :
547 : @par BNF
548 : @code
549 : userinfo = user [ ":" [ password ] ]
550 :
551 : user = *( unreserved / pct-encoded / sub-delims )
552 : password = *( unreserved / pct-encoded / sub-delims / ":" )
553 : @endcode
554 :
555 : @par Specification
556 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
557 : >3.2.1. User Information (rfc3986)</a>
558 :
559 : @see
560 : @ref has_userinfo,
561 : @ref encoded_password,
562 : @ref encoded_user,
563 : @ref encoded_userinfo,
564 : @ref password,
565 : @ref user,
566 : @ref userinfo.
567 : */
568 : bool
569 : has_password() const noexcept;
570 :
571 : /** Return the password
572 :
573 : If present, this function returns a
574 : string representing the password (which
575 : may be an empty string).
576 : Otherwise it returns an empty string.
577 : Any percent-escapes in the string are
578 : decoded first.
579 :
580 : @param token A string token to receive the result.
581 : @return The password
582 :
583 : @par Example
584 : @code
585 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" );
586 : @endcode
587 :
588 : @par Complexity
589 : Linear in `this->password().size()`.
590 :
591 : @par Exception Safety
592 : Calls to allocate may throw.
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 has_password,
608 : @ref has_userinfo,
609 : @ref encoded_password,
610 : @ref encoded_user,
611 : @ref encoded_userinfo,
612 : @ref user,
613 : @ref userinfo.
614 : */
615 : template<BOOST_URL_STRTOK_TPARAM>
616 : BOOST_URL_STRTOK_RETURN
617 12 : password(
618 : BOOST_URL_STRTOK_ARG(token)) const
619 : {
620 12 : encoding_opts opt;
621 12 : opt.space_as_plus = false;
622 24 : return encoded_password().decode(
623 24 : opt, std::move(token));
624 : }
625 :
626 : /** Return the password
627 :
628 : This function returns the password portion
629 : of the userinfo as a percent-encoded string.
630 :
631 : @return The password
632 :
633 : @par Example
634 : @code
635 : assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" );
636 : @endcode
637 :
638 : @par Complexity
639 : Constant.
640 :
641 : @par Exception Safety
642 : Throws nothing.
643 :
644 : @par BNF
645 : @code
646 : userinfo = user [ ":" [ password ] ]
647 :
648 : user = *( unreserved / pct-encoded / sub-delims )
649 : password = *( unreserved / pct-encoded / sub-delims / ":" )
650 : @endcode
651 :
652 : @par Specification
653 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1"
654 : >3.2.1. User Information (rfc3986)</a>
655 :
656 : @see
657 : @ref has_password,
658 : @ref has_userinfo,
659 : @ref encoded_user,
660 : @ref encoded_userinfo,
661 : @ref password,
662 : @ref user,
663 : @ref userinfo.
664 : */
665 : pct_string_view
666 : encoded_password() const noexcept;
667 :
668 : //--------------------------------------------
669 : //
670 : // Host
671 : //
672 : //--------------------------------------------
673 :
674 : /** Return the host type
675 :
676 : This function returns one of the
677 : following constants representing the
678 : type of host present.
679 :
680 : @li @ref host_type::ipv4
681 : @li @ref host_type::ipv6
682 : @li @ref host_type::ipvfuture
683 : @li @ref host_type::name
684 :
685 : @return The host type
686 :
687 : @par Example
688 : @code
689 : assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 );
690 : @endcode
691 :
692 : @par Complexity
693 : Constant.
694 :
695 : @par Exception Safety
696 : Throws nothing.
697 :
698 : @par Specification
699 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
700 : >3.2.2. Host (rfc3986)</a>
701 : */
702 : urls::host_type
703 8 : host_type() const noexcept
704 : {
705 8 : return u_.host_type_;
706 : }
707 :
708 : /** Return the host
709 :
710 : This function returns the host portion
711 : of the authority as a string, or the
712 : empty string if there is no authority.
713 : Any percent-escapes in the string are
714 : decoded first.
715 :
716 : @param token A string token to receive the result.
717 : @return The host
718 :
719 : @par Example
720 : @code
721 : assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" );
722 : @endcode
723 :
724 : @par Complexity
725 : Linear in `this->host().size()`.
726 :
727 : @par Exception Safety
728 : Calls to allocate may throw.
729 :
730 : @par BNF
731 : @code
732 : host = IP-literal / IPv4address / reg-name
733 :
734 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
735 :
736 : reg-name = *( unreserved / pct-encoded / "-" / ".")
737 : @endcode
738 :
739 : @par Specification
740 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
741 : >3.2.2. Host (rfc3986)</a>
742 : */
743 : template<BOOST_URL_STRTOK_TPARAM>
744 : BOOST_URL_STRTOK_RETURN
745 4 : host(
746 : BOOST_URL_STRTOK_ARG(token)) const
747 : {
748 4 : encoding_opts opt;
749 4 : opt.space_as_plus = false;
750 8 : return encoded_host().decode(
751 8 : opt, std::move(token));
752 : }
753 :
754 : /** Return the host
755 :
756 : This function returns the host portion
757 : of the authority as a string, or the
758 : empty string if there is no authority.
759 : The returned string may contain
760 : percent escapes.
761 :
762 : @return The host
763 :
764 : @par Example
765 : @code
766 : assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" );
767 : @endcode
768 :
769 : @par Complexity
770 : Constant.
771 :
772 : @par Exception Safety
773 : Throws nothing.
774 :
775 : @par BNF
776 : @code
777 : host = IP-literal / IPv4address / reg-name
778 :
779 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
780 :
781 : reg-name = *( unreserved / pct-encoded / "-" / ".")
782 : @endcode
783 :
784 : @par Specification
785 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
786 : >3.2.2. Host (rfc3986)</a>
787 : */
788 : pct_string_view
789 : encoded_host() const noexcept;
790 :
791 : /** Return the host
792 :
793 : The value returned by this function
794 : depends on the type of host returned
795 : from the function @ref host_type.
796 :
797 : @li If the type is @ref host_type::ipv4,
798 : then the IPv4 address string is returned.
799 :
800 : @li If the type is @ref host_type::ipv6,
801 : then the IPv6 address string is returned,
802 : without any enclosing brackets.
803 :
804 : @li If the type is @ref host_type::ipvfuture,
805 : then the IPvFuture address string is returned,
806 : without any enclosing brackets.
807 :
808 : @li If the type is @ref host_type::name,
809 : then the host name string is returned.
810 : Any percent-escapes in the string are
811 : decoded first.
812 :
813 : @li If the type is @ref host_type::none,
814 : then an empty string is returned.
815 :
816 : @param token A string token to receive the result.
817 : @return The host address
818 :
819 : @par Example
820 : @code
821 : assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" );
822 : @endcode
823 :
824 : @par Complexity
825 : Linear in `this->host_address().size()`.
826 :
827 : @par Exception Safety
828 : Calls to allocate may throw.
829 :
830 : @par BNF
831 : @code
832 : host = IP-literal / IPv4address / reg-name
833 :
834 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
835 :
836 : reg-name = *( unreserved / pct-encoded / "-" / ".")
837 : @endcode
838 :
839 : @par Specification
840 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
841 : >3.2.2. Host (rfc3986)</a>
842 : */
843 : template<BOOST_URL_STRTOK_TPARAM>
844 : BOOST_URL_STRTOK_RETURN
845 : host_address(
846 : BOOST_URL_STRTOK_ARG(token)) const
847 : {
848 : encoding_opts opt;
849 : opt.space_as_plus = false;
850 : return encoded_host_address().decode(
851 : opt, std::move(token));
852 : }
853 :
854 : /** Return the host
855 :
856 : The value returned by this function
857 : depends on the type of host returned
858 : from the function @ref host_type.
859 :
860 : @li If the type is @ref host_type::ipv4,
861 : then the IPv4 address string is returned.
862 :
863 : @li If the type is @ref host_type::ipv6,
864 : then the IPv6 address string is returned,
865 : without any enclosing brackets.
866 :
867 : @li If the type is @ref host_type::ipvfuture,
868 : then the IPvFuture address string is returned,
869 : without any enclosing brackets.
870 :
871 : @li If the type is @ref host_type::name,
872 : then the host name string is returned.
873 : Any percent-escapes in the string are
874 : decoded first.
875 :
876 : @li If the type is @ref host_type::none,
877 : then an empty string is returned.
878 : The returned string may contain
879 : percent escapes.
880 :
881 : @return The host address
882 :
883 : @par Example
884 : @code
885 : assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" );
886 : @endcode
887 :
888 : @par Complexity
889 : Constant.
890 :
891 : @par Exception Safety
892 : Throws nothing.
893 :
894 : @par BNF
895 : @code
896 : host = IP-literal / IPv4address / reg-name
897 :
898 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
899 :
900 : reg-name = *( unreserved / pct-encoded / "-" / ".")
901 : @endcode
902 :
903 : @par Specification
904 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
905 : >3.2.2. Host (rfc3986)</a>
906 : */
907 : pct_string_view
908 : encoded_host_address() const noexcept;
909 :
910 : /** Return the host IPv4 address
911 :
912 : If the host type is @ref host_type::ipv4,
913 : this function returns the address as
914 : a value of type @ref ipv4_address.
915 : Otherwise, if the host type is not an IPv4
916 : address, it returns a default-constructed
917 : value which is equal to the unspecified
918 : address "0.0.0.0".
919 :
920 : @return The host IPv4 address
921 :
922 : @par Example
923 : @code
924 : assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) );
925 : @endcode
926 :
927 : @par Complexity
928 : Constant.
929 :
930 : @par Exception Safety
931 : Throws nothing.
932 :
933 : @par BNF
934 : @code
935 : IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
936 :
937 : dec-octet = DIGIT ; 0-9
938 : / %x31-39 DIGIT ; 10-99
939 : / "1" 2DIGIT ; 100-199
940 : / "2" %x30-34 DIGIT ; 200-249
941 : / "25" %x30-35 ; 250-255
942 : @endcode
943 :
944 : @par Specification
945 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
946 : >3.2.2. Host (rfc3986)</a>
947 : */
948 : ipv4_address
949 : host_ipv4_address() const noexcept;
950 :
951 : /** Return the host IPv6 address
952 :
953 : If the host type is @ref host_type::ipv6,
954 : this function returns the address as
955 : a value of type @ref ipv6_address.
956 : Otherwise, if the host type is not an IPv6
957 : address, it returns a default-constructed
958 : value which is equal to the unspecified
959 : address "0:0:0:0:0:0:0:0".
960 :
961 : @return The host IPv6 address
962 :
963 : @par Example
964 : @code
965 : assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) );
966 : @endcode
967 :
968 : @par Complexity
969 : Constant.
970 :
971 : @par Exception Safety
972 : Throws nothing.
973 :
974 : @par BNF
975 : @code
976 : IPv6address = 6( h16 ":" ) ls32
977 : / "::" 5( h16 ":" ) ls32
978 : / [ h16 ] "::" 4( h16 ":" ) ls32
979 : / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
980 : / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
981 : / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
982 : / [ *4( h16 ":" ) h16 ] "::" ls32
983 : / [ *5( h16 ":" ) h16 ] "::" h16
984 : / [ *6( h16 ":" ) h16 ] "::"
985 :
986 : ls32 = ( h16 ":" h16 ) / IPv4address
987 : ; least-significant 32 bits of address
988 :
989 : h16 = 1*4HEXDIG
990 : ; 16 bits of address represented in hexadecimal
991 : @endcode
992 :
993 : @par Specification
994 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
995 : >3.2.2. Host (rfc3986)</a>
996 : */
997 : ipv6_address
998 : host_ipv6_address() const noexcept;
999 :
1000 : /** Return the host IPvFuture address
1001 :
1002 : If the host type is @ref host_type::ipvfuture,
1003 : this function returns the address as
1004 : a string.
1005 : Otherwise, if the host type is not an
1006 : IPvFuture address, it returns an
1007 : empty string.
1008 :
1009 : @return The host IPvFuture address
1010 :
1011 : @par Example
1012 : @code
1013 : assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" );
1014 : @endcode
1015 :
1016 : @par Complexity
1017 : Constant.
1018 :
1019 : @par Exception Safety
1020 : Throws nothing.
1021 :
1022 : @par BNF
1023 : @code
1024 : IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
1025 : @endcode
1026 :
1027 : @par Specification
1028 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
1029 : >3.2.2. Host (rfc3986)</a>
1030 : */
1031 : core::string_view
1032 : host_ipvfuture() const noexcept;
1033 :
1034 : /** Return the host name
1035 :
1036 : If the host type is @ref host_type::name,
1037 : this function returns the name as
1038 : a string.
1039 : Otherwise, if the host type is not an
1040 : name, it returns an empty string.
1041 : Any percent-escapes in the string are
1042 : decoded first.
1043 :
1044 : @param token A string token to receive the result
1045 : @return The host name
1046 :
1047 : @par Example
1048 : @code
1049 : assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" );
1050 : @endcode
1051 :
1052 : @par Complexity
1053 : Linear in `this->host_name().size()`.
1054 :
1055 : @par Exception Safety
1056 : Calls to allocate may throw.
1057 :
1058 : @par BNF
1059 : @code
1060 : host = IP-literal / IPv4address / reg-name
1061 :
1062 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1063 :
1064 : reg-name = *( unreserved / pct-encoded / "-" / ".")
1065 : @endcode
1066 :
1067 : @par Specification
1068 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
1069 : >3.2.2. Host (rfc3986)</a>
1070 : */
1071 : template<BOOST_URL_STRTOK_TPARAM>
1072 : BOOST_URL_STRTOK_RETURN
1073 : host_name(
1074 : BOOST_URL_STRTOK_ARG(token)) const
1075 : {
1076 : encoding_opts opt;
1077 : opt.space_as_plus = false;
1078 : return encoded_host_name().decode(
1079 : opt, std::move(token));
1080 : }
1081 :
1082 : /** Return the host name
1083 :
1084 : If the host type is @ref host_type::name,
1085 : this function returns the name as
1086 : a string.
1087 : Otherwise, if the host type is not an
1088 : name, it returns an empty string.
1089 : The returned string may contain
1090 : percent escapes.
1091 :
1092 : @return The host name
1093 :
1094 : @par Example
1095 : @code
1096 : assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" );
1097 : @endcode
1098 :
1099 : @par Complexity
1100 : Constant.
1101 :
1102 : @par Exception Safety
1103 : Throws nothing.
1104 :
1105 : @par BNF
1106 : @code
1107 : host = IP-literal / IPv4address / reg-name
1108 :
1109 : IP-literal = "[" ( IPv6address / IPvFuture ) "]"
1110 :
1111 : reg-name = *( unreserved / pct-encoded / "-" / ".")
1112 : @endcode
1113 :
1114 : @par Specification
1115 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
1116 : >3.2.2. Host (rfc3986)</a>
1117 : */
1118 : pct_string_view
1119 : encoded_host_name() const noexcept;
1120 :
1121 : //--------------------------------------------
1122 : //
1123 : // Port
1124 : //
1125 : //--------------------------------------------
1126 :
1127 : /** Return true if a port is present
1128 :
1129 : This function returns true if an
1130 : authority is present and contains a port.
1131 :
1132 : @return `true` if a port is present, otherwise `false`
1133 :
1134 : @par Example
1135 : @code
1136 : assert( url_view( "wss://www.example.com:443" ).has_port() );
1137 : @endcode
1138 :
1139 : @par Complexity
1140 : Constant.
1141 :
1142 : @par Exception Safety
1143 : Throws nothing.
1144 :
1145 : @par BNF
1146 : @code
1147 : authority = [ userinfo "@" ] host [ ":" port ]
1148 :
1149 : port = *DIGIT
1150 : @endcode
1151 :
1152 : @par Specification
1153 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
1154 : >3.2.3. Port (rfc3986)</a>
1155 :
1156 : @see
1157 : @ref encoded_host_and_port,
1158 : @ref port,
1159 : @ref port_number.
1160 : */
1161 : bool
1162 : has_port() const noexcept;
1163 :
1164 : /** Return the port
1165 :
1166 : If present, this function returns a
1167 : string representing the port (which
1168 : may be empty).
1169 : Otherwise it returns an empty string.
1170 :
1171 : @return The port as a string
1172 :
1173 : @par Example
1174 : @code
1175 : assert( url_view( "http://localhost.com:8080" ).port() == "8080" );
1176 : @endcode
1177 :
1178 : @par Complexity
1179 : Constant.
1180 :
1181 : @par Exception Safety
1182 : Throws nothing.
1183 :
1184 : @par BNF
1185 : @code
1186 : port = *DIGIT
1187 : @endcode
1188 :
1189 : @par Specification
1190 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
1191 : >3.2.3. Port (rfc3986)</a>
1192 :
1193 : @see
1194 : @ref encoded_host_and_port,
1195 : @ref has_port,
1196 : @ref port_number.
1197 : */
1198 : core::string_view
1199 : port() const noexcept;
1200 :
1201 : /** Return the port
1202 :
1203 : If a port is present and the numerical
1204 : value is representable, it is returned
1205 : as an unsigned integer. Otherwise, the
1206 : number zero is returned.
1207 :
1208 : @return The port number
1209 :
1210 : @par Example
1211 : @code
1212 : assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 );
1213 : @endcode
1214 :
1215 : @par Complexity
1216 : Constant.
1217 :
1218 : @par Exception Safety
1219 : Throws nothing.
1220 :
1221 : @par BNF
1222 : @code
1223 : port = *DIGIT
1224 : @endcode
1225 :
1226 : @par Specification
1227 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
1228 : >3.2.3. Port (rfc3986)</a>
1229 :
1230 : @see
1231 : @ref encoded_host_and_port,
1232 : @ref has_port,
1233 : @ref port.
1234 : */
1235 : std::uint16_t
1236 : port_number() const noexcept;
1237 :
1238 : /** Return the host and port
1239 :
1240 : If an authority is present, this
1241 : function returns the host and optional
1242 : port as a string, which may be empty.
1243 : Otherwise it returns an empty string.
1244 : The returned string may contain
1245 : percent escapes.
1246 :
1247 : @par Example
1248 : @code
1249 : assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" );
1250 : @endcode
1251 :
1252 : @par Complexity
1253 : Constant.
1254 :
1255 : @par Exception Safety
1256 : Throws nothing.
1257 :
1258 : @par BNF
1259 : @code
1260 : authority = [ userinfo "@" ] host [ ":" port ]
1261 : @endcode
1262 :
1263 : @par Specification
1264 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
1265 : >3.2.2. Host (rfc3986)</a>
1266 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3"
1267 : >3.2.3. Port (rfc3986)</a>
1268 :
1269 : @see
1270 : @ref has_port,
1271 : @ref port,
1272 : @ref port_number.
1273 :
1274 : @return The host and port
1275 : */
1276 : pct_string_view
1277 : encoded_host_and_port() const noexcept;
1278 :
1279 : //--------------------------------------------
1280 : //
1281 : // Comparison
1282 : //
1283 : //--------------------------------------------
1284 :
1285 : /** Return the result of comparing this with another authority
1286 :
1287 : This function compares two authorities
1288 : according to Syntax-Based comparison
1289 : algorithm.
1290 :
1291 : @par Exception Safety
1292 : Throws nothing.
1293 :
1294 : @param other The authority to compare
1295 :
1296 : @return `-1` if `*this < other`, `0` if
1297 : `this == other`, and 1 if `this > other`.
1298 :
1299 : @par Specification
1300 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2"
1301 : >6.2.2 Syntax-Based Normalization (rfc3986)</a>
1302 : */
1303 : int
1304 : compare(authority_view const& other) const noexcept;
1305 :
1306 : /** Return the result of comparing two authorities
1307 : The authorities are compared component
1308 : by component as if they were first
1309 : normalized.
1310 :
1311 : @par Complexity
1312 : Linear in `min( a0.size(), a1.size() )`
1313 :
1314 : @par Exception Safety
1315 : Throws nothing
1316 :
1317 : @param a0 The first authority to compare
1318 : @param a1 The second authority to compare
1319 : @return `true` if `a0 == a1`, otherwise `false`
1320 : */
1321 : friend
1322 : bool
1323 : operator==(
1324 : authority_view const& a0,
1325 : authority_view const& a1) noexcept
1326 : {
1327 : return a0.compare(a1) == 0;
1328 : }
1329 :
1330 : /** Return the result of comparing two authorities
1331 : The authorities are compared component
1332 : by component as if they were first
1333 : normalized.
1334 :
1335 : @par Complexity
1336 : Linear in `min( a0.size(), a1.size() )`
1337 :
1338 : @par Exception Safety
1339 : Throws nothing
1340 :
1341 : @param a0 The first authority to compare
1342 : @param a1 The second authority to compare
1343 : @return `true` if `a0 != a1`, otherwise `false`
1344 : */
1345 : friend
1346 : bool
1347 : operator!=(
1348 : authority_view const& a0,
1349 : authority_view const& a1) noexcept
1350 : {
1351 : return ! (a0 == a1);
1352 : }
1353 :
1354 : /** Return the result of comparing two authorities
1355 : The authorities are compared component
1356 : by component as if they were first
1357 : normalized.
1358 :
1359 : @par Complexity
1360 : Linear in `min( a0.size(), a1.size() )`
1361 :
1362 : @par Exception Safety
1363 : Throws nothing
1364 :
1365 : @param a0 The first authority to compare
1366 : @param a1 The second authority to compare
1367 : @return `true` if `a0 < a1`, otherwise `false`
1368 : */
1369 : friend
1370 : bool
1371 : operator<(
1372 : authority_view const& a0,
1373 : authority_view const& a1) noexcept
1374 : {
1375 : return a0.compare(a1) < 0;
1376 : }
1377 :
1378 : /** Return the result of comparing two authorities
1379 : The authorities are compared component
1380 : by component as if they were first
1381 : normalized.
1382 :
1383 : @par Complexity
1384 : Linear in `min( a0.size(), a1.size() )`
1385 :
1386 : @par Exception Safety
1387 : Throws nothing
1388 :
1389 : @param a0 The first authority to compare
1390 : @param a1 The second authority to compare
1391 : @return `true` if `a0 <= a1`, otherwise `false`
1392 : */
1393 : friend
1394 : bool
1395 : operator<=(
1396 : authority_view const& a0,
1397 : authority_view const& a1) noexcept
1398 : {
1399 : return a0.compare(a1) <= 0;
1400 : }
1401 :
1402 : /** Return the result of comparing two authorities
1403 : The authorities are compared component
1404 : by component as if they were first
1405 : normalized.
1406 :
1407 : @par Complexity
1408 : Linear in `min( a0.size(), a1.size() )`
1409 :
1410 : @par Exception Safety
1411 : Throws nothing
1412 :
1413 : @param a0 The first authority to compare
1414 : @param a1 The second authority to compare
1415 : @return `true` if `a0 > a1`, otherwise `false`
1416 : */
1417 : friend
1418 : bool
1419 : operator>(
1420 : authority_view const& a0,
1421 : authority_view const& a1) noexcept
1422 : {
1423 : return a0.compare(a1) > 0;
1424 : }
1425 :
1426 : /** Return the result of comparing two authorities
1427 : The authorities are compared component
1428 : by component as if they were first
1429 : normalized.
1430 :
1431 : @par Complexity
1432 : Linear in `min( a0.size(), a1.size() )`
1433 :
1434 : @par Exception Safety
1435 : Throws nothing
1436 :
1437 : @param a0 The first authority to compare
1438 : @param a1 The second authority to compare
1439 : @return `true` if `a0 >= a1`, otherwise `false`
1440 : */
1441 : friend
1442 : bool
1443 : operator>=(
1444 : authority_view const& a0,
1445 : authority_view const& a1) noexcept
1446 : {
1447 : return a0.compare(a1) >= 0;
1448 : }
1449 :
1450 : //--------------------------------------------
1451 :
1452 : /** Format the encoded authority to the output stream
1453 :
1454 : This hidden friend function serializes the encoded URL
1455 : to the output stream.
1456 :
1457 : @par Example
1458 : @code
1459 : authority_view a( "www.example.com" );
1460 :
1461 : std::cout << a << std::endl;
1462 : @endcode
1463 :
1464 : @return A reference to the output stream, for chaining
1465 :
1466 : @param os The output stream to write to
1467 :
1468 : @param a The URL to write
1469 : */
1470 : friend
1471 : std::ostream&
1472 1 : operator<<(
1473 : std::ostream& os,
1474 : authority_view const& a)
1475 : {
1476 1 : return os << a.buffer();
1477 : }
1478 : };
1479 :
1480 : /** Format the encoded authority to the output stream
1481 :
1482 : This function serializes the encoded URL
1483 : to the output stream.
1484 :
1485 : @par Example
1486 : @code
1487 : authority_view a( "www.example.com" );
1488 :
1489 : std::cout << a << std::endl;
1490 : @endcode
1491 :
1492 : @return A reference to the output stream, for chaining
1493 :
1494 : @param os The output stream to write to
1495 :
1496 : @param a The URL to write
1497 : */
1498 : std::ostream&
1499 : operator<<(
1500 : std::ostream& os,
1501 : authority_view const& a);
1502 :
1503 : //------------------------------------------------
1504 :
1505 : /** Parse an authority
1506 :
1507 : This function parses a string according to
1508 : the authority grammar below, and returns an
1509 : @ref authority_view referencing the string.
1510 : Ownership of the string is not transferred;
1511 : the caller is responsible for ensuring that
1512 : the lifetime of the string extends until the
1513 : view is no longer being accessed.
1514 :
1515 : @par BNF
1516 : @code
1517 : authority = [ userinfo "@" ] host [ ":" port ]
1518 :
1519 : userinfo = user [ ":" [ password ] ]
1520 :
1521 : user = *( unreserved / pct-encoded / sub-delims )
1522 : password = *( unreserved / pct-encoded / sub-delims / ":" )
1523 :
1524 : host = IP-literal / IPv4address / reg-name
1525 :
1526 : port = *DIGIT
1527 : @endcode
1528 :
1529 : @par Exception Safety
1530 : Throws nothing.
1531 :
1532 : @return A view to the parsed authority
1533 :
1534 : @param s The string to parse
1535 :
1536 : @par Specification
1537 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2"
1538 : >3.2. Authority (rfc3986)</a>
1539 :
1540 : @see
1541 : @ref authority_view.
1542 : */
1543 : BOOST_URL_DECL
1544 : system::result<authority_view>
1545 : parse_authority(
1546 : core::string_view s) noexcept;
1547 :
1548 : //------------------------------------------------
1549 :
1550 : } // urls
1551 : } // boost
1552 :
1553 : #endif
|