GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/detail/header.hpp
Date: 2025-06-15 05:10:38
Exec Total Coverage
Lines: 10 10 100.0%
Functions: 3 3 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2024 Mohammad Nejati
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/cppalliance/http_proto
9 //
10
11 #ifndef BOOST_HTTP_PROTO_DETAIL_HEADER_HPP
12 #define BOOST_HTTP_PROTO_DETAIL_HEADER_HPP
13
14 #include <boost/http_proto/detail/align_up.hpp>
15 #include <boost/http_proto/detail/config.hpp>
16 #include <boost/http_proto/error.hpp>
17 #include <boost/http_proto/field.hpp>
18 #include <boost/http_proto/metadata.hpp>
19 #include <boost/http_proto/method.hpp>
20 #include <boost/http_proto/status.hpp>
21 #include <boost/http_proto/version.hpp>
22 #include <boost/core/detail/string_view.hpp>
23 #include <boost/assert.hpp>
24 #include <cstdint>
25 #include <type_traits>
26
27 namespace boost {
28 namespace http_proto {
29
30 class fields_base;
31 struct header_limits;
32
33 namespace detail {
34
35 enum kind : unsigned char
36 {
37 fields = 0,
38 request,
39 response,
40 };
41
42 struct empty
43 {
44 kind param;
45 };
46
47 struct header
48 {
49 // +------------+-----------+--------------+------------------------------+
50 // | start-line | headers | free space | entry[count-1] ... entry[0] |
51 // +------------+-----------+--------------+------------------------------+
52 // ^ ^ ^ ^
53 // buf buf+prefix buf+size buf+cap
54
55 struct entry
56 {
57 offset_type np; // name pos
58 offset_type nn; // name size
59 offset_type vp; // value pos
60 offset_type vn; // value size
61 field id;
62
63 entry operator+(
64 std::size_t dv) const noexcept;
65 entry operator-(
66 std::size_t dv) const noexcept;
67 };
68
69 // HTTP-message = start-line CRLF *( field-line CRLF ) CRLF
70 // start-line = request-line / status-line
71 // status-line = HTTP-version SP status-code SP [ reason-phrase ]
72 // status-code = 3DIGIT
73 // HTTP-name = %x48.54.54.50 ; HTTP
74 // HTTP-version = HTTP-name "/" DIGIT "." DIGIT
75 //
76 // => "HTTP/1.1 111 \r\n" + trailing "\r\n"
77 static
78 constexpr
79 std::size_t const min_status_line = 17;
80
81 // "X:\r\n"
82 static
83 constexpr
84 std::size_t const min_field_line = 4;
85
86 static
87 constexpr
88 std::size_t const max_field_lines =
89 (max_offset - min_status_line) / min_field_line;
90
91 /** Returns the largest permissible capacity in bytes
92 */
93 static
94 constexpr
95 std::size_t
96 11974 max_capacity_in_bytes() noexcept
97 {
98 // the entire serialized contents of the header
99 // must fit entirely in max_offset
100 11974 return align_up(
101 (max_offset + (max_field_lines * sizeof(entry))),
102 11974 alignof(entry));
103 }
104
105 struct table
106 {
107 explicit
108 26882 table(
109 void* end) noexcept
110 26882 : p_(reinterpret_cast<
111 entry*>(end))
112 {
113 26882 }
114
115 entry&
116 26918 operator[](
117 std::size_t i) const noexcept
118 {
119 26918 return p_[-1 * (
120 26918 static_cast<
121 26918 long>(i) + 1)];
122 }
123
124 private:
125 entry* p_;
126 };
127
128 struct fld_t
129 {
130 };
131
132 struct req_t
133 {
134 offset_type method_len;
135 offset_type target_len;
136 http_proto::method method;
137 };
138
139 struct res_t
140 {
141 unsigned short status_int;
142 http_proto::status status;
143 };
144
145 //--------------------------------------------
146
147 detail::kind kind;
148 char const* cbuf = nullptr;
149 char* buf = nullptr;
150 std::size_t cap = 0;
151 std::size_t max_cap = max_capacity_in_bytes();
152
153 offset_type size = 0;
154 offset_type count = 0;
155 offset_type prefix = 0;
156
157 http_proto::version version =
158 http_proto::version::http_1_1;
159 metadata md;
160
161 union
162 {
163 fld_t fld;
164 req_t req;
165 res_t res;
166 };
167
168 private:
169 struct fields_tag {};
170 struct request_tag {};
171 struct response_tag {};
172
173 constexpr header(fields_tag) noexcept;
174 constexpr header(request_tag) noexcept;
175 constexpr header(response_tag) noexcept;
176
177 public:
178 // in fields_base.hpp
179 static header& get(fields_base& f) noexcept;
180
181 BOOST_HTTP_PROTO_DECL static header const*
182 get_default(detail::kind k) noexcept;
183
184 // called from parser
185 explicit header(empty) noexcept;
186
187 BOOST_HTTP_PROTO_DECL header(detail::kind) noexcept;
188 BOOST_HTTP_PROTO_DECL void swap(header&) noexcept;
189 BOOST_HTTP_PROTO_DECL bool keep_alive() const noexcept;
190
191 static std::size_t bytes_needed(
192 std::size_t size, std::size_t count) noexcept;
193 static std::size_t table_space(
194 std::size_t count) noexcept;
195 std::size_t table_space() const noexcept;
196
197 table tab() const noexcept;
198 entry* tab_() const noexcept;
199 bool is_default() const noexcept;
200 std::size_t find(field) const noexcept;
201 std::size_t find(core::string_view) const noexcept;
202 void copy_table(void*, std::size_t) const noexcept;
203 void copy_table(void*) const noexcept;
204 void assign_to(header&) const noexcept;
205
206 // metadata
207
208 std::size_t maybe_count(field) const noexcept;
209 bool is_special(field) const noexcept;
210 void on_start_line();
211 void on_insert(field, core::string_view);
212 void on_erase(field);
213 void on_insert_connection(core::string_view);
214 void on_insert_content_length(core::string_view);
215 void on_insert_expect(core::string_view);
216 void on_insert_transfer_encoding();
217 void on_insert_content_encoding(core::string_view);
218 void on_insert_upgrade(core::string_view);
219 void on_erase_connection();
220 void on_erase_content_length();
221 void on_erase_expect();
222 void on_erase_transfer_encoding();
223 void on_erase_content_encoding();
224 void on_erase_upgrade();
225 void on_erase_all(field);
226 void update_payload() noexcept;
227
228 // parsing
229
230 static std::size_t count_crlf(
231 core::string_view s) noexcept;
232 BOOST_HTTP_PROTO_DECL void parse(
233 std::size_t, header_limits const&,
234 system::error_code&) noexcept;
235 };
236
237 } // detail
238 } // http_proto
239 } // boost
240
241 #endif
242