GCC Code Coverage Report


Directory: ./
File: libs/http_proto/include/boost/http_proto/request.hpp
Date: 2025-12-09 20:49:49
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 10 10 100.0%
Branches: 2 2 100.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_REQUEST_HPP
11 #define BOOST_HTTP_PROTO_REQUEST_HPP
12
13 #include <boost/http_proto/request_base.hpp>
14
15 #if defined(BOOST_MSVC)
16 # pragma warning(push)
17 # pragma warning(disable:4251)
18 #endif
19
20 namespace boost {
21 namespace http_proto {
22
23 /** A modifiable container for HTTP requests.
24
25 This container owns a request, represented by
26 a buffer which is managed by performing
27 dynamic memory allocations as needed. The
28 contents may be inspected and modified, and
29 the implementation maintains a useful
30 invariant: changes to the request always leave
31 it in a valid state.
32
33 @par Example
34 @code
35 request req(method::get, "/");
36
37 req.set(field::host, "example.com");
38 req.set(field::accept_encoding, "gzip, deflate, br");
39 req.set(field::cache_control, "no-cache");
40
41 assert(req.buffer() ==
42 "GET / HTTP/1.1\r\n"
43 "Host: example.com\r\n"
44 "Accept-Encoding: gzip, deflate, br\r\n"
45 "Cache-Control: no-cache\r\n"
46 "\r\n");
47 @endcode
48
49 @see
50 @ref static_request,
51 @ref request_base.
52 */
53 class BOOST_HTTP_PROTO_DECL request
54 : public request_base
55 {
56 public:
57 //--------------------------------------------
58 //
59 // Special Members
60 //
61 //--------------------------------------------
62
63 /** Constructor.
64
65 A default-constructed request contains
66 a valid HTTP `GET` request with no headers.
67
68 @par Example
69 @code
70 request req;
71 @endcode
72
73 @par Postconditions
74 @code
75 this->buffer() == "GET / HTTP/1.1\r\n\r\n"
76 @endcode
77
78 @par Complexity
79 Constant.
80 */
81 65 request() noexcept = default;
82
83 /** Constructor.
84
85 Constructs a request from the string `s`,
86 which must contain valid HTTP request
87 or else an exception is thrown.
88 The new request retains ownership by
89 making a copy of the passed string.
90
91 @par Example
92 @code
93 request req(
94 "GET / HTTP/1.1\r\n"
95 "Accept-Encoding: gzip, deflate, br\r\n"
96 "Cache-Control: no-cache\r\n"
97 "\r\n");
98 @endcode
99
100 @par Postconditions
101 @code
102 this->buffer.data() != s.data()
103 @endcode
104
105 @par Complexity
106 Linear in `s.size()`.
107
108 @par Exception Safety
109 Calls to allocate may throw.
110 Exception thrown on invalid input.
111
112 @throw system_error
113 The input does not contain a valid request.
114
115 @param s The string to parse.
116 */
117 explicit
118 212 request(
119 core::string_view s)
120 212 : request_base(s)
121 {
122 211 }
123
124 /** Constructor.
125
126 The start-line of the request will
127 contain the standard text for the
128 supplied method, target and HTTP version.
129
130 @par Example
131 @code
132 request req(method::get, "/index.html", version::http_1_0);
133 @endcode
134
135 @par Complexity
136 Linear in `to_string(m).size() + t.size()`.
137
138 @par Exception Safety
139 Calls to allocate may throw.
140
141 @param m The method to set.
142
143 @param t The string representing a target.
144
145 @param v The version to set.
146 */
147 request(
148 http_proto::method m,
149 core::string_view t,
150 http_proto::version v) noexcept
151 : request()
152 {
153 set_start_line(m, t, v);
154 }
155
156 /** Constructor.
157
158 The start-line of the request will
159 contain the standard text for the
160 supplied method and target with the HTTP
161 version defaulted to `HTTP/1.1`.
162
163 @par Example
164 @code
165 request req(method::get, "/index.html");
166 @endcode
167
168 @par Complexity
169 Linear in `to_string(s).size()`.
170
171 @par Exception Safety
172 Calls to allocate may throw.
173
174 @param m The method to set.
175
176 @param t The string representing a target.
177 */
178 request(
179 http_proto::method m,
180 core::string_view t)
181 : request(
182 m, t, http_proto::version::http_1_1)
183 {
184 }
185
186 /** Constructor.
187
188 Allocates `cap` bytes initially, with an
189 upper limit of `max_cap`. Growing beyond
190 `max_cap` will throw an exception.
191
192 Useful when an estimated initial size is
193 known, but further growth up to a maximum
194 is allowed.
195
196 When `cap == max_cap`, the container
197 guarantees to never allocate.
198
199 @par Preconditions
200 @code
201 max_cap >= cap
202 @endcode
203
204 @par Exception Safety
205 Calls to allocate may throw.
206
207 @param cap Initial capacity in bytes (may be `0`).
208
209 @param max_cap Maximum allowed capacity in bytes.
210 */
211 10 request(
212 std::size_t cap,
213 std::size_t max_cap = std::size_t(-1))
214 10 : request()
215 {
216
1/1
✓ Branch 1 taken 10 times.
10 reserve_bytes(cap);
217
1/1
✓ Branch 1 taken 8 times.
10 set_max_capacity_in_bytes(max_cap);
218 10 }
219
220 /** Constructor.
221
222 The contents of `r` are transferred
223 to the newly constructed object,
224 which includes the underlying
225 character buffer.
226 After construction, the moved-from
227 object is as if default-constructed.
228
229 @par Postconditions
230 @code
231 r.buffer() == "GET / HTTP/1.1\r\n\r\n"
232 @endcode
233
234 @par Complexity
235 Constant.
236
237 @param r The request to move from.
238 */
239 26 request(
240 request&& other) noexcept
241 26 : request()
242 {
243 26 swap(other);
244 26 }
245
246 /** Constructor.
247
248 The newly constructed object contains
249 a copy of `r`.
250
251 @par Postconditions
252 @code
253 this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
254 @endcode
255
256 @par Complexity
257 Linear in `r.size()`.
258
259 @par Exception Safety
260 Calls to allocate may throw.
261
262 @param r The request to copy.
263 */
264 2 request(
265 request const& r) = default;
266
267 /** Constructor.
268
269 The newly constructed object contains
270 a copy of `r`.
271
272 @par Postconditions
273 @code
274 this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
275 @endcode
276
277 @par Complexity
278 Linear in `r.size()`.
279
280 @par Exception Safety
281 Calls to allocate may throw.
282
283 @param r The request to copy.
284 */
285 2 request(
286 request_base const& r)
287 2 : request_base(r)
288 {
289 2 }
290
291 /** Assignment
292
293 The contents of `r` are transferred to
294 `this`, including the underlying
295 character buffer. The previous contents
296 of `this` are destroyed.
297 After assignment, the moved-from
298 object is as if default-constructed.
299
300 @par Postconditions
301 @code
302 r.buffer() == "GET / HTTP/1.1\r\n\r\n"
303 @endcode
304
305 @par Complexity
306 Constant.
307
308 @param r The request to assign from.
309
310 @return A reference to this object.
311 */
312 request&
313 24 operator=(request&& r) noexcept
314 {
315 24 request temp(std::move(r));
316 24 temp.swap(*this);
317 48 return *this;
318 24 }
319
320 /** Assignment.
321
322 The contents of `r` are copied and
323 the previous contents of `this` are
324 discarded.
325
326 @par Postconditions
327 @code
328 this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
329 @endcode
330
331 @par Complexity
332 Linear in `r.size()`.
333
334 @par Exception Safety
335 Strong guarantee.
336 Calls to allocate may throw.
337 Exception thrown if max capacity exceeded.
338
339 @throw std::length_error
340 Max capacity would be exceeded.
341
342 @param r The request to copy.
343
344 @return A reference to this object.
345 */
346 request&
347 3 operator=(
348 request const& r)
349 {
350 3 copy_impl(r.h_);
351 3 return *this;
352 }
353
354 /** Assignment.
355
356 The contents of `r` are copied and
357 the previous contents of `this` are
358 discarded.
359
360 @par Postconditions
361 @code
362 this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
363 @endcode
364
365 @par Complexity
366 Linear in `r.size()`.
367
368 @par Exception Safety
369 Strong guarantee.
370 Calls to allocate may throw.
371 Exception thrown if max capacity exceeded.
372
373 @throw std::length_error
374 Max capacity would be exceeded.
375
376 @param r The request to copy.
377
378 @return A reference to this object.
379 */
380 request&
381 1 operator=(
382 request_base const& r)
383 {
384 1 copy_impl(r.h_);
385 1 return *this;
386 }
387
388 //--------------------------------------------
389
390 /** Swap.
391
392 Exchanges the contents of this request
393 with another request. All views,
394 iterators and references remain valid.
395
396 If `this == &other`, this function call has no effect.
397
398 @par Example
399 @code
400 request r1(method::get, "/");
401 request r2(method::delete_, "/item/42");
402 r1.swap(r2);
403 assert(r1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
404 assert(r2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
405 @endcode
406
407 @par Complexity
408 Constant
409
410 @param other The object to swap with
411 */
412 void
413 50 swap(request& other) noexcept
414 {
415 50 h_.swap(other.h_);
416 50 std::swap(max_cap_, other.max_cap_);
417 50 }
418
419 /** Swap.
420
421 Exchanges the contents of `v0` with
422 another `v1`. All views, iterators and
423 references remain valid.
424
425 If `&v0 == &v1`, this function call has no effect.
426
427 @par Example
428 @code
429 request r1(method::get, "/");
430 request r2(method::delete_, "/item/42");
431 std::swap(r1, r2);
432 assert(r1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
433 assert(r2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
434 @endcode
435
436 @par Effects
437 @code
438 v0.swap(v1);
439 @endcode
440
441 @par Complexity
442 Constant.
443
444 @param v0 The first object to swap.
445 @param v1 The second object to swap.
446
447 @see
448 @ref request::swap
449 */
450 friend
451 void
452 swap(
453 request& v0,
454 request& v1) noexcept
455 {
456 v0.swap(v1);
457 }
458 };
459
460 #if defined(BOOST_MSVC)
461 # pragma warning(pop)
462 #endif
463
464 } // http_proto
465 } // boost
466
467 #endif
468