forked from boostorg/beast
		
	
		
			
				
	
	
		
			738 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			738 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
// Copyright (c) 2016-2017 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)
 | 
						|
//
 | 
						|
// Official repository: https://github.com/boostorg/beast
 | 
						|
//
 | 
						|
 | 
						|
#ifndef BOOST_BEAST_HTTP_CHUNK_ENCODE_HPP
 | 
						|
#define BOOST_BEAST_HTTP_CHUNK_ENCODE_HPP
 | 
						|
 | 
						|
#include <boost/beast/core/detail/config.hpp>
 | 
						|
#include <boost/beast/core/buffers_cat.hpp>
 | 
						|
#include <boost/beast/core/string.hpp>
 | 
						|
#include <boost/beast/http/type_traits.hpp>
 | 
						|
#include <boost/beast/http/detail/chunk_encode.hpp>
 | 
						|
#include <boost/asio/buffer.hpp>
 | 
						|
#include <memory>
 | 
						|
#include <type_traits>
 | 
						|
 | 
						|
namespace boost {
 | 
						|
namespace beast {
 | 
						|
namespace http {
 | 
						|
 | 
						|
/** A chunked encoding crlf
 | 
						|
 | 
						|
    This implements a @b ConstBufferSequence holding the CRLF
 | 
						|
    (`"\r\n"`) used as a delimiter in a @em chunk.
 | 
						|
 | 
						|
    To use this class, pass an instance of it to a
 | 
						|
    stream algorithm as the buffer sequence:
 | 
						|
    @code
 | 
						|
        // writes "\r\n"
 | 
						|
        net::write(stream, chunk_crlf{});
 | 
						|
    @endcode
 | 
						|
 | 
						|
    @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
*/
 | 
						|
struct chunk_crlf
 | 
						|
{
 | 
						|
    /// Constructor
 | 
						|
    chunk_crlf() = default;
 | 
						|
 | 
						|
    //-----
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using value_type = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using value_type = net::const_buffer;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    using const_iterator = value_type const*;
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    chunk_crlf(chunk_crlf const&) = default;
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    begin() const
 | 
						|
    {
 | 
						|
        static net::const_buffer const cb{"\r\n", 2};
 | 
						|
        return &cb;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    end() const
 | 
						|
    {
 | 
						|
        return begin() + 1;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
/** A @em chunk header
 | 
						|
 | 
						|
    This implements a @b ConstBufferSequence representing the
 | 
						|
    header of a @em chunk. The serialized format is as follows:
 | 
						|
    @code
 | 
						|
        chunk-header    = 1*HEXDIG chunk-ext CRLF       
 | 
						|
        chunk-ext       = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
 | 
						|
        chunk-ext-name  = token
 | 
						|
        chunk-ext-val   = token / quoted-string
 | 
						|
    @endcode
 | 
						|
    The chunk extension is optional. After the header and
 | 
						|
    chunk body have been serialized, it is the callers
 | 
						|
    responsibility to also serialize the final CRLF (`"\r\n"`).
 | 
						|
 | 
						|
    This class allows the caller to emit piecewise chunk bodies,
 | 
						|
    by first serializing the chunk header using this class and then
 | 
						|
    serializing the chunk body in a series of one or more calls to
 | 
						|
    a stream write operation.
 | 
						|
 | 
						|
    To use this class, pass an instance of it to a
 | 
						|
    stream algorithm as the buffer sequence:
 | 
						|
    @code
 | 
						|
        // writes "400;x\r\n"
 | 
						|
        net::write(stream, chunk_header{1024, "x"});
 | 
						|
    @endcode
 | 
						|
 | 
						|
    @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
*/
 | 
						|
class chunk_header
 | 
						|
{
 | 
						|
    using view_type = buffers_cat_view<
 | 
						|
        detail::chunk_size,             // chunk-size
 | 
						|
        net::const_buffer,   // chunk-extensions
 | 
						|
        chunk_crlf>;                    // CRLF
 | 
						|
 | 
						|
    std::shared_ptr<
 | 
						|
        detail::chunk_extensions> exts_;
 | 
						|
    view_type view_;
 | 
						|
 | 
						|
public:
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs a buffer sequence representing a
 | 
						|
        @em chunked-body size and terminating CRLF (`"\r\n"`)
 | 
						|
        with no chunk extensions.
 | 
						|
 | 
						|
        @param size The size of the chunk body that follows.
 | 
						|
        The value must be greater than zero.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    explicit
 | 
						|
    chunk_header(std::size_t size);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs a buffer sequence representing a
 | 
						|
        @em chunked-body size and terminating CRLF (`"\r\n"`)
 | 
						|
        with provided chunk extensions.
 | 
						|
 | 
						|
        @param size The size of the chunk body that follows.
 | 
						|
        The value must be greater than zero.
 | 
						|
 | 
						|
        @param extensions The chunk extensions string. This
 | 
						|
        string must be formatted correctly as per rfc7230,
 | 
						|
        using this BNF syntax:
 | 
						|
        @code
 | 
						|
            chunk-ext       = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
 | 
						|
            chunk-ext-name  = token
 | 
						|
            chunk-ext-val   = token / quoted-string
 | 
						|
        @endcode
 | 
						|
        The data pointed to by this string view must remain
 | 
						|
        valid for the lifetime of any operations performed on
 | 
						|
        the object.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1.1
 | 
						|
    */
 | 
						|
    chunk_header(
 | 
						|
        std::size_t size,
 | 
						|
        string_view extensions);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs a buffer sequence representing a
 | 
						|
        @em chunked-body size and terminating CRLF (`"\r\n"`)
 | 
						|
        with provided chunk extensions.
 | 
						|
        The default allocator is used to provide storage for the
 | 
						|
        extensions object.
 | 
						|
 | 
						|
        @param size The size of the chunk body that follows.
 | 
						|
        The value must be greater than zero.
 | 
						|
 | 
						|
        @param extensions The chunk extensions object. The expression
 | 
						|
        `extensions.str()` must be valid, and the return type must
 | 
						|
        be convertible to @ref string_view. This object will be copied
 | 
						|
        or moved as needed to ensure that the chunk header object retains
 | 
						|
        ownership of the buffers provided by the chunk extensions object.
 | 
						|
 | 
						|
        @note This function participates in overload resolution only
 | 
						|
        if @b ChunkExtensions meets the requirements stated above.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    template<class ChunkExtensions
 | 
						|
#if ! BOOST_BEAST_DOXYGEN
 | 
						|
        , class = typename std::enable_if<
 | 
						|
            detail::is_chunk_extensions<
 | 
						|
                ChunkExtensions>::value>::type
 | 
						|
#endif
 | 
						|
    >
 | 
						|
    chunk_header(
 | 
						|
        std::size_t size,
 | 
						|
        ChunkExtensions&& extensions);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs a buffer sequence representing a
 | 
						|
        @em chunked-body size and terminating CRLF (`"\r\n"`)
 | 
						|
        with provided chunk extensions.
 | 
						|
        The specified allocator is used to provide storage for the
 | 
						|
        extensions object.
 | 
						|
 | 
						|
        @param size The size of the chunk body that follows.
 | 
						|
        The value be greater than zero.
 | 
						|
 | 
						|
        @param extensions The chunk extensions object. The expression
 | 
						|
        `extensions.str()` must be valid, and the return type must
 | 
						|
        be convertible to @ref string_view. This object will be copied
 | 
						|
        or moved as needed to ensure that the chunk header object retains
 | 
						|
        ownership of the buffers provided by the chunk extensions object.
 | 
						|
 | 
						|
        @param allocator The allocator to provide storage for the moved
 | 
						|
        or copied extensions object.
 | 
						|
 | 
						|
        @note This function participates in overload resolution only
 | 
						|
        if @b ChunkExtensions meets the requirements stated above.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    template<class ChunkExtensions, class Allocator
 | 
						|
#if ! BOOST_BEAST_DOXYGEN
 | 
						|
        , class = typename std::enable_if<
 | 
						|
            detail::is_chunk_extensions<
 | 
						|
                ChunkExtensions>::value>::type
 | 
						|
#endif
 | 
						|
    >
 | 
						|
    chunk_header(
 | 
						|
        std::size_t size,
 | 
						|
        ChunkExtensions&& extensions,
 | 
						|
        Allocator const& allocator);
 | 
						|
 | 
						|
    //-----
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using value_type = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using value_type = typename view_type::value_type;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using const_iterator = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using const_iterator = typename view_type::const_iterator;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    chunk_header(chunk_header const&) = default;
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    begin() const
 | 
						|
    {
 | 
						|
        return view_.begin();
 | 
						|
    }
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    end() const
 | 
						|
    {
 | 
						|
        return view_.end();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
/** A @em chunk
 | 
						|
 | 
						|
    This implements a @b ConstBufferSequence representing
 | 
						|
    a @em chunk. The serialized format is as follows:
 | 
						|
    @code
 | 
						|
        chunk           = chunk-size [ chunk-ext ] CRLF chunk-data CRLF
 | 
						|
        chunk-size      = 1*HEXDIG
 | 
						|
        chunk-ext       = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
 | 
						|
        chunk-ext-name  = token
 | 
						|
        chunk-ext-val   = token / quoted-string
 | 
						|
        chunk-data      = 1*OCTET ; a sequence of chunk-size octets
 | 
						|
    @endcode
 | 
						|
    The chunk extension is optional. 
 | 
						|
 | 
						|
    To use this class, pass an instance of it to a
 | 
						|
    stream algorithm as the buffer sequence.
 | 
						|
 | 
						|
    @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
*/
 | 
						|
template<class ConstBufferSequence>
 | 
						|
class chunk_body
 | 
						|
{
 | 
						|
    using view_type = buffers_cat_view<
 | 
						|
        detail::chunk_size,             // chunk-size
 | 
						|
        net::const_buffer,   // chunk-extensions
 | 
						|
        chunk_crlf,                     // CRLF
 | 
						|
        ConstBufferSequence,            // chunk-body
 | 
						|
        chunk_crlf>;                    // CRLF
 | 
						|
 | 
						|
    std::shared_ptr<
 | 
						|
        detail::chunk_extensions> exts_;
 | 
						|
    view_type view_;
 | 
						|
 | 
						|
public:
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs buffers representing a complete @em chunk
 | 
						|
        with no chunk extensions and having the size and contents
 | 
						|
        of the specified buffer sequence.
 | 
						|
 | 
						|
        @param buffers A buffer sequence representing the chunk
 | 
						|
        body. Although the buffers object may be copied as necessary,
 | 
						|
        ownership of the underlying memory blocks is retained by the
 | 
						|
        caller, which must guarantee that they remain valid while this
 | 
						|
        object is in use.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    explicit
 | 
						|
    chunk_body(
 | 
						|
        ConstBufferSequence const& buffers);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs buffers representing a complete @em chunk
 | 
						|
        with the passed chunk extensions and having the size and
 | 
						|
        contents of the specified buffer sequence.
 | 
						|
 | 
						|
        @param buffers A buffer sequence representing the chunk
 | 
						|
        body. Although the buffers object may be copied as necessary,
 | 
						|
        ownership of the underlying memory blocks is retained by the
 | 
						|
        caller, which must guarantee that they remain valid while this
 | 
						|
        object is in use.
 | 
						|
 | 
						|
        @param extensions The chunk extensions string. This
 | 
						|
        string must be formatted correctly as per rfc7230,
 | 
						|
        using this BNF syntax:
 | 
						|
        @code
 | 
						|
            chunk-ext       = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
 | 
						|
            chunk-ext-name  = token
 | 
						|
            chunk-ext-val   = token / quoted-string
 | 
						|
        @endcode
 | 
						|
        The data pointed to by this string view must remain
 | 
						|
        valid for the lifetime of any operations performed on
 | 
						|
        the object.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1.1
 | 
						|
    */
 | 
						|
    chunk_body(
 | 
						|
        ConstBufferSequence const& buffers,
 | 
						|
        string_view extensions);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs buffers representing a complete @em chunk
 | 
						|
        with the passed chunk extensions and having the size and
 | 
						|
        contents of the specified buffer sequence.
 | 
						|
        The default allocator is used to provide storage for the
 | 
						|
        extensions object.
 | 
						|
 | 
						|
        @param buffers A buffer sequence representing the chunk
 | 
						|
        body. Although the buffers object may be copied as necessary,
 | 
						|
        ownership of the underlying memory blocks is retained by the
 | 
						|
        caller, which must guarantee that they remain valid while this
 | 
						|
        object is in use.
 | 
						|
 | 
						|
        @param extensions The chunk extensions object. The expression
 | 
						|
        `extensions.str()` must be valid, and the return type must
 | 
						|
        be convertible to @ref string_view. This object will be copied
 | 
						|
        or moved as needed to ensure that the chunk header object retains
 | 
						|
        ownership of the buffers provided by the chunk extensions object.
 | 
						|
 | 
						|
        @note This function participates in overload resolution only
 | 
						|
        if @b ChunkExtensions meets the requirements stated above.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    template<class ChunkExtensions
 | 
						|
#if ! BOOST_BEAST_DOXYGEN
 | 
						|
        , class = typename std::enable_if<
 | 
						|
            ! std::is_convertible<typename std::decay<
 | 
						|
                ChunkExtensions>::type, string_view>::value>::type
 | 
						|
#endif
 | 
						|
    >
 | 
						|
    chunk_body(
 | 
						|
        ConstBufferSequence const& buffers,
 | 
						|
        ChunkExtensions&& extensions);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        This constructs buffers representing a complete @em chunk
 | 
						|
        with the passed chunk extensions and having the size and
 | 
						|
        contents of the specified buffer sequence.
 | 
						|
        The specified allocator is used to provide storage for the
 | 
						|
        extensions object.
 | 
						|
 | 
						|
        @param buffers A buffer sequence representing the chunk
 | 
						|
        body. Although the buffers object may be copied as necessary,
 | 
						|
        ownership of the underlying memory blocks is retained by the
 | 
						|
        caller, which must guarantee that they remain valid while this
 | 
						|
        object is in use.
 | 
						|
 | 
						|
        @param extensions The chunk extensions object. The expression
 | 
						|
        `extensions.str()` must be valid, and the return type must
 | 
						|
        be convertible to @ref string_view. This object will be copied
 | 
						|
        or moved as needed to ensure that the chunk header object retains
 | 
						|
        ownership of the buffers provided by the chunk extensions object.
 | 
						|
 | 
						|
        @param allocator The allocator to provide storage for the moved
 | 
						|
        or copied extensions object.
 | 
						|
 | 
						|
        @note This function participates in overload resolution only
 | 
						|
        if @b ChunkExtensions meets the requirements stated above.
 | 
						|
 | 
						|
        @see https://tools.ietf.org/html/rfc7230#section-4.1
 | 
						|
    */
 | 
						|
    template<class ChunkExtensions, class Allocator
 | 
						|
#if ! BOOST_BEAST_DOXYGEN
 | 
						|
        , class = typename std::enable_if<
 | 
						|
            ! std::is_convertible<typename std::decay<
 | 
						|
                ChunkExtensions>::type, string_view>::value>::type
 | 
						|
#endif
 | 
						|
    >
 | 
						|
    chunk_body(
 | 
						|
        ConstBufferSequence const& buffers,
 | 
						|
        ChunkExtensions&& extensions,
 | 
						|
        Allocator const& allocator);
 | 
						|
 | 
						|
    //-----
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using value_type = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using value_type = typename view_type::value_type;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using const_iterator = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using const_iterator = typename view_type::const_iterator;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    begin() const
 | 
						|
    {
 | 
						|
        return view_.begin();
 | 
						|
    }
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    end() const
 | 
						|
    {
 | 
						|
        return view_.end();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
/** A chunked-encoding last chunk
 | 
						|
*/
 | 
						|
template<class Trailer = chunk_crlf>
 | 
						|
class chunk_last
 | 
						|
{
 | 
						|
    static_assert(
 | 
						|
        is_fields<Trailer>::value ||
 | 
						|
        net::is_const_buffer_sequence<Trailer>::value,
 | 
						|
        "Trailer requirements not met");
 | 
						|
 | 
						|
    using buffers_type = typename
 | 
						|
        detail::buffers_or_fields<Trailer>::type;
 | 
						|
 | 
						|
    using view_type =
 | 
						|
        buffers_cat_view<
 | 
						|
            detail::chunk_size0,    // "0\r\n"
 | 
						|
            buffers_type>;          // Trailer (includes CRLF)
 | 
						|
 | 
						|
    template<class Allocator>
 | 
						|
    buffers_type
 | 
						|
    prepare(Trailer const& trailer, Allocator const& alloc);
 | 
						|
 | 
						|
    buffers_type
 | 
						|
    prepare(Trailer const& trailer, std::true_type);
 | 
						|
 | 
						|
    buffers_type
 | 
						|
    prepare(Trailer const& trailer, std::false_type);
 | 
						|
 | 
						|
    std::shared_ptr<void> sp_;
 | 
						|
    view_type view_;
 | 
						|
 | 
						|
public:
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        The last chunk will have an empty trailer
 | 
						|
    */
 | 
						|
    chunk_last();
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        @param trailer The trailer to use. This may be
 | 
						|
        a type meeting the requirements of either Fields
 | 
						|
        or ConstBufferSequence. If it is a ConstBufferSequence,
 | 
						|
        the trailer must be formatted correctly as per rfc7230
 | 
						|
        including a CRLF on its own line to denote the end
 | 
						|
        of the trailer.
 | 
						|
    */
 | 
						|
    explicit
 | 
						|
    chunk_last(Trailer const& trailer);
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        @param trailer The trailer to use. This type must
 | 
						|
        meet the requirements of Fields.
 | 
						|
 | 
						|
        @param allocator The allocator to use for storing temporary
 | 
						|
        data associated with the serialized trailer buffers.
 | 
						|
    */
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    template<class Allocator>
 | 
						|
    chunk_last(Trailer const& trailer, Allocator const& allocator);
 | 
						|
#else
 | 
						|
    template<class DeducedTrailer, class Allocator,
 | 
						|
        class = typename std::enable_if<
 | 
						|
            is_fields<DeducedTrailer>::value>::type>
 | 
						|
    chunk_last(
 | 
						|
        DeducedTrailer const& trailer, Allocator const& allocator);
 | 
						|
#endif
 | 
						|
 | 
						|
    //-----
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    chunk_last(chunk_last const&) = default;
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using value_type = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using value_type =
 | 
						|
        typename view_type::value_type;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
#if BOOST_BEAST_DOXYGEN
 | 
						|
    using const_iterator = __implementation_defined__;
 | 
						|
#else
 | 
						|
    using const_iterator =
 | 
						|
        typename view_type::const_iterator;
 | 
						|
#endif
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    begin() const
 | 
						|
    {
 | 
						|
        return view_.begin();
 | 
						|
    }
 | 
						|
 | 
						|
    /// Required for @b ConstBufferSequence
 | 
						|
    const_iterator
 | 
						|
    end() const
 | 
						|
    {
 | 
						|
        return view_.end();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
/** A set of chunk extensions
 | 
						|
 | 
						|
    This container stores a set of chunk extensions suited for use with
 | 
						|
    @ref chunk_header and @ref chunk_body. The container may be iterated
 | 
						|
    to access the extensions in their structured form.
 | 
						|
 | 
						|
    Meets the requirements of ChunkExtensions
 | 
						|
*/
 | 
						|
template<class Allocator>
 | 
						|
class basic_chunk_extensions
 | 
						|
{
 | 
						|
    std::basic_string<char,
 | 
						|
        std::char_traits<char>, Allocator> s_;
 | 
						|
 | 
						|
    std::basic_string<char,
 | 
						|
        std::char_traits<char>, Allocator> range_;
 | 
						|
 | 
						|
    template<class FwdIt>
 | 
						|
    FwdIt
 | 
						|
    do_parse(FwdIt it, FwdIt last, error_code& ec);
 | 
						|
 | 
						|
    void
 | 
						|
    do_insert(string_view name, string_view value);
 | 
						|
 | 
						|
public:
 | 
						|
    /** The type of value when iterating.
 | 
						|
 | 
						|
        The first element of the pair is the name, and the second
 | 
						|
        element is the value which may be empty. The value is
 | 
						|
        stored in its raw representation, without quotes or escapes.
 | 
						|
    */
 | 
						|
    using value_type = std::pair<string_view, string_view>;
 | 
						|
 | 
						|
    class const_iterator;
 | 
						|
 | 
						|
    /// Constructor
 | 
						|
    basic_chunk_extensions() = default;
 | 
						|
 | 
						|
    /// Constructor
 | 
						|
    basic_chunk_extensions(basic_chunk_extensions&&) = default;
 | 
						|
 | 
						|
    /// Constructor
 | 
						|
    basic_chunk_extensions(basic_chunk_extensions const&) = default;
 | 
						|
 | 
						|
    /** Constructor
 | 
						|
 | 
						|
        @param allocator The allocator to use for storing the serialized extension
 | 
						|
    */
 | 
						|
    explicit
 | 
						|
    basic_chunk_extensions(Allocator const& allocator)
 | 
						|
        : s_(allocator)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /** Clear the chunk extensions
 | 
						|
 | 
						|
        This preserves the capacity of the internal string
 | 
						|
        used to hold the serialized representation.
 | 
						|
    */
 | 
						|
    void
 | 
						|
    clear()
 | 
						|
    {
 | 
						|
        s_.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    /** Parse a set of chunk extensions
 | 
						|
 | 
						|
        Any previous extensions will be cleared
 | 
						|
    */
 | 
						|
    void
 | 
						|
    parse(string_view s, error_code& ec);
 | 
						|
 | 
						|
    /** Insert an extension name with an empty value
 | 
						|
 | 
						|
        @param name The name of the extension
 | 
						|
    */
 | 
						|
    void
 | 
						|
    insert(string_view name);
 | 
						|
 | 
						|
    /** Insert an extension value
 | 
						|
 | 
						|
        @param name The name of the extension
 | 
						|
 | 
						|
        @param value The value to insert. Depending on the
 | 
						|
        contents, the serialized extension may use a quoted string.
 | 
						|
    */
 | 
						|
    void
 | 
						|
    insert(string_view name, string_view value);
 | 
						|
 | 
						|
    /// Return the serialized representation of the chunk extension
 | 
						|
    string_view
 | 
						|
    str() const
 | 
						|
    {
 | 
						|
        return s_;
 | 
						|
    }
 | 
						|
 | 
						|
    const_iterator
 | 
						|
    begin() const;
 | 
						|
 | 
						|
    const_iterator
 | 
						|
    end() const;
 | 
						|
};
 | 
						|
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
/// A set of chunk extensions
 | 
						|
using chunk_extensions =
 | 
						|
    basic_chunk_extensions<std::allocator<char>>;
 | 
						|
 | 
						|
/** Returns a @ref chunk_body
 | 
						|
 | 
						|
    This functions constructs and returns a complete
 | 
						|
    @ref chunk_body for a chunk body represented by the
 | 
						|
    specified buffer sequence.
 | 
						|
 | 
						|
    @param buffers The buffers representing the chunk body.
 | 
						|
 | 
						|
    @param args Optional arguments passed to the @ref chunk_body constructor.
 | 
						|
 | 
						|
    @note This function is provided as a notational convenience
 | 
						|
    to omit specification of the class template arguments.
 | 
						|
*/
 | 
						|
template<class ConstBufferSequence, class... Args>
 | 
						|
auto
 | 
						|
make_chunk(
 | 
						|
    ConstBufferSequence const& buffers,
 | 
						|
    Args&&... args) ->
 | 
						|
    chunk_body<ConstBufferSequence>
 | 
						|
{
 | 
						|
    return chunk_body<ConstBufferSequence>(
 | 
						|
        buffers, std::forward<Args>(args)...);
 | 
						|
}
 | 
						|
 | 
						|
/** Returns a @ref chunk_last
 | 
						|
 | 
						|
    @note This function is provided as a notational convenience
 | 
						|
    to omit specification of the class template arguments.
 | 
						|
*/
 | 
						|
inline
 | 
						|
chunk_last<chunk_crlf>
 | 
						|
make_chunk_last()
 | 
						|
{
 | 
						|
    return chunk_last<chunk_crlf>{};
 | 
						|
}
 | 
						|
 | 
						|
/** Returns a @ref chunk_last
 | 
						|
 | 
						|
    This function construct and returns a complete
 | 
						|
    @ref chunk_last for a last chunk containing the
 | 
						|
    specified trailers.
 | 
						|
 | 
						|
    @param trailer A ConstBufferSequence or 
 | 
						|
    @note This function is provided as a notational convenience
 | 
						|
    to omit specification of the class template arguments.
 | 
						|
 | 
						|
    @param args Optional arguments passed to the @ref chunk_last
 | 
						|
    constructor.
 | 
						|
*/
 | 
						|
template<class Trailer, class... Args>
 | 
						|
chunk_last<Trailer>
 | 
						|
make_chunk_last(
 | 
						|
    Trailer const& trailer,
 | 
						|
    Args&&... args)
 | 
						|
{
 | 
						|
    return chunk_last<Trailer>{
 | 
						|
        trailer, std::forward<Args>(args)...};
 | 
						|
}
 | 
						|
 | 
						|
} // http
 | 
						|
} // beast
 | 
						|
} // boost
 | 
						|
 | 
						|
#include <boost/beast/http/impl/chunk_encode.ipp>
 | 
						|
 | 
						|
#endif
 |