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