1//
2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
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#include <boost/beast/core/buffer_traits.hpp>
11#include <boost/beast/core/error.hpp>
12#include <boost/beast/core/file_base.hpp>
13#include <boost/beast/http/message.hpp>
14#include <boost/beast/http/type_traits.hpp>
15#include <boost/optional.hpp>
16#include <cstdint>
17#include <utility>
18
19namespace boost {
20namespace beast {
21namespace http {
22
23class BodyWriter;
24class BodyReader;
25
26//[concept_Body
27
28struct Body
29{
30 // The type of message::body when used
31 struct value_type;
32
33 /// The algorithm used during parsing
34 class reader;
35
36 /// The algorithm used during serialization
37 class writer;
38
39 /// Returns the body's payload size
40 static
41 std::uint64_t
42 size(value_type const& body);
43};
44
45static_assert(is_body<Body>::value, "");
46
47//]
48
49struct Body_BodyWriter {
50 struct value_type{};
51//[concept_BodyWriter
52
53struct BodyWriter
54{
55public:
56 /// The type of buffer returned by `get`.
57 using const_buffers_type = net::const_buffer;
58
59 /** Construct the writer.
60
61 @param h The header for the message being serialized
62
63 @param body The body being serialized
64 */
65 template<bool isRequest, class Fields>
66 BodyWriter(header<isRequest, Fields> const& h, value_type const& body);
67
68 /** Initialize the writer.
69
70 This is called after construction and before the first
71 call to `get`. The message is valid and complete upon
72 entry.
73
74 @param ec Set to the error, if any occurred.
75 */
76 void
77 init(error_code& ec)
78 {
79 // The specification requires this to indicate "no error"
80 ec = {};
81 }
82
83 /** Returns the next buffer in the body.
84
85 @li If the return value is `boost::none` (unseated optional) and
86 `ec` does not contain an error, this indicates the end of the
87 body, no more buffers are present.
88
89 @li If the optional contains a value, the first element of the
90 pair represents a <em>ConstBufferSequence</em> containing one or
91 more octets of the body data. The second element indicates
92 whether or not there are additional octets of body data.
93 A value of `true` means there is more data, and that the
94 implementation will perform a subsequent call to `get`.
95 A value of `false` means there is no more body data.
96
97 @li If `ec` contains an error code, the return value is ignored.
98
99 @param ec Set to the error, if any occurred.
100 */
101 boost::optional<std::pair<const_buffers_type, bool>>
102 get(error_code& ec)
103 {
104 // The specification requires this to indicate "no error"
105 ec = {};
106
107 return boost::none; // for exposition only
108 }
109};
110
111//]
112 using writer = BodyWriter;
113};
114
115static_assert(is_body_writer<Body_BodyWriter>::value, "");
116
117struct Body_BodyReader {
118 struct value_type{};
119//[concept_BodyReader
120
121struct BodyReader
122{
123 /** Construct the reader.
124
125 @param h The header for the message being parsed
126
127 @param body The body to store the parsed results into
128 */
129 template<bool isRequest, class Fields>
130 BodyReader(header<isRequest, Fields>& h, value_type& body);
131
132 /** Initialize the reader.
133
134 This is called after construction and before the first
135 call to `put`. The message is valid and complete upon
136 entry.
137
138 @param ec Set to the error, if any occurred.
139 */
140 void
141 init(
142 boost::optional<std::uint64_t> const& content_length,
143 error_code& ec)
144 {
145 boost::ignore_unused(content_length);
146
147 // The specification requires this to indicate "no error"
148 ec = {};
149 }
150
151 /** Store buffers.
152
153 This is called zero or more times with parsed body octets.
154
155 @param buffers The constant buffer sequence to store.
156
157 @param ec Set to the error, if any occurred.
158
159 @return The number of bytes transferred from the input buffers.
160 */
161 template<class ConstBufferSequence>
162 std::size_t
163 put(ConstBufferSequence const& buffers, error_code& ec)
164 {
165 // The specification requires this to indicate "no error"
166 ec = {};
167
168 return buffer_bytes(buffers);
169 }
170
171 /** Called when the body is complete.
172
173 @param ec Set to the error, if any occurred.
174 */
175 void
176 finish(error_code& ec)
177 {
178 // The specification requires this to indicate "no error"
179 ec = {};
180 }
181};
182
183//]
184 using reader = BodyReader;
185};
186
187static_assert(is_body_reader<Body_BodyReader>::value, "");
188
189//[concept_Fields
190
191class Fields
192{
193public:
194 /// Constructed as needed when fields are serialized
195 struct writer;
196
197protected:
198 /** Returns the request-method string.
199
200 @note Only called for requests.
201 */
202 string_view
203 get_method_impl() const;
204
205 /** Returns the request-target string.
206
207 @note Only called for requests.
208 */
209 string_view
210 get_target_impl() const;
211
212 /** Returns the response reason-phrase string.
213
214 @note Only called for responses.
215 */
216 string_view
217 get_reason_impl() const;
218
219 /** Returns the chunked Transfer-Encoding setting
220 */
221 bool
222 get_chunked_impl() const;
223
224 /** Returns the keep-alive setting
225 */
226 bool
227 get_keep_alive_impl(unsigned version) const;
228
229 /** Returns `true` if the Content-Length field is present.
230 */
231 bool
232 has_content_length_impl() const;
233
234 /** Set or clear the method string.
235
236 @note Only called for requests.
237 */
238 void
239 set_method_impl(string_view s);
240
241 /** Set or clear the target string.
242
243 @note Only called for requests.
244 */
245 void
246 set_target_impl(string_view s);
247
248 /** Set or clear the reason string.
249
250 @note Only called for responses.
251 */
252 void
253 set_reason_impl(string_view s);
254
255 /** Sets or clears the chunked Transfer-Encoding value
256 */
257 void
258 set_chunked_impl(bool value);
259
260 /** Sets or clears the Content-Length field
261 */
262 void
263 set_content_length_impl(boost::optional<std::uint64_t>);
264
265 /** Adjusts the Connection field
266 */
267 void
268 set_keep_alive_impl(unsigned version, bool keep_alive);
269};
270
271static_assert(is_fields<Fields>::value,
272 "Fields type requirements not met");
273
274//]
275
276struct Fields_FieldsWriter {
277 using Fields = Fields_FieldsWriter;
278//[concept_FieldsWriter
279
280struct FieldsWriter
281{
282 // The type of buffers returned by `get`
283 struct const_buffers_type;
284
285 // Constructor for requests
286 FieldsWriter(Fields const& f, unsigned version, verb method);
287
288 // Constructor for responses
289 FieldsWriter(Fields const& f, unsigned version, unsigned status);
290
291 // Returns the serialized header buffers
292 const_buffers_type
293 get();
294};
295
296//]
297};
298
299//[concept_File
300
301struct File
302{
303 /** Default constructor
304
305 There is no open file initially.
306 */
307 File();
308
309 /** Destructor
310
311 If the file is open it is first closed.
312 */
313 ~File();
314
315 /// Returns `true` if the file is open
316 bool
317 is_open() const;
318
319 /// Close the file if open
320 void
321 close(error_code& ec);
322
323 /// Open a file at the given path with the specified mode
324 void
325 open(char const* path, file_mode mode, error_code& ec);
326
327 /// Return the size of the open file
328 std::uint64_t
329 size(error_code& ec) const;
330
331 /// Return the current position in the open file
332 std::uint64_t
333 pos(error_code& ec) const;
334
335 /// Adjust the current position in the open file
336 void
337 seek(std::uint64_t offset, error_code& ec);
338
339 /// Read from the open file
340 std::size_t
341 read(void* buffer, std::size_t n, error_code& ec) const;
342
343 /// Write to the open file
344 std::size_t
345 write(void const* buffer, std::size_t n, error_code& ec);
346};
347
348//]
349
350} // http
351} // beast
352} // boost
353

source code of boost/libs/beast/test/doc/exemplars.cpp