Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:32

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_HTTP_SERIALIZER_HPP
0011 #define BOOST_BEAST_HTTP_SERIALIZER_HPP
0012 
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/core/buffers_cat.hpp>
0015 #include <boost/beast/core/buffers_prefix.hpp>
0016 #include <boost/beast/core/buffers_suffix.hpp>
0017 #include <boost/beast/core/string.hpp>
0018 #include <boost/beast/core/detail/variant.hpp>
0019 #include <boost/beast/http/message.hpp>
0020 #include <boost/beast/http/chunk_encode.hpp>
0021 #include <boost/asio/buffer.hpp>
0022 #include <boost/optional.hpp>
0023 
0024 namespace boost {
0025 namespace beast {
0026 namespace http {
0027 
0028 /** Provides buffer oriented HTTP message serialization functionality.
0029 
0030     An object of this type is used to serialize a complete
0031     HTTP message into a sequence of octets. To use this class,
0032     construct an instance with the message to be serialized.
0033     The implementation will automatically perform chunk encoding
0034     if the contents of the message indicate that chunk encoding
0035     is required.
0036 
0037     Chunked output produced by the serializer never contains chunk
0038     extensions or trailers, and the location of chunk boundaries
0039     is not specified. If callers require chunk extensions, trailers,
0040     or control over the exact contents of each chunk they should
0041     use the serializer to write just the message header, and then
0042     assume control over serializing the chunked payload by using
0043     the chunk buffer sequence types @ref chunk_body, @ref chunk_crlf,
0044     @ref chunk_header, and @ref chunk_last.
0045 
0046     @tparam isRequest `true` if the message is a request.
0047 
0048     @tparam Body The body type of the message.
0049 
0050     @tparam Fields The type of fields in the message.
0051 */
0052 template<
0053     bool isRequest,
0054     class Body,
0055     class Fields = fields>
0056 class serializer
0057 {
0058 public:
0059     static_assert(is_body<Body>::value,
0060         "Body type requirements not met");
0061 
0062     static_assert(is_body_writer<Body>::value,
0063         "BodyWriter type requirements not met");
0064 
0065     /** The type of message this serializer uses
0066 
0067         This may be const or non-const depending on the
0068         implementation of the corresponding <em>BodyWriter</em>.
0069     */
0070 #if BOOST_BEAST_DOXYGEN
0071     using value_type = __implementation_defined__;
0072 #else
0073     using value_type = typename std::conditional<
0074         std::is_constructible<typename Body::writer,
0075             header<isRequest, Fields>&,
0076             typename Body::value_type&>::value &&
0077         ! std::is_constructible<typename Body::writer,
0078             header<isRequest, Fields> const&,
0079             typename Body::value_type const&>::value,
0080         message<isRequest, Body, Fields>,
0081         message<isRequest, Body, Fields> const>::type;
0082 #endif
0083 
0084 private:
0085     enum
0086     {
0087         do_construct        =   0,
0088 
0089         do_init             =  10,
0090         do_header_only      =  20,
0091         do_header           =  30,
0092         do_body             =  40,
0093         
0094         do_init_c           =  50,
0095         do_header_only_c    =  60,
0096         do_header_c         =  70,
0097         do_body_c           =  80,
0098         do_final_c          =  90,
0099     #ifndef BOOST_BEAST_NO_BIG_VARIANTS
0100         do_body_final_c     = 100,
0101         do_all_c            = 110,
0102     #endif
0103 
0104         do_complete         = 120
0105     };
0106 
0107     void fwrinit(std::true_type);
0108     void fwrinit(std::false_type);
0109 
0110     template<std::size_t, class Visit>
0111     void
0112     do_visit(error_code& ec, Visit& visit);
0113 
0114     using writer = typename Body::writer;
0115 
0116     using cb1_t = buffers_suffix<typename
0117         Fields::writer::const_buffers_type>;        // header
0118     using pcb1_t  = buffers_prefix_view<cb1_t const&>;
0119 
0120     using cb2_t = buffers_suffix<buffers_cat_view<
0121         typename Fields::writer::const_buffers_type,// header
0122         typename writer::const_buffers_type>>;      // body
0123     using pcb2_t = buffers_prefix_view<cb2_t const&>;
0124 
0125     using cb3_t = buffers_suffix<
0126         typename writer::const_buffers_type>;       // body
0127     using pcb3_t = buffers_prefix_view<cb3_t const&>;
0128 
0129     using cb4_t = buffers_suffix<buffers_cat_view<
0130         typename Fields::writer::const_buffers_type,// header
0131         detail::chunk_size,                         // chunk-size
0132         net::const_buffer,                          // chunk-ext
0133         chunk_crlf,                                 // crlf
0134         typename writer::const_buffers_type,        // body
0135         chunk_crlf>>;                               // crlf
0136     using pcb4_t = buffers_prefix_view<cb4_t const&>;
0137 
0138     using cb5_t = buffers_suffix<buffers_cat_view<
0139         detail::chunk_size,                         // chunk-header
0140         net::const_buffer,                          // chunk-ext
0141         chunk_crlf,                                 // crlf
0142         typename writer::const_buffers_type,        // body
0143         chunk_crlf>>;                               // crlf
0144     using pcb5_t = buffers_prefix_view<cb5_t const&>;
0145 
0146     using cb6_t = buffers_suffix<buffers_cat_view<
0147         detail::chunk_size,                         // chunk-header
0148         net::const_buffer,                          // chunk-size
0149         chunk_crlf,                                 // crlf
0150         typename writer::const_buffers_type,        // body
0151         chunk_crlf,                                 // crlf
0152         net::const_buffer,                          // chunk-final
0153         net::const_buffer,                          // trailers 
0154         chunk_crlf>>;                               // crlf
0155     using pcb6_t = buffers_prefix_view<cb6_t const&>;
0156 
0157     using cb7_t = buffers_suffix<buffers_cat_view<
0158         typename Fields::writer::const_buffers_type,// header
0159         detail::chunk_size,                         // chunk-size
0160         net::const_buffer,                          // chunk-ext
0161         chunk_crlf,                                 // crlf
0162         typename writer::const_buffers_type,        // body
0163         chunk_crlf,                                 // crlf
0164         net::const_buffer,                          // chunk-final
0165         net::const_buffer,                          // trailers 
0166         chunk_crlf>>;                               // crlf
0167     using pcb7_t = buffers_prefix_view<cb7_t const&>;
0168 
0169     using cb8_t = buffers_suffix<buffers_cat_view<
0170         net::const_buffer,                          // chunk-final
0171         net::const_buffer,                          // trailers 
0172         chunk_crlf>>;                               // crlf
0173     using pcb8_t = buffers_prefix_view<cb8_t const&>;
0174 
0175     value_type& m_;
0176     writer wr_;
0177     boost::optional<typename Fields::writer> fwr_;
0178     beast::detail::variant<
0179         cb1_t, cb2_t, cb3_t, cb4_t,
0180         cb5_t ,cb6_t, cb7_t, cb8_t> v_;
0181     beast::detail::variant<
0182         pcb1_t, pcb2_t, pcb3_t, pcb4_t,
0183         pcb5_t ,pcb6_t, pcb7_t, pcb8_t> pv_;
0184     std::size_t limit_ =
0185         (std::numeric_limits<std::size_t>::max)();
0186     int s_ = do_construct;
0187     bool split_ = false;
0188     bool header_done_ = false;
0189     bool more_ = false;
0190 
0191 public:
0192     /// Constructor
0193     serializer(serializer&&) = default;
0194 
0195     /// Constructor
0196     serializer(serializer const&) = default;
0197 
0198     /// Assignment
0199     serializer& operator=(serializer const&) = delete;
0200 
0201     /** Constructor
0202 
0203         The implementation guarantees that the message passed on
0204         construction will not be accessed until the first call to
0205         @ref next. This allows the message to be lazily created.
0206         For example, if the header is filled in before serialization.
0207 
0208         @param msg A reference to the message to serialize, which must
0209         remain valid for the lifetime of the serializer. Depending on
0210         the type of Body used, this may or may not be a `const` reference.
0211 
0212         @note This function participates in overload resolution only if
0213         Body::writer is constructible from a `const` message reference.
0214     */
0215     explicit
0216     serializer(value_type& msg);
0217 
0218     /// Returns the message being serialized
0219     value_type&
0220     get()
0221     {
0222         return m_;
0223     }
0224 
0225     /// Returns the serialized buffer size limit
0226     std::size_t
0227     limit()
0228     {
0229         return limit_;
0230     }
0231 
0232     /** Set the serialized buffer size limit
0233 
0234         This function adjusts the limit on the maximum size of the
0235         buffers passed to the visitor. The new size limit takes effect
0236         in the following call to @ref next.
0237 
0238         The default is no buffer size limit.
0239 
0240         @param limit The new buffer size limit. If this number
0241         is zero, the size limit is removed.
0242     */
0243     void
0244     limit(std::size_t limit)
0245     {
0246         limit_ = limit > 0 ? limit :
0247             (std::numeric_limits<std::size_t>::max)();
0248     }
0249 
0250     /** Returns `true` if we will pause after writing the complete header.
0251     */
0252     bool
0253     split()
0254     {
0255         return split_;
0256     }
0257 
0258     /** Set whether the header and body are written separately.
0259 
0260         When the split feature is enabled, the implementation will
0261         write only the octets corresponding to the serialized header
0262         first. If the header has already been written, this function
0263         will have no effect on output.
0264     */
0265     void
0266     split(bool v)
0267     {
0268         split_ = v;
0269     }
0270 
0271     /** Return `true` if serialization of the header is complete.
0272 
0273         This function indicates whether or not all buffers containing
0274         serialized header octets have been retrieved.
0275     */
0276     bool
0277     is_header_done()
0278     {
0279         return header_done_;
0280     }
0281 
0282     /** Return `true` if serialization is complete.
0283 
0284         The operation is complete when all octets corresponding
0285         to the serialized representation of the message have been
0286         successfully retrieved.
0287     */
0288     bool
0289     is_done() const
0290     {
0291         return s_ == do_complete;
0292     }
0293 
0294     /** Returns the next set of buffers in the serialization.
0295 
0296         This function will attempt to call the `visit` function
0297         object with a <em>ConstBufferSequence</em> of unspecified type
0298         representing the next set of buffers in the serialization
0299         of the message represented by this object. 
0300 
0301         If there are no more buffers in the serialization, the
0302         visit function will not be called. In this case, no error
0303         will be indicated, and the function @ref is_done will
0304         return `true`.
0305 
0306         @param ec Set to the error, if any occurred.
0307 
0308         @param visit The function to call. The equivalent function
0309         signature of this object must be:
0310         @code
0311             template<class ConstBufferSequence>
0312             void visit(error_code&, ConstBufferSequence const&);
0313         @endcode
0314         The function is not copied, if no error occurs it will be
0315         invoked before the call to @ref next returns.
0316 
0317     */
0318     template<class Visit>
0319     void
0320     next(error_code& ec, Visit&& visit);
0321 
0322     /** Consume buffer octets in the serialization.
0323 
0324         This function should be called after one or more octets
0325         contained in the buffers provided in the prior call
0326         to @ref next have been used.
0327 
0328         After a call to @ref consume, callers should check the
0329         return value of @ref is_done to determine if the entire
0330         message has been serialized.
0331 
0332         @param n The number of octets to consume. This number must
0333         be greater than zero and no greater than the number of
0334         octets in the buffers provided in the prior call to @ref next.
0335     */
0336     void
0337     consume(std::size_t n);
0338 
0339     /** Provides low-level access to the associated <em>BodyWriter</em>
0340 
0341         This function provides access to the instance of the writer
0342         associated with the body and created by the serializer
0343         upon construction. The behavior of accessing this object
0344         is defined by the specification of the particular writer
0345         and its associated body.
0346 
0347         @return A reference to the writer.
0348     */
0349     writer&
0350     writer_impl()
0351     {
0352         return wr_;
0353     }
0354 };
0355 
0356 /// A serializer for HTTP/1 requests
0357 template<class Body, class Fields = fields>
0358 using request_serializer = serializer<true, Body, Fields>;
0359 
0360 /// A serializer for HTTP/1 responses
0361 template<class Body, class Fields = fields>
0362 using response_serializer = serializer<false, Body, Fields>;
0363 
0364 } // http
0365 } // beast
0366 } // boost
0367 
0368 #include <boost/beast/http/impl/serializer.hpp>
0369 
0370 #endif