]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/http/serializer.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / beast / http / serializer.hpp
CommitLineData
b32b8144 1//
92f5a8d4 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
b32b8144
FG
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/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_HTTP_SERIALIZER_HPP
11#define BOOST_BEAST_HTTP_SERIALIZER_HPP
12
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/beast/core/buffers_cat.hpp>
15#include <boost/beast/core/buffers_prefix.hpp>
16#include <boost/beast/core/buffers_suffix.hpp>
17#include <boost/beast/core/string.hpp>
b32b8144
FG
18#include <boost/beast/core/detail/variant.hpp>
19#include <boost/beast/http/message.hpp>
20#include <boost/beast/http/chunk_encode.hpp>
21#include <boost/asio/buffer.hpp>
22#include <boost/optional.hpp>
23
24namespace boost {
25namespace beast {
26namespace http {
27
28/** Provides buffer oriented HTTP message serialization functionality.
29
30 An object of this type is used to serialize a complete
31 HTTP message into a sequence of octets. To use this class,
32 construct an instance with the message to be serialized.
33 The implementation will automatically perform chunk encoding
34 if the contents of the message indicate that chunk encoding
35 is required.
36
37 Chunked output produced by the serializer never contains chunk
38 extensions or trailers, and the location of chunk boundaries
39 is not specified. If callers require chunk extensions, trailers,
40 or control over the exact contents of each chunk they should
41 use the serializer to write just the message header, and then
42 assume control over serializing the chunked payload by using
43 the chunk buffer sequence types @ref chunk_body, @ref chunk_crlf,
44 @ref chunk_header, and @ref chunk_last.
45
46 @tparam isRequest `true` if the message is a request.
47
48 @tparam Body The body type of the message.
49
50 @tparam Fields The type of fields in the message.
51*/
52template<
53 bool isRequest,
54 class Body,
55 class Fields = fields>
56class serializer
57{
58public:
59 static_assert(is_body<Body>::value,
92f5a8d4 60 "Body type requirements not met");
b32b8144
FG
61
62 static_assert(is_body_writer<Body>::value,
92f5a8d4 63 "BodyWriter type requirements not met");
b32b8144
FG
64
65 /** The type of message this serializer uses
66
67 This may be const or non-const depending on the
92f5a8d4 68 implementation of the corresponding <em>BodyWriter</em>.
b32b8144
FG
69 */
70#if BOOST_BEAST_DOXYGEN
92f5a8d4 71 using value_type = __implementation_defined__;
b32b8144 72#else
11fdf7f2 73 using value_type = typename std::conditional<
92f5a8d4 74 std::is_constructible<typename Body::writer,
11fdf7f2
TL
75 header<isRequest, Fields>&,
76 typename Body::value_type&>::value &&
77 ! std::is_constructible<typename Body::writer,
78 header<isRequest, Fields> const&,
92f5a8d4 79 typename Body::value_type const&>::value,
11fdf7f2
TL
80 message<isRequest, Body, Fields>,
81 message<isRequest, Body, Fields> const>::type;
b32b8144
FG
82#endif
83
84private:
85 enum
86 {
87 do_construct = 0,
88
89 do_init = 10,
90 do_header_only = 20,
91 do_header = 30,
92 do_body = 40,
93
94 do_init_c = 50,
95 do_header_only_c = 60,
96 do_header_c = 70,
97 do_body_c = 80,
98 do_final_c = 90,
99 #ifndef BOOST_BEAST_NO_BIG_VARIANTS
100 do_body_final_c = 100,
101 do_all_c = 110,
102 #endif
103
104 do_complete = 120
105 };
106
11fdf7f2
TL
107 void fwrinit(std::true_type);
108 void fwrinit(std::false_type);
b32b8144
FG
109
110 template<std::size_t, class Visit>
111 void
112 do_visit(error_code& ec, Visit& visit);
113
114 using writer = typename Body::writer;
115
116 using cb1_t = buffers_suffix<typename
117 Fields::writer::const_buffers_type>; // header
118 using pcb1_t = buffers_prefix_view<cb1_t const&>;
119
120 using cb2_t = buffers_suffix<buffers_cat_view<
121 typename Fields::writer::const_buffers_type,// header
122 typename writer::const_buffers_type>>; // body
123 using pcb2_t = buffers_prefix_view<cb2_t const&>;
124
125 using cb3_t = buffers_suffix<
126 typename writer::const_buffers_type>; // body
127 using pcb3_t = buffers_prefix_view<cb3_t const&>;
128
129 using cb4_t = buffers_suffix<buffers_cat_view<
130 typename Fields::writer::const_buffers_type,// header
131 detail::chunk_size, // chunk-size
92f5a8d4 132 net::const_buffer, // chunk-ext
b32b8144
FG
133 chunk_crlf, // crlf
134 typename writer::const_buffers_type, // body
135 chunk_crlf>>; // crlf
136 using pcb4_t = buffers_prefix_view<cb4_t const&>;
137
138 using cb5_t = buffers_suffix<buffers_cat_view<
139 detail::chunk_size, // chunk-header
92f5a8d4 140 net::const_buffer, // chunk-ext
b32b8144
FG
141 chunk_crlf, // crlf
142 typename writer::const_buffers_type, // body
143 chunk_crlf>>; // crlf
144 using pcb5_t = buffers_prefix_view<cb5_t const&>;
145
146 using cb6_t = buffers_suffix<buffers_cat_view<
147 detail::chunk_size, // chunk-header
92f5a8d4 148 net::const_buffer, // chunk-size
b32b8144
FG
149 chunk_crlf, // crlf
150 typename writer::const_buffers_type, // body
151 chunk_crlf, // crlf
92f5a8d4
TL
152 net::const_buffer, // chunk-final
153 net::const_buffer, // trailers
b32b8144
FG
154 chunk_crlf>>; // crlf
155 using pcb6_t = buffers_prefix_view<cb6_t const&>;
156
157 using cb7_t = buffers_suffix<buffers_cat_view<
158 typename Fields::writer::const_buffers_type,// header
159 detail::chunk_size, // chunk-size
92f5a8d4 160 net::const_buffer, // chunk-ext
b32b8144
FG
161 chunk_crlf, // crlf
162 typename writer::const_buffers_type, // body
163 chunk_crlf, // crlf
92f5a8d4
TL
164 net::const_buffer, // chunk-final
165 net::const_buffer, // trailers
b32b8144
FG
166 chunk_crlf>>; // crlf
167 using pcb7_t = buffers_prefix_view<cb7_t const&>;
168
169 using cb8_t = buffers_suffix<buffers_cat_view<
92f5a8d4
TL
170 net::const_buffer, // chunk-final
171 net::const_buffer, // trailers
b32b8144
FG
172 chunk_crlf>>; // crlf
173 using pcb8_t = buffers_prefix_view<cb8_t const&>;
174
175 value_type& m_;
11fdf7f2
TL
176 writer wr_;
177 boost::optional<typename Fields::writer> fwr_;
b32b8144
FG
178 beast::detail::variant<
179 cb1_t, cb2_t, cb3_t, cb4_t,
180 cb5_t ,cb6_t, cb7_t, cb8_t> v_;
181 beast::detail::variant<
182 pcb1_t, pcb2_t, pcb3_t, pcb4_t,
183 pcb5_t ,pcb6_t, pcb7_t, pcb8_t> pv_;
184 std::size_t limit_ =
185 (std::numeric_limits<std::size_t>::max)();
186 int s_ = do_construct;
187 bool split_ = false;
188 bool header_done_ = false;
92f5a8d4 189 bool more_ = false;
b32b8144
FG
190
191public:
192 /// Constructor
193 serializer(serializer&&) = default;
194
195 /// Constructor
196 serializer(serializer const&) = default;
197
198 /// Assignment
199 serializer& operator=(serializer const&) = delete;
200
201 /** Constructor
202
203 The implementation guarantees that the message passed on
204 construction will not be accessed until the first call to
205 @ref next. This allows the message to be lazily created.
206 For example, if the header is filled in before serialization.
207
208 @param msg A reference to the message to serialize, which must
209 remain valid for the lifetime of the serializer. Depending on
210 the type of Body used, this may or may not be a `const` reference.
211
212 @note This function participates in overload resolution only if
213 Body::writer is constructible from a `const` message reference.
214 */
215 explicit
216 serializer(value_type& msg);
217
218 /// Returns the message being serialized
219 value_type&
220 get()
221 {
222 return m_;
223 }
224
225 /// Returns the serialized buffer size limit
226 std::size_t
227 limit()
228 {
229 return limit_;
230 }
231
232 /** Set the serialized buffer size limit
233
234 This function adjusts the limit on the maximum size of the
235 buffers passed to the visitor. The new size limit takes effect
236 in the following call to @ref next.
237
238 The default is no buffer size limit.
239
240 @param limit The new buffer size limit. If this number
241 is zero, the size limit is removed.
242 */
243 void
244 limit(std::size_t limit)
245 {
246 limit_ = limit > 0 ? limit :
247 (std::numeric_limits<std::size_t>::max)();
248 }
249
250 /** Returns `true` if we will pause after writing the complete header.
251 */
252 bool
253 split()
254 {
255 return split_;
256 }
257
258 /** Set whether the header and body are written separately.
259
260 When the split feature is enabled, the implementation will
261 write only the octets corresponding to the serialized header
262 first. If the header has already been written, this function
263 will have no effect on output.
264 */
265 void
266 split(bool v)
267 {
268 split_ = v;
269 }
270
271 /** Return `true` if serialization of the header is complete.
272
273 This function indicates whether or not all buffers containing
274 serialized header octets have been retrieved.
275 */
276 bool
277 is_header_done()
278 {
279 return header_done_;
280 }
281
282 /** Return `true` if serialization is complete.
283
284 The operation is complete when all octets corresponding
285 to the serialized representation of the message have been
286 successfully retrieved.
287 */
288 bool
289 is_done()
290 {
291 return s_ == do_complete;
292 }
293
294 /** Returns the next set of buffers in the serialization.
295
296 This function will attempt to call the `visit` function
92f5a8d4 297 object with a <em>ConstBufferSequence</em> of unspecified type
b32b8144
FG
298 representing the next set of buffers in the serialization
299 of the message represented by this object.
300
301 If there are no more buffers in the serialization, the
302 visit function will not be called. In this case, no error
303 will be indicated, and the function @ref is_done will
304 return `true`.
305
306 @param ec Set to the error, if any occurred.
307
308 @param visit The function to call. The equivalent function
309 signature of this object must be:
310 @code
311 template<class ConstBufferSequence>
312 void visit(error_code&, ConstBufferSequence const&);
313 @endcode
314 The function is not copied, if no error occurs it will be
315 invoked before the call to @ref next returns.
316
317 */
318 template<class Visit>
319 void
320 next(error_code& ec, Visit&& visit);
321
322 /** Consume buffer octets in the serialization.
323
324 This function should be called after one or more octets
325 contained in the buffers provided in the prior call
326 to @ref next have been used.
327
328 After a call to @ref consume, callers should check the
329 return value of @ref is_done to determine if the entire
330 message has been serialized.
331
332 @param n The number of octets to consume. This number must
333 be greater than zero and no greater than the number of
334 octets in the buffers provided in the prior call to @ref next.
335 */
336 void
337 consume(std::size_t n);
338
92f5a8d4 339 /** Provides low-level access to the associated <em>BodyWriter</em>
11fdf7f2
TL
340
341 This function provides access to the instance of the writer
342 associated with the body and created by the serializer
343 upon construction. The behavior of accessing this object
344 is defined by the specification of the particular writer
345 and its associated body.
346
347 @return A reference to the writer.
348 */
349 writer&
350 writer_impl()
351 {
352 return wr_;
b32b8144
FG
353 }
354};
355
356/// A serializer for HTTP/1 requests
357template<class Body, class Fields = fields>
358using request_serializer = serializer<true, Body, Fields>;
359
360/// A serializer for HTTP/1 responses
361template<class Body, class Fields = fields>
362using response_serializer = serializer<false, Body, Fields>;
363
364} // http
365} // beast
366} // boost
367
92f5a8d4 368#include <boost/beast/http/impl/serializer.hpp>
b32b8144
FG
369
370#endif