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