1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_HPP
11  
#ifndef BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/rfc/ipv4_address_rule.hpp>
15  
#include <boost/url/rfc/ipv4_address_rule.hpp>
16  
#include <boost/url/rfc/detail/ip_literal_rule.hpp>
16  
#include <boost/url/rfc/detail/ip_literal_rule.hpp>
17  
#include <boost/url/rfc/detail/reg_name_rule.hpp>
17  
#include <boost/url/rfc/detail/reg_name_rule.hpp>
18  
#include <boost/url/grammar/parse.hpp>
18  
#include <boost/url/grammar/parse.hpp>
19  
#include <cstring>
19  
#include <cstring>
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace urls {
22  
namespace urls {
23  
namespace detail {
23  
namespace detail {
24  

24  

25  
BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
25  
BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
26  
auto
26  
auto
27  
host_rule_t::
27  
host_rule_t::
28  
parse(
28  
parse(
29  
    char const*& it,
29  
    char const*& it,
30  
    char const* const end
30  
    char const* const end
31  
        ) const noexcept ->
31  
        ) const noexcept ->
32  
    system::result<value_type>
32  
    system::result<value_type>
33  
{
33  
{
34  
    value_type t;
34  
    value_type t;
35  

35  

36  
    if(it == end)
36  
    if(it == end)
37  
    {
37  
    {
38  
        // empty host
38  
        // empty host
39  
        t.host_type =
39  
        t.host_type =
40  
            urls::host_type::name;
40  
            urls::host_type::name;
41  
        return t;
41  
        return t;
42  
    }
42  
    }
43  

43  

44  
    auto const it0 = it;
44  
    auto const it0 = it;
45  
    if(*it == '[')
45  
    if(*it == '[')
46  
    {
46  
    {
47  
        // IP-literal
47  
        // IP-literal
48  
        auto rv = grammar::parse(
48  
        auto rv = grammar::parse(
49  
            it, end,
49  
            it, end,
50  
            detail::ip_literal_rule);
50  
            detail::ip_literal_rule);
51  
        if(! rv)
51  
        if(! rv)
52  
            return rv.error();
52  
            return rv.error();
53  
        auto v = *rv;
53  
        auto v = *rv;
54  
        if(v.is_ipv6)
54  
        if(v.is_ipv6)
55  
        {
55  
        {
56  
            // IPv6address
56  
            // IPv6address
57  
            auto const b =
57  
            auto const b =
58  
                v.ipv6.to_bytes();
58  
                v.ipv6.to_bytes();
59  
            std::memcpy(
59  
            std::memcpy(
60  
                t.addr,
60  
                t.addr,
61  
                b.data(),
61  
                b.data(),
62  
                b.size());
62  
                b.size());
63  
            t.host_type =
63  
            t.host_type =
64  
                urls::host_type::ipv6;
64  
                urls::host_type::ipv6;
65  
            t.match = make_pct_string_view_unsafe(
65  
            t.match = make_pct_string_view_unsafe(
66  
                it0, it - it0, it - it0);
66  
                it0, it - it0, it - it0);
67  
            return t;
67  
            return t;
68  
        }
68  
        }
69  

69  

70  
        // IPvFuture
70  
        // IPvFuture
71  
        t.host_type =
71  
        t.host_type =
72  
            urls::host_type::ipvfuture;
72  
            urls::host_type::ipvfuture;
73  
        t.match = make_pct_string_view_unsafe(
73  
        t.match = make_pct_string_view_unsafe(
74  
            it0, it - it0, it - it0);
74  
            it0, it - it0, it - it0);
75  
        return t;
75  
        return t;
76  
    }
76  
    }
77  

77  

78  
    // IPv4address
78  
    // IPv4address
79  
    {
79  
    {
80  
        auto rv = grammar::parse(
80  
        auto rv = grammar::parse(
81  
            it, end, ipv4_address_rule);
81  
            it, end, ipv4_address_rule);
82  
        if( rv )
82  
        if( rv )
83  
        {
83  
        {
84  
            auto it02 = it;
84  
            auto it02 = it;
85  
            auto rv2 = grammar::parse(
85  
            auto rv2 = grammar::parse(
86  
                it, end,
86  
                it, end,
87  
                detail::reg_name_rule);
87  
                detail::reg_name_rule);
88  
            if (rv2.has_value() &&
88  
            if (rv2.has_value() &&
89  
                !rv2->empty())
89  
                !rv2->empty())
90  
            {
90  
            {
91  
                auto dn = static_cast<
91  
                auto dn = static_cast<
92  
                    std::size_t>(it02 - it0) +
92  
                    std::size_t>(it02 - it0) +
93  
                    rv2->decoded_size();
93  
                    rv2->decoded_size();
94  
                t.name = make_pct_string_view_unsafe(
94  
                t.name = make_pct_string_view_unsafe(
95  
                    it0, it - it0, dn);
95  
                    it0, it - it0, dn);
96  
                t.host_type =
96  
                t.host_type =
97  
                    urls::host_type::name;
97  
                    urls::host_type::name;
98  
                t.match = t.name;
98  
                t.match = t.name;
99  
                return t;
99  
                return t;
100  
            }
100  
            }
101  
            it = it02;
101  
            it = it02;
102  
            auto const b =
102  
            auto const b =
103  
                rv->to_bytes();
103  
                rv->to_bytes();
104  
            std::memcpy(
104  
            std::memcpy(
105  
                t.addr,
105  
                t.addr,
106  
                b.data(),
106  
                b.data(),
107  
                b.size());
107  
                b.size());
108  
            t.host_type =
108  
            t.host_type =
109  
                urls::host_type::ipv4;
109  
                urls::host_type::ipv4;
110  
            t.match = make_pct_string_view_unsafe(
110  
            t.match = make_pct_string_view_unsafe(
111  
                it0, it - it0, it - it0);
111  
                it0, it - it0, it - it0);
112  
            return t;
112  
            return t;
113  
        }
113  
        }
114  

114  

115  
        it = it0; // rewind
115  
        it = it0; // rewind
116  
    }
116  
    }
117  

117  

118  
    // reg-name
118  
    // reg-name
119  
    {
119  
    {
120  
        auto rv = grammar::parse(
120  
        auto rv = grammar::parse(
121  
            it, end,
121  
            it, end,
122  
            detail::reg_name_rule);
122  
            detail::reg_name_rule);
123  
        if(! rv)
123  
        if(! rv)
124  
            return rv.error();
124  
            return rv.error();
125  
        t.name = *rv;
125  
        t.name = *rv;
126  
        t.host_type =
126  
        t.host_type =
127  
            urls::host_type::name;
127  
            urls::host_type::name;
128  
        t.match = *rv;
128  
        t.match = *rv;
129  
        return t;
129  
        return t;
130  
    }
130  
    }
131  
}
131  
}
132  

132  

133  
} // detail
133  
} // detail
134  
} // urls
134  
} // urls
135  
} // boost
135  
} // boost
136  

136  

137  

137  

138  
#endif
138  
#endif