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