GCC Code Coverage Report


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

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