Line data Source code
1 : // 2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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 : 11 : #include <boost/url/detail/config.hpp> 12 : #include <boost/url/rfc/ipv4_address_rule.hpp> 13 : #include "host_rule.hpp" 14 : #include "ip_literal_rule.hpp" 15 : #include "reg_name_rule.hpp" 16 : #include <boost/url/grammar/parse.hpp> 17 : 18 : namespace boost { 19 : namespace urls { 20 : namespace detail { 21 : 22 : auto 23 1938 : host_rule_t:: 24 : parse( 25 : char const*& it, 26 : char const* const end 27 : ) const noexcept -> 28 : system::result<value_type> 29 : { 30 1938 : value_type t; 31 : 32 1938 : if(it == end) 33 : { 34 : // empty host 35 224 : t.host_type = 36 : urls::host_type::name; 37 224 : return t; 38 : } 39 : 40 1714 : auto const it0 = it; 41 1714 : if(*it == '[') 42 : { 43 : // IP-literal 44 : auto rv = grammar::parse( 45 : it, end, 46 61 : detail::ip_literal_rule); 47 61 : if(! rv) 48 24 : return rv.error(); 49 37 : auto v = *rv; 50 37 : if(v.is_ipv6) 51 : { 52 : // IPv6address 53 : auto const b = 54 32 : v.ipv6.to_bytes(); 55 32 : std::memcpy( 56 : t.addr, 57 32 : b.data(), 58 : b.size()); 59 32 : t.host_type = 60 : urls::host_type::ipv6; 61 64 : t.match = core::string_view( 62 32 : it0, it - it0); 63 32 : return t; 64 : } 65 : 66 : // IPvFuture 67 5 : t.host_type = 68 : urls::host_type::ipvfuture; 69 10 : t.match = core::string_view( 70 5 : it0, it - it0); 71 5 : return t; 72 : } 73 : 74 : // IPv4address 75 : { 76 : auto rv = grammar::parse( 77 1653 : it, end, ipv4_address_rule); 78 1653 : if( rv ) 79 : { 80 27 : auto it02 = it; 81 : auto rv2 = grammar::parse( 82 : it, end, 83 27 : detail::reg_name_rule); 84 53 : if (rv2.has_value() && 85 26 : !rv2->empty()) 86 : { 87 6 : t.name = core::string_view( 88 6 : it0, it - it0); 89 6 : t.host_type = 90 : urls::host_type::name; 91 12 : t.match = core::string_view( 92 6 : it0, it - it0); 93 6 : return t; 94 : } 95 21 : it = it02; 96 : auto const b = 97 21 : rv->to_bytes(); 98 21 : std::memcpy( 99 : t.addr, 100 21 : b.data(), 101 : b.size()); 102 21 : t.host_type = 103 : urls::host_type::ipv4; 104 42 : t.match = core::string_view( 105 21 : it0, it - it0); 106 21 : return t; 107 : } 108 : 109 1626 : it = it0; // rewind 110 : } 111 : 112 : // reg-name 113 : { 114 : auto rv = grammar::parse( 115 : it, end, 116 1626 : detail::reg_name_rule); 117 1626 : if(! rv) 118 7 : return rv.error(); 119 1619 : t.name = *rv; 120 1619 : t.host_type = 121 : urls::host_type::name; 122 3238 : t.match = core::string_view( 123 1619 : it0, it - it0); 124 1619 : return t; 125 : } 126 : } 127 : 128 : } // detail 129 : } // urls 130 : } // boost 131 :