diff --git a/beast/http/body.h b/beast/http/body.h index 16bf77db0..69ac0b85a 100644 --- a/beast/http/body.h +++ b/beast/http/body.h @@ -50,17 +50,16 @@ public: body (body const&) = delete; body& operator= (body const&) = delete; + template + void + clear(); + void write (void const* data, std::size_t bytes); template void - write (ConstBufferSequence const& buffers) - { - for (auto const& buffer : buffers) - write (boost::asio::buffer_cast (buffer), - boost::asio::buffer_size (buffer)); - } + write (ConstBufferSequence const& buffers); std::size_t size() const; @@ -92,8 +91,9 @@ body::body() inline body::body (body&& other) + : buf_ (std::move(other.buf_)) { - buf_ = std::move(other.buf_); + other.clear(); } inline @@ -101,9 +101,17 @@ body& body::operator= (body&& other) { buf_ = std::move(other.buf_); + other.clear(); return *this; } +template +void +body::clear() +{ + buf_ = std::make_unique (); +} + inline void body::write (void const* data, std::size_t bytes) @@ -112,6 +120,15 @@ body::write (void const* data, std::size_t bytes) boost::asio::const_buffers_1 (data, bytes))); } +template +void +body::write (ConstBufferSequence const& buffers) +{ + for (auto const& buffer : buffers) + write (boost::asio::buffer_cast (buffer), + boost::asio::buffer_size (buffer)); +} + inline std::size_t body::size() const diff --git a/beast/http/message.h b/beast/http/message.h index 9f0ec6a66..66f398784 100644 --- a/beast/http/message.h +++ b/beast/http/message.h @@ -21,7 +21,6 @@ #define BEAST_HTTP_MESSAGE_H_INCLUDED #include -#include #include #include #include @@ -72,9 +71,8 @@ public: #endif - // Memberspaces + // Memberspace beast::http::headers headers; - beast::http::body body; bool request() const @@ -213,7 +211,6 @@ message::message (message&& other) , keep_alive_ (other.keep_alive_) , upgrade_ (other.upgrade_) , headers (std::move(other.headers)) - , body (std::move(other.body)) { } @@ -230,33 +227,32 @@ message::operator= (message&& other) keep_alive_ = other.keep_alive_; upgrade_ = other.upgrade_; headers = std::move(other.headers); - body = std::move(other.body); return *this; } #endif //------------------------------------------------------------------------------ -template +template void -write (AsioStreamBuf& stream, std::string const& s) +write (Streambuf& stream, std::string const& s) { stream.commit (boost::asio::buffer_copy ( stream.prepare (s.size()), boost::asio::buffer(s))); } -template +template void -write (AsioStreamBuf& stream, char const* s) +write (Streambuf& stream, char const* s) { auto const len (::strlen(s)); stream.commit (boost::asio::buffer_copy ( stream.prepare (len), boost::asio::buffer (s, len))); } -template +template void -write (AsioStreamBuf& stream, message const& m) +write (Streambuf& stream, message const& m) { if (m.request()) { @@ -311,4 +307,4 @@ to_string (message const& m) } // http } // beast -#endif \ No newline at end of file +#endif diff --git a/beast/http/parser.h b/beast/http/parser.h index 769f73d92..8d0e8ad81 100644 --- a/beast/http/parser.h +++ b/beast/http/parser.h @@ -21,6 +21,8 @@ #define BEAST_HTTP_PARSER_H_INCLUDED #include +#include +#include #include #include @@ -34,15 +36,33 @@ class parser : public beast::http::basic_parser { private: std::reference_wrapper message_; + std::function write_body_; public: /** Construct a parser for HTTP request or response. - The result is stored in the passed message. + The headers plus request or status line are stored in message. + The content-body, if any, is passed as a series of calls to + the write_body function. Transfer encodings are applied before + any data is passed to the write_body function. */ - parser (message& m, bool request) + parser (std::function write_body, + message& m, bool request) + : beast::http::basic_parser (request) + , message_(m) + , write_body_(std::move(write_body)) + { + message_.get().request(request); + } + + parser (message& m, body& b, bool request) : beast::http::basic_parser (request) , message_(m) { + write_body_ = [&b](void const* data, std::size_t size) + { + b.write(data, size); + }; + message_.get().request(request); } @@ -135,7 +155,7 @@ parser::operator= (parser&& other) template void -parser::do_start () +parser::do_start() { } @@ -176,7 +196,7 @@ template void parser::do_body (void const* data, std::size_t bytes) { - message_.get().body.write (data, bytes); + write_body_(data, bytes); } template diff --git a/beast/http/tests/parser.test.cpp b/beast/http/tests/parser.test.cpp index d81946383..c8e8ace4f 100644 --- a/beast/http/tests/parser.test.cpp +++ b/beast/http/tests/parser.test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace beast { namespace http { @@ -31,7 +32,8 @@ public: request (std::string const& text) { message m; - parser p (m, true); + body b; + parser p (m, b, true); auto result (p.write (boost::asio::buffer(text))); p.write_eof(); return std::make_pair (std::move(m), result.first); @@ -65,7 +67,8 @@ public: "\r\n" ; message m; - parser p (m, true); + body b; + parser p (m, b, true); auto result (p.write (boost::asio::buffer(text))); expect (! result.first); auto result2 (p.write_eof()); @@ -80,7 +83,8 @@ public: "\r\n" ; message m; - parser p (m, true); + body b; + parser p (m, b, true); auto result = p.write (boost::asio::buffer(text)); if (expect (result.first)) expect (result.first.message() == "invalid HTTP method");