]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/include/beast/http/message.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / http / message.hpp
1 //
2 // Copyright (c) 2013-2017 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
8 #ifndef BEAST_HTTP_MESSAGE_HPP
9 #define BEAST_HTTP_MESSAGE_HPP
10
11 #include <beast/config.hpp>
12 #include <beast/http/fields.hpp>
13 #include <beast/core/detail/integer_sequence.hpp>
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <utility>
18
19 namespace beast {
20 namespace http {
21
22 #if BEAST_DOXYGEN
23 /** A container for a HTTP request or response header.
24
25 A header includes the Start Line and Fields.
26
27 Some use-cases:
28
29 @li When the message has no body, such as a response to a HEAD request.
30
31 @li When the caller wishes to defer instantiation of the body.
32
33 @li Invoke algorithms which operate on the header only.
34 */
35 template<bool isRequest, class Fields>
36 struct header
37
38 #else
39 template<bool isRequest, class Fields>
40 struct header;
41
42 template<class Fields>
43 struct header<true, Fields>
44 #endif
45 {
46 /// Indicates if the header is a request or response.
47 #if BEAST_DOXYGEN
48 static bool constexpr is_request = isRequest;
49
50 #else
51 static bool constexpr is_request = true;
52 #endif
53
54 /// The type representing the fields.
55 using fields_type = Fields;
56
57 /** The HTTP version.
58
59 This holds both the major and minor version numbers,
60 using these formulas:
61 @code
62 major = version / 10;
63 minor = version % 10;
64 @endcode
65 */
66 int version;
67
68 /** The Request Method
69
70 @note This field is present only if `isRequest == true`.
71 */
72 std::string method;
73
74 /** The Request URI
75
76 @note This field is present only if `isRequest == true`.
77 */
78 std::string url;
79
80 /// The HTTP field values.
81 fields_type fields;
82
83 /// Default constructor
84 header() = default;
85
86 /// Move constructor
87 header(header&&) = default;
88
89 /// Copy constructor
90 header(header const&) = default;
91
92 /// Move assignment
93 header& operator=(header&&) = default;
94
95 /// Copy assignment
96 header& operator=(header const&) = default;
97
98 /** Construct the header.
99
100 All arguments are forwarded to the constructor
101 of the `fields` member.
102
103 @note This constructor participates in overload resolution
104 if and only if the first parameter is not convertible to
105 `header`.
106 */
107 #if BEAST_DOXYGEN
108 template<class... Args>
109 explicit
110 header(Args&&... args);
111
112 #else
113 template<class Arg1, class... ArgN,
114 class = typename std::enable_if<
115 (sizeof...(ArgN) > 0) || ! std::is_convertible<
116 typename std::decay<Arg1>::type,
117 header>::value>::type>
118 explicit
119 header(Arg1&& arg1, ArgN&&... argn)
120 : fields(std::forward<Arg1>(arg1),
121 std::forward<ArgN>(argn)...)
122 {
123 }
124 };
125
126 /** A container for a HTTP request or response header.
127
128 A header includes the Start Line and Fields.
129
130 Some use-cases:
131
132 @li When the message has no body, such as a response to a HEAD request.
133
134 @li When the caller wishes to defer instantiation of the body.
135
136 @li Invoke algorithms which operate on the header only.
137 */
138 template<class Fields>
139 struct header<false, Fields>
140 {
141 /// Indicates if the header is a request or response.
142 static bool constexpr is_request = false;
143
144 /// The type representing the fields.
145 using fields_type = Fields;
146
147 /** The HTTP version.
148
149 This holds both the major and minor version numbers,
150 using these formulas:
151 @code
152 major = version / 10;
153 minor = version % 10;
154 @endcode
155 */
156 int version;
157
158 /// The HTTP field values.
159 fields_type fields;
160
161 /// Default constructor
162 header() = default;
163
164 /// Move constructor
165 header(header&&) = default;
166
167 /// Copy constructor
168 header(header const&) = default;
169
170 /// Move assignment
171 header& operator=(header&&) = default;
172
173 /// Copy assignment
174 header& operator=(header const&) = default;
175
176 /** Construct the header.
177
178 All arguments are forwarded to the constructor
179 of the `fields` member.
180
181 @note This constructor participates in overload resolution
182 if and only if the first parameter is not convertible to
183 `header`.
184 */
185 template<class Arg1, class... ArgN,
186 class = typename std::enable_if<
187 (sizeof...(ArgN) > 0) || ! std::is_convertible<
188 typename std::decay<Arg1>::type,
189 header>::value>::type>
190 explicit
191 header(Arg1&& arg1, ArgN&&... argn)
192 : fields(std::forward<Arg1>(arg1),
193 std::forward<ArgN>(argn)...)
194 {
195 }
196 #endif
197
198 /** The Response Status-Code.
199
200 @note This field is present only if `isRequest == false`.
201 */
202 int status;
203
204 /** The Response Reason-Phrase.
205
206 The Reason-Phrase is obsolete as of rfc7230.
207
208 @note This field is present only if `isRequest == false`.
209 */
210 std::string reason;
211 };
212
213 /** A container for a complete HTTP message.
214
215 A message can be a request or response, depending on the
216 `isRequest` template argument value. Requests and responses
217 have different types; functions may be overloaded based on
218 the type if desired.
219
220 The `Body` template argument type determines the model used
221 to read or write the content body of the message.
222
223 @tparam isRequest `true` if this represents a request,
224 or `false` if this represents a response. Some class data
225 members are conditionally present depending on this value.
226
227 @tparam Body A type meeting the requirements of Body.
228
229 @tparam Fields The type of container used to hold the
230 field value pairs.
231 */
232 template<bool isRequest, class Body, class Fields>
233 struct message : header<isRequest, Fields>
234 {
235 /// The base class used to hold the header portion of the message.
236 using base_type = header<isRequest, Fields>;
237
238 /** The type providing the body traits.
239
240 The @ref message::body member will be of type `body_type::value_type`.
241 */
242 using body_type = Body;
243
244 /// A value representing the body.
245 typename Body::value_type body;
246
247 /// Default constructor
248 message() = default;
249
250 /// Move constructor
251 message(message&&) = default;
252
253 /// Copy constructor
254 message(message const&) = default;
255
256 /// Move assignment
257 message& operator=(message&&) = default;
258
259 /// Copy assignment
260 message& operator=(message const&) = default;
261
262 /** Construct a message from a header.
263
264 Additional arguments, if any, are forwarded to
265 the constructor of the body member.
266 */
267 template<class... Args>
268 explicit
269 message(base_type&& base, Args&&... args)
270 : base_type(std::move(base))
271 , body(std::forward<Args>(args)...)
272 {
273 }
274
275 /** Construct a message from a header.
276
277 Additional arguments, if any, are forwarded to
278 the constructor of the body member.
279 */
280 template<class... Args>
281 explicit
282 message(base_type const& base, Args&&... args)
283 : base_type(base)
284 , body(std::forward<Args>(args)...)
285 {
286 }
287
288 /** Construct a message.
289
290 @param u An argument forwarded to the body constructor.
291
292 @note This constructor participates in overload resolution
293 only if `u` is not convertible to `base_type`.
294 */
295 template<class U
296 #if ! BEAST_DOXYGEN
297 , class = typename std::enable_if<
298 ! std::is_convertible<typename
299 std::decay<U>::type, base_type>::value>::type
300 #endif
301 >
302 explicit
303 message(U&& u)
304 : body(std::forward<U>(u))
305 {
306 }
307
308 /** Construct a message.
309
310 @param u An argument forwarded to the body constructor.
311
312 @param v An argument forwarded to the fields constructor.
313
314 @note This constructor participates in overload resolution
315 only if `u` is not convertible to `base_type`.
316 */
317 template<class U, class V
318 #if ! BEAST_DOXYGEN
319 ,class = typename std::enable_if<! std::is_convertible<
320 typename std::decay<U>::type, base_type>::value>::type
321 #endif
322 >
323 message(U&& u, V&& v)
324 : base_type(std::forward<V>(v))
325 , body(std::forward<U>(u))
326 {
327 }
328
329 /** Construct a message.
330
331 @param un A tuple forwarded as a parameter pack to the body constructor.
332 */
333 template<class... Un>
334 message(std::piecewise_construct_t, std::tuple<Un...> un)
335 : message(std::piecewise_construct, un,
336 beast::detail::make_index_sequence<sizeof...(Un)>{})
337 {
338 }
339
340 /** Construct a message.
341
342 @param un A tuple forwarded as a parameter pack to the body constructor.
343
344 @param vn A tuple forwarded as a parameter pack to the fields constructor.
345 */
346 template<class... Un, class... Vn>
347 message(std::piecewise_construct_t,
348 std::tuple<Un...>&& un, std::tuple<Vn...>&& vn)
349 : message(std::piecewise_construct, un, vn,
350 beast::detail::make_index_sequence<sizeof...(Un)>{},
351 beast::detail::make_index_sequence<sizeof...(Vn)>{})
352 {
353 }
354
355 /// Returns the header portion of the message
356 base_type&
357 base()
358 {
359 return *this;
360 }
361
362 /// Returns the header portion of the message
363 base_type const&
364 base() const
365 {
366 return *this;
367 }
368
369 private:
370 template<class... Un, size_t... IUn>
371 message(std::piecewise_construct_t,
372 std::tuple<Un...>& tu, beast::detail::index_sequence<IUn...>)
373 : body(std::forward<Un>(std::get<IUn>(tu))...)
374 {
375 }
376
377 template<class... Un, class... Vn,
378 std::size_t... IUn, std::size_t... IVn>
379 message(std::piecewise_construct_t,
380 std::tuple<Un...>& tu, std::tuple<Vn...>& tv,
381 beast::detail::index_sequence<IUn...>,
382 beast::detail::index_sequence<IVn...>)
383 : base_type(std::forward<Vn>(std::get<IVn>(tv))...)
384 , body(std::forward<Un>(std::get<IUn>(tu))...)
385 {
386 }
387 };
388
389 //------------------------------------------------------------------------------
390
391 #if BEAST_DOXYGEN
392 /** Swap two header objects.
393
394 @par Requirements
395 `Fields` is @b Swappable.
396 */
397 template<bool isRequest, class Fields>
398 void
399 swap(
400 header<isRequest, Fields>& m1,
401 header<isRequest, Fields>& m2);
402 #endif
403
404 /** Swap two message objects.
405
406 @par Requirements:
407 `Body::value_type` and `Fields` are @b Swappable.
408 */
409 template<bool isRequest, class Body, class Fields>
410 void
411 swap(
412 message<isRequest, Body, Fields>& m1,
413 message<isRequest, Body, Fields>& m2);
414
415 /// A typical HTTP request header
416 using request_header = header<true, fields>;
417
418 /// Typical HTTP response header
419 using response_header = header<false, fields>;
420
421 /// A typical HTTP request
422 template<class Body, class Fields = fields>
423 using request = message<true, Body, Fields>;
424
425 /// A typical HTTP response
426 template<class Body, class Fields = fields>
427 using response = message<false, Body, Fields>;
428
429 //------------------------------------------------------------------------------
430
431 /** Returns `true` if the HTTP/1 message indicates a keep alive.
432
433 Undefined behavior if version is greater than 11.
434 */
435 template<bool isRequest, class Fields>
436 bool
437 is_keep_alive(header<isRequest, Fields> const& msg);
438
439 /** Returns `true` if the HTTP/1 message indicates an Upgrade request or response.
440
441 Undefined behavior if version is greater than 11.
442 */
443 template<bool isRequest, class Fields>
444 bool
445 is_upgrade(header<isRequest, Fields> const& msg);
446
447 /** HTTP/1 connection prepare options.
448
449 @note These values are used with @ref prepare.
450 */
451 enum class connection
452 {
453 /// Specify Connection: close.
454 close,
455
456 /// Specify Connection: keep-alive where possible.
457 keep_alive,
458
459 /// Specify Connection: upgrade.
460 upgrade
461 };
462
463 /** Prepare a HTTP message.
464
465 This function will adjust the Content-Length, Transfer-Encoding,
466 and Connection fields of the message based on the properties of
467 the body and the options passed in.
468
469 @param msg The message to prepare. The fields may be modified.
470
471 @param options A list of prepare options.
472 */
473 template<
474 bool isRequest, class Body, class Fields,
475 class... Options>
476 void
477 prepare(message<isRequest, Body, Fields>& msg,
478 Options&&... options);
479
480 } // http
481 } // beast
482
483 #include <beast/http/impl/message.ipp>
484
485 #endif