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