GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/static_request.hpp
Date: 2025-09-21 18:08:15
Exec Total Coverage
Lines: 19 19 100.0%
Functions: 9 9 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Mohammad Nejati
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/cppalliance/http_proto
8 //
9
10 #ifndef BOOST_HTTP_PROTO_STATIC_REQUEST_HPP
11 #define BOOST_HTTP_PROTO_STATIC_REQUEST_HPP
12
13 #include <boost/http_proto/request_base.hpp>
14
15 namespace boost {
16 namespace http_proto {
17
18 /** A modifiable static container for HTTP requests.
19
20 This container owns a request, represented
21 by an inline buffer with fixed capacity.
22 The contents may be inspected and modified,
23 and the implementation maintains a useful
24 invariant: changes to the request always
25 leave it in a valid state.
26
27 @par Example
28 @code
29 static_request<1024> req(method::get, "/");
30
31 req.set(field::host, "example.com");
32 req.set(field::accept_encoding, "gzip, deflate, br");
33 req.set(field::cache_control, "no-cache");
34
35 assert(req.buffer() ==
36 "GET / HTTP/1.1\r\n"
37 "Host: example.com\r\n"
38 "Accept-Encoding: gzip, deflate, br\r\n"
39 "Cache-Control: no-cache\r\n"
40 "\r\n");
41 @endcode
42
43 @par Invariants
44 @code
45 this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() == Capacity
46 @endcode
47
48 @tparam Capacity The maximum capacity in bytes.
49
50 @see
51 @ref request,
52 @ref request_view.
53 */
54 template<std::size_t Capacity>
55 class static_request
56 : public request_base
57 {
58 alignas(entry)
59 char buf_[Capacity];
60
61 public:
62
63 //--------------------------------------------
64 //
65 // Special Members
66 //
67 //--------------------------------------------
68
69 /** Constructor.
70
71 A default-constructed request contains
72 a valid HTTP `GET` request with no headers.
73
74 @par Example
75 @code
76 static_request<1024> req;
77 @endcode
78
79 @par Postconditions
80 @code
81 this->buffer() == "GET / HTTP/1.1\r\n\r\n"
82 @endcode
83
84 @par Complexity
85 Constant.
86 */
87 40 static_request() noexcept
88 40 : fields_view_base(&this->fields_base::h_)
89 40 , request_base(buf_, Capacity)
90 {
91 40 }
92
93 /** Constructor.
94
95 Constructs a request from the string `s`,
96 which must contain valid HTTP request
97 or else an exception is thrown.
98 The new request retains ownership by
99 making a copy of the passed string.
100
101 @par Example
102 @code
103 static_request<1024> req(
104 "GET / HTTP/1.1\r\n"
105 "Accept-Encoding: gzip, deflate, br\r\n"
106 "Cache-Control: no-cache\r\n"
107 "\r\n");
108 @endcode
109
110 @par Postconditions
111 @code
112 this->buffer.data() != s.data()
113 @endcode
114
115 @par Complexity
116 Linear in `s.size()`.
117
118 @par Exception Safety
119 Exception thrown on invalid input.
120 Exception thrown if max capacity exceeded.
121
122 @throw system_error
123 The input does not contain a valid request.
124
125 @throw std::length_error
126 Max capacity would be exceeded.
127
128 @param s The string to parse.
129 */
130 explicit
131 44 static_request(
132 core::string_view s)
133 44 : fields_view_base(&this->fields_base::h_)
134 44 , request_base(s, buf_, Capacity)
135 {
136 44 }
137
138 /** Constructor.
139
140 The start-line of the request will
141 contain the standard text for the
142 supplied method, target and HTTP version.
143
144 @par Example
145 @code
146 static_request<1024> req(method::get, "/index.html", version::http_1_0);
147 @endcode
148
149 @par Complexity
150 Linear in `to_string(m).size() + t.size()`.
151
152 @par Exception Safety
153 Exception thrown if max capacity exceeded.
154
155 @throw std::length_error
156 Max capacity would be exceeded.
157
158 @param m The method to set.
159
160 @param t The string representing a target.
161
162 @param v The version to set.
163 */
164 static_request(
165 http_proto::method m,
166 core::string_view t,
167 http_proto::version v) noexcept
168 : static_request()
169 {
170 set_start_line(m, t, v);
171 }
172
173 /** Constructor.
174
175 The start-line of the request will
176 contain the standard text for the
177 supplied method and target with the HTTP
178 version defaulted to `HTTP/1.1`.
179
180 @par Example
181 @code
182 static_request<1024> req(method::get, "/index.html");
183 @endcode
184
185 @par Complexity
186 Linear in `obsolete_reason(s).size()`.
187
188 @par Exception Safety
189 Exception thrown if max capacity exceeded.
190
191 @throw std::length_error
192 Max capacity would be exceeded.
193
194 @param m The method to set.
195
196 @param t The string representing a target.
197 */
198 static_request(
199 http_proto::method m,
200 core::string_view t)
201 : static_request(
202 m, t, http_proto::version::http_1_1)
203 {
204 }
205
206 /** Constructor.
207
208 The newly constructed object contains
209 a copy of `r`.
210
211 @par Postconditions
212 @code
213 this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
214 @endcode
215
216 @par Complexity
217 Linear in `r.size()`.
218
219 @param r The request to copy.
220 */
221 4 static_request(
222 static_request const& r) noexcept
223 4 : fields_view_base(&this->fields_base::h_)
224 4 , request_base(*r.ph_, buf_, Capacity)
225 {
226 4 }
227
228 /** Constructor.
229
230 The newly constructed object contains
231 a copy of `r`.
232
233 @par Postconditions
234 @code
235 this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
236 @endcode
237
238 @par Complexity
239 Linear in `r.size()`.
240
241 @par Exception Safety
242 Exception thrown if max capacity exceeded.
243
244 @throw std::length_error
245 Max capacity would be exceeded.
246
247 @param r The request to copy.
248 */
249 2 static_request(
250 request_view const& r)
251 2 : fields_view_base(&this->fields_base::h_)
252 2 , request_base(*r.ph_, buf_, Capacity)
253 {
254 2 }
255
256 /** Assignment.
257
258 The contents of `r` are copied and
259 the previous contents of `this` are
260 discarded.
261
262 @par Postconditions
263 @code
264 this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
265 @endcode
266
267 @par Complexity
268 Linear in `r.size()`.
269
270 @param r The request to copy.
271
272 @return A reference to this object.
273 */
274 static_request&
275 9 operator=(
276 static_request const& r) noexcept
277 {
278 9 copy_impl(*r.ph_);
279 9 return *this;
280 }
281
282 /** Assignment.
283
284 The contents of `r` are copied and
285 the previous contents of `this` are
286 discarded.
287
288 @par Postconditions
289 @code
290 this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
291 @endcode
292
293 @par Complexity
294 Linear in `r.size()`.
295
296 @par Exception Safety
297 Strong guarantee.
298 Exception thrown if max capacity exceeded.
299
300 @throw std::length_error
301 Max capacity would be exceeded.
302
303 @param r The request to copy.
304
305 @return A reference to this object.
306 */
307 static_request&
308 operator=(
309 request_view const& r)
310 {
311 copy_impl(*r.ph_);
312 return *this;
313 }
314 };
315
316 } // http_proto
317 } // boost
318
319 #endif
320