123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- //
- // 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 <boost/beast/core/buffer_traits.hpp>
- #include <boost/beast/core/error.hpp>
- #include <boost/beast/core/file_base.hpp>
- #include <boost/beast/http/message.hpp>
- #include <boost/beast/http/type_traits.hpp>
- #include <boost/optional.hpp>
- #include <cstdint>
- #include <utility>
- 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<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<bool isRequest, class Fields>
- BodyWriter(header<isRequest, Fields> 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 <em>ConstBufferSequence</em> 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<std::pair<const_buffers_type, bool>>
- 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<Body_BodyWriter>::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<bool isRequest, class Fields>
- BodyReader(header<isRequest, Fields>& 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<std::uint64_t> 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<class ConstBufferSequence>
- 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<Body_BodyReader>::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<std::uint64_t>);
- /** Adjusts the Connection field
- */
- void
- set_keep_alive_impl(unsigned version, bool keep_alive);
- };
- static_assert(is_fields<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
|