GCC Code Coverage Report


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