[/ Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] [section:Body Body] In this table: * `X` is a type meeting the requirements of [*`Body`]. [table Body requirements [[operation] [type] [semantics, pre/post-conditions]] [ [`X::value_type`] [] [ The type of the `message::body` member. If this is not movable or not copyable, the containing message will be not movable or not copyable. ] ] [ [`X:value_type{}`] [] [`DefaultConstructible`] ] [ [`Body::reader`] [] [ If present, a type meeting the requirements of [link beast.types.Reader [*`Reader`]]. Provides an implementation to parse the body. ] ] [ [`Body::writer`] [] [ If present, a type meeting the requirements of [link beast.types.Writer [*`Writer`]]. Provides an implementation to serialize the body. ] ] ] [endsect] [section:BufferSequence BufferSequence] A `BufferSequence` is a type meeting either of the following requirements: * [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]] * [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*`MutableBufferSequence`]] [endsect] [section:Field Field] A [*`Field`] represents a single HTTP header field/value pair. In this table: * `X` denotes a type meeting the requirements of [*`Field`]. * `a` denotes a value of type `X`. [table Field requirements [[operation][type][semantics, pre/post-conditions]] [ [`a.name()`] [`boost::string_ref`] [ This function returns a value implicitly convertible to `boost::string_ref` containing the case-insensitve field name, without leading or trailing white space. ] ] [ [`a.value()`] [`boost::string_ref`] [ This function returns a value implicitly convertible to `boost::string_ref` containing the value for the field. The value is considered canonical if there is no leading or trailing whitespace. ] ] ] [endsect] [section:FieldSequence FieldSequence] A [*`FieldSequence`] is an iterable container whose value type meets the requirements of [link beast.types.Field [*`Field`]]. In this table: * `X` denotes a type that meets the requirements of [*`FieldSequence`]. * `a` is a value of type `X`. [table FieldSequence requirements [[operation][type][semantics, pre/post-conditions]] [ [`X::value_type`] [] [ A type that meets the requirements of `Field`. ] ] [ [`X::const_iterator`] [] [ A type that meets the requirements of `ForwardIterator`. ] ] [ [`a.begin()`] [`X::const_iterator`] [ Returns an iterator to the beginning of the field sequence. ] ] [ [`a.end()`] [`X::const_iterator`] [ Returns an iterator to the end of the field sequence. ] ] ] [endsect] [section:Reader Reader] Parser implementations will construct the corresponding `reader` object during the parse. This customization point allows the Body to determine the strategy for storing incoming message body data. In this table: * `X` denotes a type meeting the requirements of [*`Reader`]. * `a` denotes a value of type `X`. * `p` is any pointer. * `n` is a value convertible to `std::size_t`. * `ec` is a value of type `error_code&`. * `m` denotes a value of type `message const&` where `std::is_same:value == true` [table Reader requirements [[operation] [type] [semantics, pre/post-conditions]] [ [`X a(m);`] [] [ `a` is constructible from `m`. The lifetime of `m` is guaranteed to end no earlier than after `a` is destroyed. ] ] [ [`a.write(p, n, ec)`] [`void`] [ Deserializes the input sequence into the body. If `ec` is set, the deserialization is aborted and the error is returned to the caller. ] ] ] [note Definitions for required `Reader` member functions should be declared inline so the generated code becomes part of the implementation. ] [endsect] [section:Writer Writer] A `Writer` serializes the message body. The implementation creates an instance of this type when serializing a message, and calls into it zero or more times to provide buffers containing the data. The interface of `Writer` is intended to allow serialization in these scenarios: * A body that does not entirely fit in memory. * A body produced incrementally from coroutine output. * A body represented by zero or more buffers already in memory. * A body as a series of buffers when the content size is not known ahead of time. * Body data generated on demand from other threads. * Body data computed algorithmically. In this table: * `X` denotes a type meeting the requirements of `Writer`. * `a` denotes a value of type `X`. * `m` denotes a value of type `message const&` where `std::is_same:value == true`. * `rc` is an object of type [link beast.ref.http__resume_context resume_context]. * `ec` is a value of type `error_code&`. * `wf` is a [*write function]: a function object of unspecified type provided by the implementation which accepts any value meeting the requirements of `ConstBufferSequence` as its single parameter. [table Writer requirements [[operation] [type] [semantics, pre/post-conditions]] [ [`X a(m);`] [] [ `a` is constructible from `m`. The lifetime of `m` is guaranteed to end no earlier than after `a` is destroyed. ] ] [ [`a.init(ec)`] [`void`] [ Called immediately after construction. If `ec` is set, the serialization is aborted and the error is propagated to the caller. ] ] [ [`a.content_length()`] [`std::uint64_t`] [ If this member is present, it is called after initialization and before calls to provide buffers. The serialized message will have the Content-Length field set to the value returned from this function. If this member is absent, the serialized message body will be chunk-encoded for HTTP versions 1.1 and later, else the serialized message body will be sent unmodified, with the error `boost::asio::error::eof` returned to the caller, to notify they should close the connection to indicate the end of the message. ] ] [ [`a(rc, ec, wf)`] [`boost::tribool`] [ Called repeatedly after `init` succeeds. `wf` is a function object which takes as its single parameter, any value meeting the requirements of `ConstBufferSequence`. Buffers provided by the `writer` to this [*write function] must remain valid until the next member function of `writer` is invoked (which may be the destructor). This function returns `true` to indicate all message body data has been written, or `false` if there is more body data. If the return value is `boost::indeterminate`, the implementation will suspend the operation until the writer invokes `rc`. It is the writers responsibility when returning `boost::indeterminate`, to acquire ownership of the `resume_context` via move construction and eventually call it or else undefined behavior results. ] ] ] [note Definitions for required `Writer` member functions should be declared inline so the generated code becomes part of the implementation. ] Exemplar: ``` struct writer { public: /** Construct the writer. The msg object is guaranteed to exist for the lifetime of the writer. Exceptions: No-throw guarantee. @param msg The message whose body is to be written. */ template explicit writer(message const& msg); /** Initialize the writer. Called once immediately after construction. The writer can perform initialization which may fail. @param ec Contains the error code if any errors occur. */ void init(error_code& ec); /** Returns the content length. If this member is present, the implementation will set the Content-Length field accordingly. If absent, the implementation will use chunk-encoding or terminate the connection to indicate the end of the message. */ std::size_t content_length() const; /** Write zero or one buffer representing the message body. Postconditions: If return value is `true`: * Callee does not take ownership of resume. * Callee made zero or one calls to `write`. * There is no more data remaining to write. If return value is `false`: * Callee does not take ownership of resume. * Callee made one call to `write`. If return value is boost::indeterminate: * Callee takes ownership of `resume`. * Caller suspends the write operation until `resume` is invoked. When the caller takes ownership of resume, the asynchronous operation will not complete until the caller destroys the object. @param resume A functor to call to resume the write operation after the writer has returned boost::indeterminate. @param ec Set to indicate an error. This will cause an asynchronous write operation to complete with the error. @param write A functor the writer will call to provide the next set of buffers. Ownership of the buffers is not transferred, the writer must guarantee that the buffers remain valid until the next member function is invoked, which may be the destructor. @return `true` if there is data, `false` when done, boost::indeterminate to suspend. @note Undefined behavior if the callee takes ownership of resume but does not return boost::indeterminate. */ template boost::tribool operator()(resume_context&&, error_code&, WriteFunction&& write); }; ``` [endsect]