2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
8 #ifndef BEAST_HTTP_MESSAGE_HPP
9 #define BEAST_HTTP_MESSAGE_HPP
11 #include <beast/config.hpp>
12 #include <beast/http/fields.hpp>
13 #include <beast/core/detail/integer_sequence.hpp>
23 /** A container for a HTTP request or response header.
25 A header includes the Start Line and Fields.
29 @li When the message has no body, such as a response to a HEAD request.
31 @li When the caller wishes to defer instantiation of the body.
33 @li Invoke algorithms which operate on the header only.
35 template<bool isRequest, class Fields>
39 template<bool isRequest, class Fields>
42 template<class Fields>
43 struct header<true, Fields>
46 /// Indicates if the header is a request or response.
48 static bool constexpr is_request = isRequest;
51 static bool constexpr is_request = true;
54 /// The type representing the fields.
55 using fields_type = Fields;
59 This holds both the major and minor version numbers,
68 /** The Request Method
70 @note This field is present only if `isRequest == true`.
76 @note This field is present only if `isRequest == true`.
80 /// The HTTP field values.
83 /// Default constructor
87 header(header&&) = default;
90 header(header const&) = default;
93 header& operator=(header&&) = default;
96 header& operator=(header const&) = default;
98 /** Construct the header.
100 All arguments are forwarded to the constructor
101 of the `fields` member.
103 @note This constructor participates in overload resolution
104 if and only if the first parameter is not convertible to
108 template<class... Args>
110 header(Args&&... args);
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>
119 header(Arg1&& arg1, ArgN&&... argn)
120 : fields(std::forward<Arg1>(arg1),
121 std::forward<ArgN>(argn)...)
126 /** A container for a HTTP request or response header.
128 A header includes the Start Line and Fields.
132 @li When the message has no body, such as a response to a HEAD request.
134 @li When the caller wishes to defer instantiation of the body.
136 @li Invoke algorithms which operate on the header only.
138 template<class Fields>
139 struct header<false, Fields>
141 /// Indicates if the header is a request or response.
142 static bool constexpr is_request = false;
144 /// The type representing the fields.
145 using fields_type = Fields;
147 /** The HTTP version.
149 This holds both the major and minor version numbers,
150 using these formulas:
152 major = version / 10;
153 minor = version % 10;
158 /// The HTTP field values.
161 /// Default constructor
165 header(header&&) = default;
168 header(header const&) = default;
171 header& operator=(header&&) = default;
174 header& operator=(header const&) = default;
176 /** Construct the header.
178 All arguments are forwarded to the constructor
179 of the `fields` member.
181 @note This constructor participates in overload resolution
182 if and only if the first parameter is not convertible to
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>
191 header(Arg1&& arg1, ArgN&&... argn)
192 : fields(std::forward<Arg1>(arg1),
193 std::forward<ArgN>(argn)...)
198 /** The Response Status-Code.
200 @note This field is present only if `isRequest == false`.
204 /** The Response Reason-Phrase.
206 The Reason-Phrase is obsolete as of rfc7230.
208 @note This field is present only if `isRequest == false`.
213 /** A container for a complete HTTP message.
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
220 The `Body` template argument type determines the model used
221 to read or write the content body of the message.
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.
227 @tparam Body A type meeting the requirements of Body.
229 @tparam Fields The type of container used to hold the
232 template<bool isRequest, class Body, class Fields>
233 struct message : header<isRequest, Fields>
235 /// The base class used to hold the header portion of the message.
236 using base_type = header<isRequest, Fields>;
238 /** The type providing the body traits.
240 The @ref message::body member will be of type `body_type::value_type`.
242 using body_type = Body;
244 /// A value representing the body.
245 typename Body::value_type body;
247 /// Default constructor
251 message(message&&) = default;
254 message(message const&) = default;
257 message& operator=(message&&) = default;
260 message& operator=(message const&) = default;
262 /** Construct a message from a header.
264 Additional arguments, if any, are forwarded to
265 the constructor of the body member.
267 template<class... Args>
269 message(base_type&& base, Args&&... args)
270 : base_type(std::move(base))
271 , body(std::forward<Args>(args)...)
275 /** Construct a message from a header.
277 Additional arguments, if any, are forwarded to
278 the constructor of the body member.
280 template<class... Args>
282 message(base_type const& base, Args&&... args)
284 , body(std::forward<Args>(args)...)
288 /** Construct a message.
290 @param u An argument forwarded to the body constructor.
292 @note This constructor participates in overload resolution
293 only if `u` is not convertible to `base_type`.
297 , class = typename std::enable_if<
298 ! std::is_convertible<typename
299 std::decay<U>::type, base_type>::value>::type
304 : body(std::forward<U>(u))
308 /** Construct a message.
310 @param u An argument forwarded to the body constructor.
312 @param v An argument forwarded to the fields constructor.
314 @note This constructor participates in overload resolution
315 only if `u` is not convertible to `base_type`.
317 template<class U, class V
319 ,class = typename std::enable_if<! std::is_convertible<
320 typename std::decay<U>::type, base_type>::value>::type
323 message(U&& u, V&& v)
324 : base_type(std::forward<V>(v))
325 , body(std::forward<U>(u))
329 /** Construct a message.
331 @param un A tuple forwarded as a parameter pack to the body constructor.
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)>{})
340 /** Construct a message.
342 @param un A tuple forwarded as a parameter pack to the body constructor.
344 @param vn A tuple forwarded as a parameter pack to the fields constructor.
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)>{})
355 /// Returns the header portion of the message
362 /// Returns the header portion of the message
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))...)
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))...)
389 //------------------------------------------------------------------------------
392 /** Swap two header objects.
395 `Fields` is @b Swappable.
397 template<bool isRequest, class Fields>
400 header<isRequest, Fields>& m1,
401 header<isRequest, Fields>& m2);
404 /** Swap two message objects.
407 `Body::value_type` and `Fields` are @b Swappable.
409 template<bool isRequest, class Body, class Fields>
412 message<isRequest, Body, Fields>& m1,
413 message<isRequest, Body, Fields>& m2);
415 /// A typical HTTP request header
416 using request_header = header<true, fields>;
418 /// Typical HTTP response header
419 using response_header = header<false, fields>;
421 /// A typical HTTP request
422 template<class Body, class Fields = fields>
423 using request = message<true, Body, Fields>;
425 /// A typical HTTP response
426 template<class Body, class Fields = fields>
427 using response = message<false, Body, Fields>;
429 //------------------------------------------------------------------------------
431 /** Returns `true` if the HTTP/1 message indicates a keep alive.
433 Undefined behavior if version is greater than 11.
435 template<bool isRequest, class Fields>
437 is_keep_alive(header<isRequest, Fields> const& msg);
439 /** Returns `true` if the HTTP/1 message indicates an Upgrade request or response.
441 Undefined behavior if version is greater than 11.
443 template<bool isRequest, class Fields>
445 is_upgrade(header<isRequest, Fields> const& msg);
447 /** HTTP/1 connection prepare options.
449 @note These values are used with @ref prepare.
451 enum class connection
453 /// Specify Connection: close.
456 /// Specify Connection: keep-alive where possible.
459 /// Specify Connection: upgrade.
463 /** Prepare a HTTP message.
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.
469 @param msg The message to prepare. The fields may be modified.
471 @param options A list of prepare options.
474 bool isRequest, class Body, class Fields,
477 prepare(message<isRequest, Body, Fields>& msg,
478 Options&&... options);
483 #include <beast/http/impl/message.ipp>