1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2024 Mohammad Nejati
3  
// Copyright (c) 2024 Mohammad Nejati
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/cppalliance/http
8  
// Official repository: https://github.com/cppalliance/http
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_HTTP_DETAIL_HEADER_HPP
11  
#ifndef BOOST_HTTP_DETAIL_HEADER_HPP
12  
#define BOOST_HTTP_DETAIL_HEADER_HPP
12  
#define BOOST_HTTP_DETAIL_HEADER_HPP
13  

13  

14  
#include <boost/http/detail/config.hpp>
14  
#include <boost/http/detail/config.hpp>
15  
#include <boost/http/error.hpp>
15  
#include <boost/http/error.hpp>
16  
#include <boost/http/field.hpp>
16  
#include <boost/http/field.hpp>
17  
#include <boost/http/metadata.hpp>
17  
#include <boost/http/metadata.hpp>
18  
#include <boost/http/method.hpp>
18  
#include <boost/http/method.hpp>
19  
#include <boost/http/status.hpp>
19  
#include <boost/http/status.hpp>
20  
#include <boost/http/version.hpp>
20  
#include <boost/http/version.hpp>
21  

21  

22  
#include <boost/assert.hpp>
22  
#include <boost/assert.hpp>
23  
#include <boost/core/detail/string_view.hpp>
23  
#include <boost/core/detail/string_view.hpp>
24  

24  

25  
#include <cstdint>
25  
#include <cstdint>
26  

26  

27  
namespace boost {
27  
namespace boost {
28  
namespace http {
28  
namespace http {
29  

29  

30  
class fields_base;
30  
class fields_base;
31  
struct header_limits;
31  
struct header_limits;
32  

32  

33  
namespace detail {
33  
namespace detail {
34  

34  

35  
enum kind : unsigned char
35  
enum kind : unsigned char
36  
{
36  
{
37  
    fields = 0,
37  
    fields = 0,
38  
    request,
38  
    request,
39  
    response,
39  
    response,
40  
};
40  
};
41  

41  

42  
struct empty
42  
struct empty
43  
{
43  
{
44  
    kind param;
44  
    kind param;
45  
};
45  
};
46  

46  

47  
struct header
47  
struct header
48  
{
48  
{
49  
    // +------------+---------+------+------------+-----------------------------+
49  
    // +------------+---------+------+------------+-----------------------------+
50  
    // | start-line | headers | \r\n | free space | entry[count-1] ... entry[0] |
50  
    // | start-line | headers | \r\n | free space | entry[count-1] ... entry[0] |
51  
    // +------------+---------+------+------------+-----------------------------+
51  
    // +------------+---------+------+------------+-----------------------------+
52  
    // ^            ^                ^                                          ^
52  
    // ^            ^                ^                                          ^
53  
    // buf          buf+prefix       buf+size                                   buf+cap
53  
    // buf          buf+prefix       buf+size                                   buf+cap
54  

54  

55  
#ifdef BOOST_HTTP_TEST_LIMITS
55  
#ifdef BOOST_HTTP_TEST_LIMITS
56  
    using offset_type = std::uint8_t;
56  
    using offset_type = std::uint8_t;
57  
#else
57  
#else
58  
    using offset_type = std::uint32_t;
58  
    using offset_type = std::uint32_t;
59  
#endif
59  
#endif
60  

60  

61  
    static constexpr
61  
    static constexpr
62  
    std::size_t max_offset =
62  
    std::size_t max_offset =
63  
        std::numeric_limits<
63  
        std::numeric_limits<
64  
            offset_type>::max();
64  
            offset_type>::max();
65  

65  

66  
    static constexpr
66  
    static constexpr
67  
    field unknown_field =
67  
    field unknown_field =
68  
        static_cast<field>(0);
68  
        static_cast<field>(0);
69  

69  

70  
    struct entry
70  
    struct entry
71  
    {
71  
    {
72  
        offset_type np;   // name pos
72  
        offset_type np;   // name pos
73  
        offset_type nn;   // name size
73  
        offset_type nn;   // name size
74  
        offset_type vp;   // value pos
74  
        offset_type vp;   // value pos
75  
        offset_type vn;   // value size
75  
        offset_type vn;   // value size
76  
        field id;
76  
        field id;
77  

77  

78  
        entry operator+(
78  
        entry operator+(
79  
            std::size_t dv) const noexcept;
79  
            std::size_t dv) const noexcept;
80  
        entry operator-(
80  
        entry operator-(
81  
            std::size_t dv) const noexcept;
81  
            std::size_t dv) const noexcept;
82  
    };
82  
    };
83  

83  

84  
    struct table
84  
    struct table
85  
    {
85  
    {
86  
        explicit
86  
        explicit
87  
        table(
87  
        table(
88  
            void* end) noexcept
88  
            void* end) noexcept
89  
            : p_(reinterpret_cast<
89  
            : p_(reinterpret_cast<
90  
                entry*>(end))
90  
                entry*>(end))
91  
        {
91  
        {
92  
        }
92  
        }
93  

93  

94  
        entry&
94  
        entry&
95  
        operator[](
95  
        operator[](
96  
            std::size_t i) const noexcept
96  
            std::size_t i) const noexcept
97  
        {
97  
        {
98  
            return p_[-1 * (
98  
            return p_[-1 * (
99  
                static_cast<
99  
                static_cast<
100  
                    long>(i) + 1)];
100  
                    long>(i) + 1)];
101  
        }
101  
        }
102  

102  

103  
    private:
103  
    private:
104  
        entry* p_;
104  
        entry* p_;
105  
    };
105  
    };
106  

106  

107  
    struct fld_t
107  
    struct fld_t
108  
    {
108  
    {
109  
    };
109  
    };
110  

110  

111  
    struct req_t
111  
    struct req_t
112  
    {
112  
    {
113  
        offset_type method_len;
113  
        offset_type method_len;
114  
        offset_type target_len;
114  
        offset_type target_len;
115  
        http::method method;
115  
        http::method method;
116  
    };
116  
    };
117  

117  

118  
    struct res_t
118  
    struct res_t
119  
    {
119  
    {
120  
        unsigned short status_int;
120  
        unsigned short status_int;
121  
        http::status status;
121  
        http::status status;
122  
    };
122  
    };
123  

123  

124  
    //--------------------------------------------
124  
    //--------------------------------------------
125  

125  

126  
    detail::kind kind;
126  
    detail::kind kind;
127  
    char const* cbuf = nullptr;
127  
    char const* cbuf = nullptr;
128  
    char* buf = nullptr;
128  
    char* buf = nullptr;
129  
    std::size_t cap = 0;
129  
    std::size_t cap = 0;
130  

130  

131  
    offset_type size = 0;
131  
    offset_type size = 0;
132  
    offset_type count = 0;
132  
    offset_type count = 0;
133  
    offset_type prefix = 0;
133  
    offset_type prefix = 0;
134  

134  

135  
    http::version version =
135  
    http::version version =
136  
        http::version::http_1_1;
136  
        http::version::http_1_1;
137  
    metadata md;
137  
    metadata md;
138  

138  

139  
    union
139  
    union
140  
    {
140  
    {
141  
        fld_t fld;
141  
        fld_t fld;
142  
        req_t req;
142  
        req_t req;
143  
        res_t res;
143  
        res_t res;
144  
    };
144  
    };
145  

145  

146  
private:
146  
private:
147  
    struct fields_tag {};
147  
    struct fields_tag {};
148  
    struct request_tag {};
148  
    struct request_tag {};
149  
    struct response_tag {};
149  
    struct response_tag {};
150  

150  

151  
    constexpr header(fields_tag) noexcept;
151  
    constexpr header(fields_tag) noexcept;
152  
    constexpr header(request_tag) noexcept;
152  
    constexpr header(request_tag) noexcept;
153  
    constexpr header(response_tag) noexcept;
153  
    constexpr header(response_tag) noexcept;
154  

154  

155  
public:
155  
public:
156  
    // in fields_base.hpp
156  
    // in fields_base.hpp
157  
    static header&
157  
    static header&
158  
    get(fields_base& f) noexcept;
158  
    get(fields_base& f) noexcept;
159  

159  

160  
    BOOST_HTTP_DECL
160  
    BOOST_HTTP_DECL
161  
    static header const*
161  
    static header const*
162  
    get_default(detail::kind k) noexcept;
162  
    get_default(detail::kind k) noexcept;
163  

163  

164  
    // called from parser
164  
    // called from parser
165  
    explicit header(empty) noexcept;
165  
    explicit header(empty) noexcept;
166  

166  

167  
    BOOST_HTTP_DECL
167  
    BOOST_HTTP_DECL
168  
    header(detail::kind) noexcept;
168  
    header(detail::kind) noexcept;
169  

169  

170  
    BOOST_HTTP_DECL
170  
    BOOST_HTTP_DECL
171  
    void swap(header&) noexcept;
171  
    void swap(header&) noexcept;
172  

172  

173  
    BOOST_HTTP_DECL
173  
    BOOST_HTTP_DECL
174  
    bool keep_alive() const noexcept;
174  
    bool keep_alive() const noexcept;
175  

175  

176  
    static std::size_t bytes_needed(
176  
    static std::size_t bytes_needed(
177  
        std::size_t size, std::size_t count) noexcept;
177  
        std::size_t size, std::size_t count) noexcept;
178  
    static std::size_t table_space(
178  
    static std::size_t table_space(
179  
        std::size_t count) noexcept;
179  
        std::size_t count) noexcept;
180  

180  

181  
    std::size_t table_space() const noexcept;
181  
    std::size_t table_space() const noexcept;
182  

182  

183  
    table tab() const noexcept;
183  
    table tab() const noexcept;
184  
    entry* tab_() const noexcept;
184  
    entry* tab_() const noexcept;
185  
    bool is_default() const noexcept;
185  
    bool is_default() const noexcept;
186  
    std::size_t find(field) const noexcept;
186  
    std::size_t find(field) const noexcept;
187  
    std::size_t find(core::string_view) const noexcept;
187  
    std::size_t find(core::string_view) const noexcept;
188  
    void copy_table(void*, std::size_t) const noexcept;
188  
    void copy_table(void*, std::size_t) const noexcept;
189  
    void copy_table(void*) const noexcept;
189  
    void copy_table(void*) const noexcept;
190  
    void assign_to(header&) const noexcept;
190  
    void assign_to(header&) const noexcept;
191  

191  

192  
    // metadata
192  
    // metadata
193  

193  

194  
    std::size_t maybe_count(field) const noexcept;
194  
    std::size_t maybe_count(field) const noexcept;
195  
    bool is_special(field) const noexcept;
195  
    bool is_special(field) const noexcept;
196  
    void on_start_line();
196  
    void on_start_line();
197  
    void on_insert(field, core::string_view);
197  
    void on_insert(field, core::string_view);
198  
    void on_erase(field);
198  
    void on_erase(field);
199  
    void on_insert_connection(core::string_view);
199  
    void on_insert_connection(core::string_view);
200  
    void on_insert_content_length(core::string_view);
200  
    void on_insert_content_length(core::string_view);
201  
    void on_insert_expect(core::string_view);
201  
    void on_insert_expect(core::string_view);
202  
    void on_insert_transfer_encoding(core::string_view);
202  
    void on_insert_transfer_encoding(core::string_view);
203  
    void on_insert_content_encoding(core::string_view);
203  
    void on_insert_content_encoding(core::string_view);
204  
    void on_insert_upgrade(core::string_view);
204  
    void on_insert_upgrade(core::string_view);
205  
    void on_erase_connection();
205  
    void on_erase_connection();
206  
    void on_erase_content_length();
206  
    void on_erase_content_length();
207  
    void on_erase_expect();
207  
    void on_erase_expect();
208  
    void on_erase_transfer_encoding();
208  
    void on_erase_transfer_encoding();
209  
    void on_erase_content_encoding();
209  
    void on_erase_content_encoding();
210  
    void on_erase_upgrade();
210  
    void on_erase_upgrade();
211  
    void on_erase_all(field);
211  
    void on_erase_all(field);
212  
    void update_payload() noexcept;
212  
    void update_payload() noexcept;
213  

213  

214  
    // parsing
214  
    // parsing
215  

215  

216  
    static std::size_t
216  
    static std::size_t
217  
    count_crlf(core::string_view s) noexcept;
217  
    count_crlf(core::string_view s) noexcept;
218  

218  

219  
    void parse(
219  
    void parse(
220  
        std::size_t,
220  
        std::size_t,
221  
        header_limits const&,
221  
        header_limits const&,
222  
        system::error_code&) noexcept;
222  
        system::error_code&) noexcept;
223  
};
223  
};
224  

224  

225  
} // detail
225  
} // detail
226  
} // http
226  
} // http
227  
} // boost
227  
} // boost
228  

228  

229  
#endif
229  
#endif