Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Christian Mazakas
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_RESPONSE_HPP
12 : #define BOOST_HTTP_PROTO_RESPONSE_HPP
13 :
14 : #include <boost/http_proto/detail/config.hpp>
15 : #include <boost/http_proto/message_base.hpp>
16 : #include <boost/http_proto/response_view.hpp>
17 : #include <boost/http_proto/status.hpp>
18 :
19 : namespace boost {
20 : namespace http_proto {
21 :
22 : /** Container for HTTP responses
23 : */
24 : class BOOST_SYMBOL_VISIBLE
25 : response
26 : : public message_base
27 : {
28 : public:
29 : /** Constructor
30 : */
31 : BOOST_HTTP_PROTO_DECL
32 : response() noexcept;
33 :
34 : /** Constructor
35 : */
36 : BOOST_HTTP_PROTO_DECL
37 : explicit
38 : response(
39 : core::string_view s);
40 :
41 : /** Constructor
42 :
43 : Construct a response which allocates `size` bytes
44 : for storing the response header. The provided `size`
45 : will be aligned up as required by the implementation.
46 : This size will also be used as the limit for
47 : growing the header.
48 :
49 : <br/>
50 :
51 : This constructor is useful when an upper-bound size
52 : of the response is known ahead of time and we want
53 : to prevent reallocations.
54 :
55 : <br/>
56 :
57 : Passing an initial size of `0` does not throw and
58 : the maximum capacity is set to an
59 : implementation-defined limit.
60 :
61 : @param size Initial and final size, in bytes, of
62 : the backing allocation for the response's header.
63 : Any operation that attempts to grow the container
64 : beyond this size will throw `std::length_error`.
65 :
66 : @code
67 : boost::http_proto::response
68 : make_response(std::string_view server)
69 : {
70 : std::size_t size = 4096;
71 : boost::http_proto::response res(size);
72 : BOOST_ASSERT(
73 : res.max_capacity_in_bytes(), 4096);
74 :
75 : // uses spare capacity so that reallocations
76 : // are avoided
77 : res.append(
78 : boost::http_proto::field::server, server);
79 : res.append(
80 : boost::http_proto::field::connection, "close");
81 : return res;
82 : }
83 : @endcode
84 : */
85 : BOOST_HTTP_PROTO_DECL
86 : explicit
87 : response(
88 : std::size_t size);
89 :
90 : /** Constructor
91 :
92 : Constructs a response with an initial allocation of
93 : `size` bytes used for the response header. The
94 : container can regrow up until the limit `max_size`.
95 : `size` and `max_size` are aligned up as required by the
96 : implementation.
97 :
98 : <br/>
99 :
100 : This constructor is useful when there's a best-fit
101 : guess for an initial header size but we still wish
102 : to permit reallocating and growing the container to
103 : some upper limit.
104 :
105 : <br/>
106 :
107 : Passing an initial size of `0` does not throw.
108 :
109 : @param size Initial size, in bytes, of
110 : the backing allocation for the response's header.
111 :
112 : @param max_size Max size, in bytes, of the backing
113 : allocation for the response's header. Any operation
114 : that attempts to grow the container beyond this
115 : size will throw `std::length_error`.
116 :
117 : @throws std::length_error Thrown if `size > max_size`
118 :
119 : @code
120 : boost::http_proto::response
121 : make_response(std::string_view server)
122 : {
123 : std::size_t size = 4096;
124 : boost::http_proto::response res(size, 2 * size);
125 : BOOST_ASSERT(
126 : res.max_capacity_in_bytes(), 2 * 4096);
127 :
128 : // uses spare capacity so that reallocations
129 : // are avoided
130 : res.append(
131 : boost::http_proto::field::server, server);
132 : res.append(
133 : boost::http_proto::field::connection, "close");
134 : return res;
135 : }
136 : @endcode
137 : */
138 : BOOST_HTTP_PROTO_DECL
139 : response(
140 : std::size_t size,
141 : std::size_t max_size);
142 :
143 : /** Constructor
144 :
145 : The moved-from object will be
146 : left in the default-constructed
147 : state.
148 : */
149 : BOOST_HTTP_PROTO_DECL
150 : response(response&& other) noexcept;
151 :
152 : /** Constructor
153 : */
154 : BOOST_HTTP_PROTO_DECL
155 : response(response const& other);
156 :
157 : /** Constructor
158 : */
159 : BOOST_HTTP_PROTO_DECL
160 : response(
161 : response_view const& other);
162 :
163 : /** Assignment
164 : */
165 : BOOST_HTTP_PROTO_DECL
166 : response&
167 : operator=(
168 : response&& other) noexcept;
169 :
170 : /** Assignment
171 : */
172 : response&
173 3 : operator=(
174 : response const& other)
175 : {
176 3 : copy_impl(*other.ph_);
177 3 : return *this;
178 : }
179 :
180 : /** Assignment
181 : */
182 : response&
183 1 : operator=(
184 : response_view const& other)
185 : {
186 1 : copy_impl(*other.ph_);
187 1 : return *this;
188 : }
189 :
190 : /** Constructor
191 : */
192 : BOOST_HTTP_PROTO_DECL
193 : response(
194 : http_proto::status sc,
195 : http_proto::version v);
196 :
197 : /** Constructor
198 : *
199 : * The start-line of the response will contain the standard
200 : * text for the supplied status code and the HTTP version
201 : * will be defaulted to 1.1.
202 : */
203 : BOOST_HTTP_PROTO_DECL
204 : explicit
205 : response(
206 : http_proto::status sc);
207 :
208 : /** Return a read-only view to the response
209 : */
210 5 : operator
211 : response_view() const noexcept
212 : {
213 5 : return response_view(ph_);
214 : }
215 :
216 : //--------------------------------------------
217 : //
218 : // Observers
219 : //
220 : //--------------------------------------------
221 :
222 : /** Return the reason string
223 :
224 : This field is obsolete in HTTP/1
225 : and should only be used for display
226 : purposes.
227 : */
228 : core::string_view
229 28 : reason() const noexcept
230 : {
231 56 : return core::string_view(
232 28 : ph_->cbuf + 13,
233 28 : ph_->prefix - 15);
234 : }
235 :
236 : /** Return the status code
237 : */
238 : http_proto::status
239 28 : status() const noexcept
240 : {
241 28 : return ph_->res.status;
242 : }
243 :
244 : /** Return the status code
245 : */
246 : unsigned short
247 28 : status_int() const noexcept
248 : {
249 28 : return ph_->res.status_int;
250 : }
251 :
252 : /** Return the HTTP version
253 : */
254 : http_proto::version
255 28 : version() const noexcept
256 : {
257 28 : return ph_->version;
258 : }
259 :
260 : //--------------------------------------------
261 : //
262 : // Modifiers
263 : //
264 : //--------------------------------------------
265 :
266 : /** Set the version, status code of the response
267 :
268 : The reason phrase will be set to the
269 : standard text for the specified status
270 : code.
271 :
272 : @par sc The status code. This must not be
273 : @ref http_proto::status::unknown.
274 :
275 : @par v The HTTP-version.
276 : */
277 : void
278 13 : set_start_line(
279 : http_proto::status sc,
280 : http_proto::version v =
281 : http_proto::version::http_1_1)
282 : {
283 13 : set_impl(
284 : sc,
285 : static_cast<
286 : unsigned short>(sc),
287 : obsolete_reason(sc),
288 : v);
289 13 : }
290 :
291 : void
292 6 : set_start_line(
293 : unsigned short si,
294 : core::string_view reason,
295 : http_proto::version v)
296 : {
297 6 : set_impl(
298 : int_to_status(si),
299 : si,
300 : reason,
301 : v);
302 6 : }
303 :
304 : /** Swap this with another instance
305 : */
306 : void
307 6 : swap(response& other) noexcept
308 : {
309 6 : h_.swap(other.h_);
310 6 : }
311 :
312 : /** Swap two instances
313 : */
314 : // hidden friend
315 : friend
316 : void
317 : swap(
318 : response& t0,
319 : response& t1) noexcept
320 : {
321 : t0.swap(t1);
322 : }
323 :
324 : private:
325 : BOOST_HTTP_PROTO_DECL
326 : void
327 : set_impl(
328 : http_proto::status sc,
329 : unsigned short si,
330 : core::string_view reason,
331 : http_proto::version v);
332 : };
333 :
334 : } // http_proto
335 : } // boost
336 :
337 : #endif
|