// // Copyright (c) 2016-2019 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 // #include #include #include #include #include #include #include #include namespace boost { namespace beast { namespace http { class BodyWriter; class BodyReader; //[concept_Body struct Body { // The type of message::body when used struct value_type; /// The algorithm used during parsing class reader; /// The algorithm used during serialization class writer; /// Returns the body's payload size static std::uint64_t size(value_type const& body); }; static_assert(is_body::value, ""); //] struct Body_BodyWriter { struct value_type{}; //[concept_BodyWriter struct BodyWriter { public: /// The type of buffer returned by `get`. using const_buffers_type = net::const_buffer; /** Construct the writer. @param h The header for the message being serialized @param body The body being serialized */ template BodyWriter(header const& h, value_type const& body); /** Initialize the writer. This is called after construction and before the first call to `get`. The message is valid and complete upon entry. @param ec Set to the error, if any occurred. */ void init(error_code& ec) { // The specification requires this to indicate "no error" ec = {}; } /** Returns the next buffer in the body. @li If the return value is `boost::none` (unseated optional) and `ec` does not contain an error, this indicates the end of the body, no more buffers are present. @li If the optional contains a value, the first element of the pair represents a ConstBufferSequence containing one or more octets of the body data. The second element indicates whether or not there are additional octets of body data. A value of `true` means there is more data, and that the implementation will perform a subsequent call to `get`. A value of `false` means there is no more body data. @li If `ec` contains an error code, the return value is ignored. @param ec Set to the error, if any occurred. */ boost::optional> get(error_code& ec) { // The specification requires this to indicate "no error" ec = {}; return boost::none; // for exposition only } }; //] using writer = BodyWriter; }; static_assert(is_body_writer::value, ""); struct Body_BodyReader { struct value_type{}; //[concept_BodyReader struct BodyReader { /** Construct the reader. @param h The header for the message being parsed @param body The body to store the parsed results into */ template BodyReader(header& h, value_type& body); /** Initialize the reader. This is called after construction and before the first call to `put`. The message is valid and complete upon entry. @param ec Set to the error, if any occurred. */ void init( boost::optional const& content_length, error_code& ec) { boost::ignore_unused(content_length); // The specification requires this to indicate "no error" ec = {}; } /** Store buffers. This is called zero or more times with parsed body octets. @param buffers The constant buffer sequence to store. @param ec Set to the error, if any occurred. @return The number of bytes transferred from the input buffers. */ template std::size_t put(ConstBufferSequence const& buffers, error_code& ec) { // The specification requires this to indicate "no error" ec = {}; return buffer_bytes(buffers); } /** Called when the body is complete. @param ec Set to the error, if any occurred. */ void finish(error_code& ec) { // The specification requires this to indicate "no error" ec = {}; } }; //] using reader = BodyReader; }; static_assert(is_body_reader::value, ""); //[concept_Fields class Fields { public: /// Constructed as needed when fields are serialized struct writer; protected: /** Returns the request-method string. @note Only called for requests. */ string_view get_method_impl() const; /** Returns the request-target string. @note Only called for requests. */ string_view get_target_impl() const; /** Returns the response reason-phrase string. @note Only called for responses. */ string_view get_reason_impl() const; /** Returns the chunked Transfer-Encoding setting */ bool get_chunked_impl() const; /** Returns the keep-alive setting */ bool get_keep_alive_impl(unsigned version) const; /** Returns `true` if the Content-Length field is present. */ bool has_content_length_impl() const; /** Set or clear the method string. @note Only called for requests. */ void set_method_impl(string_view s); /** Set or clear the target string. @note Only called for requests. */ void set_target_impl(string_view s); /** Set or clear the reason string. @note Only called for responses. */ void set_reason_impl(string_view s); /** Sets or clears the chunked Transfer-Encoding value */ void set_chunked_impl(bool value); /** Sets or clears the Content-Length field */ void set_content_length_impl(boost::optional); /** Adjusts the Connection field */ void set_keep_alive_impl(unsigned version, bool keep_alive); }; static_assert(is_fields::value, "Fields type requirements not met"); //] struct Fields_FieldsWriter { using Fields = Fields_FieldsWriter; //[concept_FieldsWriter struct FieldsWriter { // The type of buffers returned by `get` struct const_buffers_type; // Constructor for requests FieldsWriter(Fields const& f, unsigned version, verb method); // Constructor for responses FieldsWriter(Fields const& f, unsigned version, unsigned status); // Returns the serialized header buffers const_buffers_type get(); }; //] }; //[concept_File struct File { /** Default constructor There is no open file initially. */ File(); /** Destructor If the file is open it is first closed. */ ~File(); /// Returns `true` if the file is open bool is_open() const; /// Close the file if open void close(error_code& ec); /// Open a file at the given path with the specified mode void open(char const* path, file_mode mode, error_code& ec); /// Return the size of the open file std::uint64_t size(error_code& ec) const; /// Return the current position in the open file std::uint64_t pos(error_code& ec) const; /// Adjust the current position in the open file void seek(std::uint64_t offset, error_code& ec); /// Read from the open file std::size_t read(void* buffer, std::size_t n, error_code& ec) const; /// Write to the open file std::size_t write(void const* buffer, std::size_t n, error_code& ec); }; //] } // http } // beast } // boost