diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b3e317..7b3e1246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,16 @@ API Changes: * WebSocket writes return the bytes transferred +* HTTP reads and writes return bytes transferred + Actions Required: * Modify websocket write completion handlers to receive the extra std::size_t bytes_transferred parameter. +* Modify HTTP read and/or write completion handlers to + receive the extra std::size_t bytes_transferred parameter. + -------------------------------------------------------------------------------- Version 111: diff --git a/doc/qbk/04_http/03_streams.qbk b/doc/qbk/04_http/03_streams.qbk index 69c9b6cc..9b7854ab 100644 --- a/doc/qbk/04_http/03_streams.qbk +++ b/doc/qbk/04_http/03_streams.qbk @@ -72,8 +72,11 @@ Messages may also be read asynchronously. When performing asynchronous stream read operations the stream, buffer, and message variables must remain valid until the operation has completed. Beast asynchronous initiation functions use Asio's completion handler model. This call -reads a message asynchronously and report the error code upon -completion: +reads a message asynchronously and reports the error code upon +completion. The handler is called with the error, set to any that +occurs, and the number of bytes parsed. This number may be used to +measure the relative amount of work performed, or it may be ignored +as this example shows. [http_snippet_5] @@ -106,4 +109,9 @@ The asynchronous version could be used instead: [http_snippet_8] +The completion handler is called with the number of bytes written to the +stream, which includes protocol specific data such as the delimiters in +the header and line endings. The number may be used to measure the amount +of data transferred, or it may be ignored as in the example. + [endsect] diff --git a/example/http/client/async-ssl/http_client_async_ssl.cpp b/example/http/client/async-ssl/http_client_async_ssl.cpp index 5c39086f..11026ab6 100644 --- a/example/http/client/async-ssl/http_client_async_ssl.cpp +++ b/example/http/client/async-ssl/http_client_async_ssl.cpp @@ -125,12 +125,17 @@ public: std::bind( &session::on_write, shared_from_this(), - std::placeholders::_1)); + std::placeholders::_1, + std::placeholders::_2)); } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) return fail(ec, "write"); @@ -139,12 +144,17 @@ public: std::bind( &session::on_read, shared_from_this(), - std::placeholders::_1)); + std::placeholders::_1, + std::placeholders::_2)); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) return fail(ec, "read"); diff --git a/example/http/client/async/http_client_async.cpp b/example/http/client/async/http_client_async.cpp index 1e191002..6fab9c81 100644 --- a/example/http/client/async/http_client_async.cpp +++ b/example/http/client/async/http_client_async.cpp @@ -104,12 +104,17 @@ public: std::bind( &session::on_write, shared_from_this(), - std::placeholders::_1)); + std::placeholders::_1, + std::placeholders::_2)); } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) return fail(ec, "write"); @@ -118,12 +123,17 @@ public: std::bind( &session::on_read, shared_from_this(), - std::placeholders::_1)); + std::placeholders::_1, + std::placeholders::_2)); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) return fail(ec, "read"); diff --git a/example/http/client/crawl/http_crawl.cpp b/example/http/client/crawl/http_crawl.cpp index c8a1d8f6..6e492c7a 100644 --- a/example/http/client/crawl/http_crawl.cpp +++ b/example/http/client/crawl/http_crawl.cpp @@ -297,12 +297,17 @@ public: strand_.wrap(std::bind( &worker::on_write, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) { report_.aggregate( @@ -324,12 +329,17 @@ public: strand_.wrap(std::bind( &worker::on_read, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec) { report_.aggregate( diff --git a/example/http/server/async-ssl/http_server_async_ssl.cpp b/example/http/server/async-ssl/http_server_async_ssl.cpp index c33979c8..4dff6ed4 100644 --- a/example/http/server/async-ssl/http_server_async_ssl.cpp +++ b/example/http/server/async-ssl/http_server_async_ssl.cpp @@ -247,7 +247,8 @@ class session : public std::enable_shared_from_this self_.strand_.wrap(std::bind( &session::on_write, self_.shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } }; @@ -305,12 +306,17 @@ public: strand_.wrap(std::bind( &session::on_read, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + // This means they closed the connection if(ec == http::error::end_of_stream) return do_close(); @@ -323,8 +329,12 @@ public: } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec == http::error::end_of_stream) { // This means we should close the connection, usually because diff --git a/example/http/server/async/http_server_async.cpp b/example/http/server/async/http_server_async.cpp index 5564db29..5c3f96e6 100644 --- a/example/http/server/async/http_server_async.cpp +++ b/example/http/server/async/http_server_async.cpp @@ -243,7 +243,8 @@ class session : public std::enable_shared_from_this self_.strand_.wrap(std::bind( &session::on_write, self_.shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } }; @@ -283,12 +284,17 @@ public: strand_.wrap(std::bind( &session::on_read, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + // This means they closed the connection if(ec == http::error::end_of_stream) return do_close(); @@ -301,8 +307,12 @@ public: } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec == http::error::end_of_stream) { // This means we should close the connection, usually because diff --git a/example/http/server/fast/http_server_fast.cpp b/example/http/server/fast/http_server_fast.cpp index 5081d29d..e470c508 100644 --- a/example/http/server/fast/http_server_fast.cpp +++ b/example/http/server/fast/http_server_fast.cpp @@ -172,7 +172,7 @@ private: socket_, buffer_, *parser_, - [this](boost::beast::error_code ec) + [this](boost::beast::error_code ec, std::size_t) { if (ec) accept(); @@ -220,7 +220,7 @@ private: http::async_write( socket_, *string_serializer_, - [this](boost::beast::error_code ec) + [this](boost::beast::error_code ec, std::size_t) { socket_.shutdown(tcp::socket::shutdown_send, ec); string_serializer_.reset(); @@ -276,7 +276,7 @@ private: http::async_write( socket_, *file_serializer_, - [this](boost::beast::error_code ec) + [this](boost::beast::error_code ec, std::size_t) { socket_.shutdown(tcp::socket::shutdown_send, ec); file_serializer_.reset(); diff --git a/example/http/server/flex/http_server_flex.cpp b/example/http/server/flex/http_server_flex.cpp index 1607a1b8..85749ad5 100644 --- a/example/http/server/flex/http_server_flex.cpp +++ b/example/http/server/flex/http_server_flex.cpp @@ -258,7 +258,8 @@ class session self_.strand_.wrap(std::bind( &session::on_write, self_.derived().shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } }; @@ -296,12 +297,17 @@ public: strand_.wrap(std::bind( &session::on_read, derived().shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } void - on_read(boost::system::error_code ec) + on_read( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + // This means they closed the connection if(ec == http::error::end_of_stream) return derived().do_eof(); @@ -314,8 +320,12 @@ public: } void - on_write(boost::system::error_code ec) + on_write( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + if(ec == http::error::end_of_stream) { // This means we should close the connection, usually because diff --git a/example/http/server/small/http_server_small.cpp b/example/http/server/small/http_server_small.cpp index 4aad278d..8ed8d422 100644 --- a/example/http/server/small/http_server_small.cpp +++ b/example/http/server/small/http_server_small.cpp @@ -87,8 +87,10 @@ private: socket_, buffer_, request_, - [self](boost::beast::error_code ec) + [self](boost::beast::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); if(!ec) self->process_request(); }); @@ -175,7 +177,7 @@ private: http::async_write( socket_, response_, - [self](boost::beast::error_code ec) + [self](boost::beast::error_code ec, std::size_t) { self->socket_.shutdown(tcp::socket::shutdown_send, ec); self->deadline_.cancel(); diff --git a/example/http/server/stackless-ssl/http_server_stackless_ssl.cpp b/example/http/server/stackless-ssl/http_server_stackless_ssl.cpp index 3b04fe95..c7386e4b 100644 --- a/example/http/server/stackless-ssl/http_server_stackless_ssl.cpp +++ b/example/http/server/stackless-ssl/http_server_stackless_ssl.cpp @@ -250,7 +250,8 @@ class session self_.strand_.wrap(std::bind( &session::loop, self_.shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } }; @@ -282,13 +283,16 @@ public: void run() { - loop(); + loop({}, 0); } #include void - loop(boost::system::error_code ec = {}) + loop( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); reenter(*this) { // Perform the SSL handshake @@ -297,7 +301,8 @@ public: strand_.wrap(std::bind( &session::loop, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + 0))); if(ec) return fail(ec, "handshake"); @@ -308,7 +313,8 @@ public: strand_.wrap(std::bind( &session::loop, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); if(ec == http::error::end_of_stream) { // The remote host closed the connection @@ -337,7 +343,8 @@ public: strand_.wrap(std::bind( &session::loop, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + 0))); if(ec) return fail(ec, "shutdown"); diff --git a/example/http/server/stackless/http_server_stackless.cpp b/example/http/server/stackless/http_server_stackless.cpp index 3ffa3a5b..4db45ab2 100644 --- a/example/http/server/stackless/http_server_stackless.cpp +++ b/example/http/server/stackless/http_server_stackless.cpp @@ -247,7 +247,8 @@ class session self_.strand_.wrap(std::bind( &session::loop, self_.shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); } }; @@ -276,13 +277,16 @@ public: void run() { - loop(); + loop({}, 0); } #include void - loop(boost::system::error_code ec = {}) + loop( + boost::system::error_code ec, + std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); reenter(*this) { for(;;) @@ -292,7 +296,8 @@ public: strand_.wrap(std::bind( &session::loop, shared_from_this(), - std::placeholders::_1))); + std::placeholders::_1, + std::placeholders::_2))); if(ec == http::error::end_of_stream) { // The remote host closed the connection diff --git a/include/boost/beast/http/impl/file_body_win32.ipp b/include/boost/beast/http/impl/file_body_win32.ipp index ec200a7b..c1191538 100644 --- a/include/boost/beast/http/impl/file_body_win32.ipp +++ b/include/boost/beast/http/impl/file_body_win32.ipp @@ -58,7 +58,7 @@ struct basic_file_body template< class Protocol, bool isRequest, class Fields> friend - void + std::size_t write_some( boost::asio::basic_stream_socket& sock, serializer template< class Protocol, bool isRequest, class Fields> friend - void + std::size_t write_some( boost::asio::basic_stream_socket& sock, serializer& sock_; serializer, Fields>& sr_; - bool header_ = false; + std::size_t bytes_transferred_ = 0; Handler h_; + bool header_ = false; public: write_some_win32_op(write_some_win32_op&&) = default; @@ -363,7 +364,8 @@ public: operator()(); void - operator()(error_code ec, + operator()( + error_code ec, std::size_t bytes_transferred = 0); friend @@ -445,7 +447,8 @@ operator()() if(! bSuccess && dwError != boost::detail::winapi::ERROR_IO_PENDING_) { - // completed immediately + // VFALCO This needs review, is 0 the right number? + // completed immediately (with error?) overlapped.complete(error_code{static_cast( boost::detail::winapi::GetLastError()), system_category()}, 0); @@ -460,8 +463,10 @@ template< void write_some_win32_op< Protocol, Handler, isRequest, Fields>:: -operator()(error_code ec, std::size_t bytes_transferred) +operator()( + error_code ec, std::size_t bytes_transferred) { + bytes_transferred_ += bytes_transferred; if(! ec) { if(header_) @@ -481,7 +486,7 @@ operator()(error_code ec, std::size_t bytes_transferred) ec = error::end_of_stream; } } - h_(ec); + h_(ec, bytes_transferred_); } #endif @@ -491,7 +496,7 @@ operator()(error_code ec, std::size_t bytes_transferred) //------------------------------------------------------------------------------ template -void +std::size_t write_some( boost::asio::basic_stream_socket& sock, serializer( beast::detail::clamp(std::min( @@ -535,7 +542,7 @@ write_some( ec.assign(static_cast( boost::detail::winapi::GetLastError()), system_category()); - return; + return 0; } r.pos_ += nNumberOfBytesToWrite; BOOST_ASSERT(r.pos_ <= r.body_.last_); @@ -551,6 +558,7 @@ write_some( if(! sr.keep_alive()) ec = error::end_of_stream; } + return nNumberOfBytesToWrite; } #if BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR @@ -559,7 +567,9 @@ template< class Protocol, bool isRequest, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write_some( boost::asio::basic_stream_socket& sock, serializer init{handler}; - detail::write_some_win32_op, isRequest, Fields>{ + detail::write_some_win32_op< + Protocol, + handler_type, + isRequest, Fields>{ init.completion_handler, sock, sr}(); return init.result.get(); } diff --git a/include/boost/beast/http/impl/read.ipp b/include/boost/beast/http/impl/read.ipp index 7a494a5c..21dce0a5 100644 --- a/include/boost/beast/http/impl/read.ipp +++ b/include/boost/beast/http/impl/read.ipp @@ -44,7 +44,7 @@ class read_some_op basic_parser& p_; boost::optional mb_; - std::size_t used_ = 0; + std::size_t bytes_transferred_ = 0; Handler h_; public: @@ -62,7 +62,9 @@ public: } void - operator()(error_code ec, std::size_t bytes_transferred); + operator()( + error_code ec = {}, + std::size_t bytes_transferred = 0); friend void* asio_handler_allocate( @@ -106,7 +108,9 @@ template:: -operator()(error_code ec, std::size_t bytes_transferred) +operator()( + error_code ec, + std::size_t bytes_transferred) { switch(state_) { @@ -142,7 +146,7 @@ operator()(error_code ec, std::size_t bytes_transferred) do_parse: { auto const used = p_.put(b_.data(), ec); - used_ += used; + bytes_transferred_ += used; b_.consume(used); if(! ec || ec != http::error::need_more) goto do_upcall; @@ -173,7 +177,7 @@ operator()(error_code ec, std::size_t bytes_transferred) break; } upcall: - h_(ec, used_); + h_(ec, bytes_transferred_); } //------------------------------------------------------------------------------ @@ -209,6 +213,7 @@ class read_op Stream& s_; DynamicBuffer& b_; basic_parser& p_; + std::size_t bytes_transferred_ = 0; Handler h_; public: @@ -228,7 +233,8 @@ public: void operator()( - error_code ec, std::size_t bytes_used = 0); + error_code ec = {}, + std::size_t bytes_transferred = 0); friend void* asio_handler_allocate( @@ -273,7 +279,9 @@ template:: -operator()(error_code ec, std::size_t) +operator()( + error_code ec, + std::size_t bytes_transferred) { switch(state_) { @@ -297,13 +305,14 @@ operator()(error_code ec, std::size_t) case 3: if(ec) goto upcall; + bytes_transferred_ += bytes_transferred; if(Condition{}(p_)) goto upcall; state_ = 3; goto do_read; } upcall: - h_(ec); + h_(ec, bytes_transferred_); } //------------------------------------------------------------------------------ @@ -326,6 +335,7 @@ class read_msg_op DynamicBuffer& b; message_type& m; parser_type p; + std::size_t bytes_transferred = 0; data(Handler&, Stream& s_, DynamicBuffer& b_, message_type& m_) @@ -353,7 +363,8 @@ public: void operator()( - error_code ec, std::size_t bytes_used = 0); + error_code ec = {}, + std::size_t bytes_transferred = 0); friend void* asio_handler_allocate( @@ -398,7 +409,9 @@ template:: -operator()(error_code ec, std::size_t) +operator()( + error_code ec, + std::size_t bytes_transferred) { auto& d = *d_; switch(d.state) @@ -414,6 +427,8 @@ operator()(error_code ec, std::size_t) case 2: if(ec) goto upcall; + d.bytes_transferred += + bytes_transferred; if(d.p.is_done()) { d.m = d.p.release(); @@ -423,7 +438,8 @@ operator()(error_code ec, std::size_t) goto do_read; } upcall: - d_.invoke(ec); + bytes_transferred = d.bytes_transferred; + d_.invoke(ec, bytes_transferred); } } // detail @@ -446,11 +462,11 @@ read_some( "DynamicBuffer requirements not met"); BOOST_ASSERT(! parser.is_done()); error_code ec; - auto const bytes_used = read_some( - stream, buffer, parser, ec); + auto const bytes_transferred = + read_some(stream, buffer, parser, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); - return bytes_used; + return bytes_transferred; } template< @@ -469,16 +485,16 @@ read_some( static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); BOOST_ASSERT(! parser.is_done()); - std::size_t bytes_used = 0; + std::size_t bytes_transferred = 0; if(buffer.size() == 0) goto do_read; for(;;) { // invoke parser { - auto const used = parser.put(buffer.data(), ec); - bytes_used += used; - buffer.consume(used); + auto const n = parser.put(buffer.data(), ec); + bytes_transferred += n; + buffer.consume(n); if(! ec) break; if(ec != http::error::need_more) @@ -495,13 +511,12 @@ read_some( catch(std::length_error const&) { ec = error::buffer_overflow; - return bytes_used; + return bytes_transferred; } - auto const bytes_transferred = - stream.read_some(*b, ec); + auto const n = stream.read_some(*b, ec); if(ec == boost::asio::error::eof) { - BOOST_ASSERT(bytes_transferred == 0); + BOOST_ASSERT(n == 0); if(parser.got_some()) { // caller sees EOF on next read @@ -516,9 +531,9 @@ read_some( } if(ec) break; - buffer.commit(bytes_transferred); + buffer.commit(n); } - return bytes_used; + return bytes_transferred; } template< @@ -543,8 +558,7 @@ async_read_some( detail::read_some_op>{ - init.completion_handler, stream, buffer, parser}( - error_code{}, 0); + init.completion_handler, stream, buffer, parser}(); return init.result.get(); } @@ -554,7 +568,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_header( SyncReadStream& stream, DynamicBuffer& buffer, @@ -565,16 +579,18 @@ read_header( static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); error_code ec; - read_header(stream, buffer, parser, ec); + auto const bytes_transferred = + read_header(stream, buffer, parser, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_header( SyncReadStream& stream, DynamicBuffer& buffer, @@ -589,15 +605,18 @@ read_header( if(parser.is_header_done()) { ec.assign(0, ec.category()); - return; + return 0; } + std::size_t bytes_transferred = 0; do { - read_some(stream, buffer, parser, ec); + bytes_transferred += read_some( + stream, buffer, parser, ec); if(ec) - return; + return bytes_transferred; } while(! parser.is_header_done()); + return bytes_transferred; } template< @@ -605,7 +624,9 @@ template< class DynamicBuffer, bool isRequest, class Derived, class ReadHandler> -async_return_type +async_return_type< + ReadHandler, + void(error_code, std::size_t)> async_read_header( AsyncReadStream& stream, DynamicBuffer& buffer, @@ -621,9 +642,8 @@ async_read_header( void(error_code)> init{handler}; detail::read_op>{ - init.completion_handler, stream, buffer, parser}( - error_code{}); + handler_type>{ + init.completion_handler, stream, buffer, parser}(); return init.result.get(); } @@ -633,7 +653,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -644,16 +664,18 @@ read( static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); error_code ec; - read(stream, buffer, parser, ec); + auto const bytes_transferred = + read(stream, buffer, parser, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -668,15 +690,18 @@ read( if(parser.is_done()) { ec.assign(0, ec.category()); - return; + return 0; } + std::size_t bytes_transferred = 0; do { - read_some(stream, buffer, parser, ec); + bytes_transferred += read_some( + stream, buffer, parser, ec); if(ec) - return; + return bytes_transferred; } while(! parser.is_done()); + return bytes_transferred; } template< @@ -684,7 +709,9 @@ template< class DynamicBuffer, bool isRequest, class Derived, class ReadHandler> -async_return_type +async_return_type< + ReadHandler, + void(error_code, std::size_t)> async_read( AsyncReadStream& stream, DynamicBuffer& buffer, @@ -696,13 +723,13 @@ async_read( static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); parser.eager(true); - async_completion init{handler}; + async_completion< + ReadHandler, + void(error_code, std::size_t)> init{handler}; detail::read_op>{ - init.completion_handler, stream, buffer, parser}( - error_code{}); + handler_type>{ + init.completion_handler, stream, buffer, parser}(); return init.result.get(); } @@ -712,7 +739,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Body, class Allocator> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -727,16 +754,18 @@ read( static_assert(is_body_writer::value, "BodyWriter requirements not met"); error_code ec; - read(stream, buffer, msg, ec); + auto const bytes_transferred = + read(stream, buffer, msg, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Body, class Allocator> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -753,10 +782,12 @@ read( "BodyWriter requirements not met"); parser p{std::move(msg)}; p.eager(true); - read(stream, buffer, p.base(), ec); + auto const bytes_transferred = + read(stream, buffer, p.base(), ec); if(ec) - return; + return bytes_transferred; msg = p.release(); + return bytes_transferred; } template< @@ -764,7 +795,9 @@ template< class DynamicBuffer, bool isRequest, class Body, class Allocator, class ReadHandler> -async_return_type +async_return_type< + ReadHandler, + void(error_code, std::size_t)> async_read( AsyncReadStream& stream, DynamicBuffer& buffer, @@ -779,13 +812,16 @@ async_read( "Body requirements not met"); static_assert(is_body_writer::value, "BodyWriter requirements not met"); - async_completion init{handler}; - detail::read_msg_op>{ - init.completion_handler, stream, buffer, msg}( - error_code{}); + async_completion< + ReadHandler, + void(error_code, std::size_t)> init{handler}; + detail::read_msg_op< + AsyncReadStream, + DynamicBuffer, + isRequest, Body, Allocator, + handler_type>{ + init.completion_handler, stream, buffer, msg}(); return init.result.get(); } diff --git a/include/boost/beast/http/impl/write.ipp b/include/boost/beast/http/impl/write.ipp index 4388cb22..5ce7ee90 100644 --- a/include/boost/beast/http/impl/write.ipp +++ b/include/boost/beast/http/impl/write.ipp @@ -81,7 +81,8 @@ public: operator()(); void - operator()(error_code ec, + operator()( + error_code ec, std::size_t bytes_transferred); friend @@ -167,7 +168,7 @@ operator()( if(! sr_.keep_alive()) ec = error::end_of_stream; } - h_(ec); + h_(ec, bytes_transferred); } //------------------------------------------------------------------------------ @@ -206,6 +207,7 @@ class write_op int state_ = 0; Stream& s_; serializer& sr_; + std::size_t bytes_transferred_ = 0; Handler h_; public: @@ -222,7 +224,9 @@ public: } void - operator()(error_code ec); + operator()( + error_code ec = {}, + std::size_t bytes_transferred = 0); friend void* asio_handler_allocate( @@ -267,7 +271,8 @@ template< void write_op:: -operator()(error_code ec) +operator()( + error_code ec, std::size_t bytes_transferred) { if(ec) goto upcall; @@ -279,7 +284,7 @@ operator()(error_code ec) { state_ = 1; return s_.get_io_service().post( - bind_handler(std::move(*this), ec)); + bind_handler(std::move(*this), ec, 0)); } state_ = 2; return beast::http::async_write_some( @@ -295,6 +300,7 @@ operator()(error_code ec) case 3: { + bytes_transferred_ += bytes_transferred; if(Predicate{}(sr_)) goto upcall; return beast::http::async_write_some( @@ -302,7 +308,7 @@ operator()(error_code ec) } } upcall: - h_(ec); + h_(ec, bytes_transferred_); } //------------------------------------------------------------------------------ @@ -341,7 +347,8 @@ public: operator()(); void - operator()(error_code ec); + operator()( + error_code ec, std::size_t bytes_transferred); friend void* asio_handler_allocate( @@ -395,9 +402,9 @@ template:: -operator()(error_code ec) +operator()(error_code ec, std::size_t bytes_transferred) { - d_.invoke(ec); + d_.invoke(ec, bytes_transferred); } //------------------------------------------------------------------------------ @@ -454,16 +461,10 @@ public: } }; -} // detail - -//------------------------------------------------------------------------------ - -namespace detail { - template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_some( SyncWriteStream& stream, serializer& sr, @@ -474,45 +475,53 @@ write_some( write_some_lambda f{stream}; sr.next(ec, f); if(ec) - return; + return f.bytes_transferred; if(f.invoked) sr.consume(f.bytes_transferred); if(sr.is_done()) if(! sr.keep_alive()) ec = error::end_of_stream; - return; + return f.bytes_transferred; } if(! sr.keep_alive()) ec = error::end_of_stream; else ec.assign(0, ec.category()); + return 0; } template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write_some( AsyncWriteStream& stream, serializer& sr, WriteHandler&& handler) { - async_completion init{handler}; - detail::write_some_op, - isRequest, Body, Fields>{ - init.completion_handler, stream, sr}(); + async_completion< + WriteHandler, + void(error_code, std::size_t)> init{handler}; + detail::write_some_op< + AsyncWriteStream, + handler_type, + isRequest, Body, Fields>{ + init.completion_handler, stream, sr}(); return init.result.get(); } } // detail +//------------------------------------------------------------------------------ + template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_some( SyncWriteStream& stream, serializer& sr) @@ -524,15 +533,17 @@ write_some( static_assert(is_body_reader::value, "BodyReader requirements not met"); error_code ec; - write_some(stream, sr, ec); + auto const bytes_transferred = + write_some(stream, sr, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_some( SyncWriteStream& stream, serializer& sr, @@ -544,14 +555,16 @@ write_some( "Body requirements not met"); static_assert(is_body_reader::value, "BodyReader requirements not met"); - detail::write_some(stream, sr, ec); + return detail::write_some(stream, sr, ec); } template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write_some( AsyncWriteStream& stream, serializer& sr, @@ -573,7 +586,7 @@ async_write_some( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_header(SyncWriteStream& stream, serializer& sr) { @@ -584,15 +597,17 @@ write_header(SyncWriteStream& stream, static_assert(is_body_reader::value, "BodyReader requirements not met"); error_code ec; - write_header(stream, sr, ec); + auto const bytes_transferred = + write_header(stream, sr, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_header( SyncWriteStream& stream, serializer& sr, @@ -605,14 +620,16 @@ write_header( static_assert(is_body_reader::value, "BodyReader requirements not met"); sr.split(true); + std::size_t bytes_transferred = 0; if(! sr.is_header_done()) { detail::write_lambda f{stream}; do { sr.next(ec, f); + bytes_transferred += f.bytes_transferred; if(ec) - return; + return bytes_transferred; BOOST_ASSERT(f.invoked); sr.consume(f.bytes_transferred); } @@ -622,13 +639,16 @@ write_header( { ec.assign(0, ec.category()); } + return bytes_transferred; } template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write_header( AsyncWriteStream& stream, serializer& sr, @@ -642,14 +662,16 @@ async_write_header( static_assert(is_body_reader::value, "BodyReader requirements not met"); sr.split(true); - async_completion init{handler}; - detail::write_op, - detail::serializer_is_header_done, - isRequest, Body, Fields>{ - init.completion_handler, stream, sr}( - error_code{}); + async_completion< + WriteHandler, + void(error_code, std::size_t)> init{handler}; + detail::write_op< + AsyncWriteStream, + handler_type, + detail::serializer_is_header_done, + isRequest, Body, Fields>{ + init.completion_handler, stream, sr}(); return init.result.get(); } @@ -658,7 +680,7 @@ async_write_header( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, serializer& sr) @@ -666,15 +688,17 @@ write( static_assert(is_sync_write_stream::value, "SyncWriteStream requirements not met"); error_code ec; - write(stream, sr, ec); + auto const bytes_transferred = + write(stream, sr, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, serializer& sr, @@ -682,22 +706,27 @@ write( { static_assert(is_sync_write_stream::value, "SyncWriteStream requirements not met"); + std::size_t bytes_transferred = 0; sr.split(false); for(;;) { - write_some(stream, sr, ec); + bytes_transferred += + write_some(stream, sr, ec); if(ec) - return; + return bytes_transferred; if(sr.is_done()) break; } + return bytes_transferred; } template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write( AsyncWriteStream& stream, serializer& sr, @@ -711,12 +740,16 @@ async_write( static_assert(is_body_reader::value, "BodyReader requirements not met"); sr.split(false); - async_completion init{handler}; - detail::write_op, - detail::serializer_is_done, isRequest, Body, Fields>{ - init.completion_handler, stream, sr}(error_code{}); + async_completion< + WriteHandler, + void(error_code, std::size_t)> init{handler}; + detail::write_op< + AsyncWriteStream, + handler_type, + detail::serializer_is_done, + isRequest, Body, Fields>{ + init.completion_handler, stream, sr}(); return init.result.get(); } @@ -725,7 +758,7 @@ async_write( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, message const& msg) @@ -737,15 +770,17 @@ write( static_assert(is_body_reader::value, "BodyReader requirements not met"); error_code ec; - write(stream, msg, ec); + auto const bytes_transferred = + write(stream, msg, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_transferred; } template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, message const& msg, @@ -758,7 +793,7 @@ write( static_assert(is_body_reader::value, "BodyReader requirements not met"); serializer sr{msg}; - write(stream, sr, ec); + return write(stream, sr, ec); } template< @@ -766,7 +801,8 @@ template< bool isRequest, class Body, class Fields, class WriteHandler> async_return_type< - WriteHandler, void(error_code)> + WriteHandler, + void(error_code, std::size_t)> async_write( AsyncWriteStream& stream, message& msg, @@ -779,12 +815,15 @@ async_write( "Body requirements not met"); static_assert(is_body_reader::value, "BodyReader requirements not met"); - async_completion init{handler}; - detail::write_msg_op, isRequest, - Body, Fields>{init.completion_handler, - stream, msg}(); + async_completion< + WriteHandler, + void(error_code, std::size_t)> init{handler}; + detail::write_msg_op< + AsyncWriteStream, + handler_type, + isRequest, Body, Fields>{ + init.completion_handler, stream, msg}(); return init.result.get(); } diff --git a/include/boost/beast/http/read.hpp b/include/boost/beast/http/read.hpp index 8181853f..91fa7937 100644 --- a/include/boost/beast/http/read.hpp +++ b/include/boost/beast/http/read.hpp @@ -59,7 +59,7 @@ namespace http { @param parser The parser to use. - @return The number of bytes consumed by the parser. + @return The number of bytes transferred to the parser. @throws system_error Thrown on failure. */ @@ -118,7 +118,7 @@ read_some( @param ec Set to the error, if any occurred. - @return The number of bytes consumed by the parser. + @return The number of bytes transferred to the parser. */ template< class SyncReadStream, @@ -179,8 +179,8 @@ read_some( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error, // result of operation - std::size_t bytes_used // the number of bytes consumed by the parser + error_code const& error, // result of operation + std::size_t bytes_transferred // the number of bytes transferred to the parser ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -249,6 +249,8 @@ async_read_some( @param parser The parser to use. + @return The number of bytes transferred to the parser. + @throws system_error Thrown on failure. @note The implementation will call @ref basic_parser::eager @@ -258,7 +260,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_header( SyncReadStream& stream, DynamicBuffer& buffer, @@ -304,6 +306,8 @@ read_header( @param ec Set to the error, if any occurred. + @return The number of bytes transferred to the parser. + @note The implementation will call @ref basic_parser::eager with the value `false` on the parser passed in. */ @@ -311,7 +315,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_header( SyncReadStream& stream, DynamicBuffer& buffer, @@ -365,7 +369,8 @@ read_header( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation, + std::size_t bytes_transferred // the number of bytes transferred to the parser ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -384,7 +389,7 @@ template< void_or_deduced #else async_return_type< - ReadHandler, void(error_code)> + ReadHandler, void(error_code, std::size_t)> #endif async_read_header( AsyncReadStream& stream, @@ -432,6 +437,8 @@ async_read_header( @param parser The parser to use. + @return The number of bytes transferred to the parser. + @throws system_error Thrown on failure. @note The implementation will call @ref basic_parser::eager @@ -441,7 +448,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -487,6 +494,8 @@ read( @param ec Set to the error, if any occurred. + @return The number of bytes transferred to the parser. + @note The implementation will call @ref basic_parser::eager with the value `true` on the parser passed in. */ @@ -494,7 +503,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -548,7 +557,8 @@ read( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation, + std::size_t bytes_transferred // the number of bytes transferred to the parser ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -567,7 +577,8 @@ template< void_or_deduced #else async_return_type< - ReadHandler, void(error_code)> + ReadHandler, + void(error_code, std::size_t)> #endif async_read( AsyncReadStream& stream, @@ -617,13 +628,15 @@ async_read( the behavior is undefined. The type must be @b MoveAssignable and @b MoveConstructible. + @return The number of bytes transferred to the parser. + @throws system_error Thrown on failure. */ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Body, class Allocator> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -670,12 +683,14 @@ read( The type must be @b MoveAssignable and @b MoveConstructible. @param ec Set to the error, if any occurred. + + @return The number of bytes transferred to the parser. */ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Body, class Allocator> -void +std::size_t read( SyncReadStream& stream, DynamicBuffer& buffer, @@ -733,7 +748,8 @@ read( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation, + std::size_t bytes_transferred // the number of bytes transferred to the parser ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -749,7 +765,8 @@ template< void_or_deduced #else async_return_type< - ReadHandler, void(error_code)> + ReadHandler, + void(error_code, std::size_t)> #endif async_read( AsyncReadStream& stream, diff --git a/include/boost/beast/http/write.hpp b/include/boost/beast/http/write.hpp index 7452e90c..aeee1747 100644 --- a/include/boost/beast/http/write.hpp +++ b/include/boost/beast/http/write.hpp @@ -58,6 +58,8 @@ namespace http { @param sr The serializer to use. + @return The number of bytes written to the stream. + @throws system_error Thrown on failure. @see serializer @@ -65,7 +67,7 @@ namespace http { template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_some( SyncWriteStream& stream, serializer& sr); @@ -100,12 +102,14 @@ write_some( @param ec Set to indicate what error occurred, if any. + @return The number of bytes written to the stream. + @see @ref async_write_some, @ref serializer */ template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_some( SyncWriteStream& stream, serializer& sr, @@ -148,7 +152,8 @@ write_some( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation + std::size_t bytes_transferred // the number of bytes written to the stream ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -164,7 +169,9 @@ template< #if BOOST_BEAST_DOXYGEN void_or_deduced #else -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> #endif async_write_some( AsyncWriteStream& stream, @@ -191,6 +198,8 @@ async_write_some( @param sr The serializer to use. + @return The number of bytes written to the stream. + @throws system_error Thrown on failure. @note The implementation will call @ref serializer::split with @@ -201,7 +210,7 @@ async_write_some( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_header( SyncWriteStream& stream, serializer& sr); @@ -226,6 +235,8 @@ write_header( @param ec Set to indicate what error occurred, if any. + @return The number of bytes written to the stream. + @note The implementation will call @ref serializer::split with the value `true` on the serializer passed in. @@ -234,7 +245,7 @@ write_header( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write_header( SyncWriteStream& stream, serializer& sr, @@ -267,7 +278,8 @@ write_header( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation + std::size_t bytes_transferred // the number of bytes written to the stream ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -286,7 +298,9 @@ template< #if BOOST_BEAST_DOXYGEN void_or_deduced #else -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> #endif async_write_header( AsyncWriteStream& stream, @@ -313,6 +327,8 @@ async_write_header( @param sr The serializer to use. + @return The number of bytes written to the stream. + @throws system_error Thrown on failure. @see @ref serializer @@ -320,7 +336,7 @@ async_write_header( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, serializer& sr); @@ -345,12 +361,14 @@ write( @param ec Set to the error, if any occurred. + @return The number of bytes written to the stream. + @see @ref serializer */ template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, serializer& sr, @@ -383,7 +401,8 @@ write( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation + std::size_t bytes_transferred // the number of bytes written to the stream ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -399,7 +418,9 @@ template< #if BOOST_BEAST_DOXYGEN void_or_deduced #else -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> #endif async_write( AsyncWriteStream& stream, @@ -428,6 +449,8 @@ async_write( @param msg The message to write. + @return The number of bytes written to the stream. + @throws system_error Thrown on failure. @see @ref message @@ -435,7 +458,7 @@ async_write( template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, message const& msg); @@ -462,12 +485,14 @@ write( @param ec Set to the error, if any occurred. + @return The number of bytes written to the stream. + @see @ref message */ template< class SyncWriteStream, bool isRequest, class Body, class Fields> -void +std::size_t write( SyncWriteStream& stream, message const& msg, @@ -503,7 +528,8 @@ write( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation + std::size_t bytes_transferred // the number of bytes written to the stream ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -516,7 +542,9 @@ template< class AsyncWriteStream, bool isRequest, class Body, class Fields, class WriteHandler> -async_return_type +async_return_type< + WriteHandler, + void(error_code, std::size_t)> async_write( AsyncWriteStream& stream, message& msg, diff --git a/include/boost/beast/websocket/impl/accept.ipp b/include/boost/beast/websocket/impl/accept.ipp index dad361a3..040cb8e4 100644 --- a/include/boost/beast/websocket/impl/accept.ipp +++ b/include/boost/beast/websocket/impl/accept.ipp @@ -67,7 +67,9 @@ public: { } - void operator()(error_code ec = {}); + void operator()( + error_code ec = {}, + std::size_t bytes_transferred = 0); friend void* asio_handler_allocate( @@ -110,7 +112,9 @@ template void stream:: response_op:: -operator()(error_code ec) +operator()( + error_code ec, + std::size_t) { auto& d = *d_; BOOST_ASIO_CORO_REENTER(*this) @@ -170,7 +174,9 @@ public: template void run(Buffers const& buffers); - void operator()(error_code ec = {}); + void operator()( + error_code ec = {}, + std::size_t bytes_used = 0); friend void* asio_handler_allocate( @@ -242,7 +248,7 @@ template void stream:: accept_op:: -operator()(error_code ec) +operator()(error_code ec, std::size_t) { auto& d = *d_; BOOST_ASIO_CORO_REENTER(*this) diff --git a/include/boost/beast/websocket/impl/handshake.ipp b/include/boost/beast/websocket/impl/handshake.ipp index 5b1879db..2e708f21 100644 --- a/include/boost/beast/websocket/impl/handshake.ipp +++ b/include/boost/beast/websocket/impl/handshake.ipp @@ -76,7 +76,9 @@ public: } void - operator()(error_code ec = {}); + operator()( + error_code ec = {}, + std::size_t bytes_used = 0); friend void* asio_handler_allocate( @@ -118,7 +120,7 @@ template template void stream::handshake_op:: -operator()(error_code ec) +operator()(error_code ec, std::size_t) { auto& d = *d_; BOOST_ASIO_CORO_REENTER(*this) diff --git a/test/beast/http/read.cpp b/test/beast/http/read.cpp index 441dbd09..1db94561 100644 --- a/test/beast/http/read.cpp +++ b/test/beast/http/read.cpp @@ -329,7 +329,7 @@ public: handler() { ++count(); } ~handler() { --count(); } handler(handler const&) { ++count(); } - void operator()(error_code const&) const {} + void operator()(error_code const&, std::size_t) const {} }; void diff --git a/test/beast/http/write.cpp b/test/beast/http/write.cpp index c303b5af..7d4ccfdc 100644 --- a/test/beast/http/write.cpp +++ b/test/beast/http/write.cpp @@ -614,7 +614,7 @@ public: handler() { ++count(); } ~handler() { --count(); } handler(handler const&) { ++count(); } - void operator()(error_code const&) const {} + void operator()(error_code const&, std::size_t) const {} }; void @@ -830,7 +830,7 @@ public: res.chunked(true); response_serializer sr{res}; async_write_header(ts, sr, - [&](const error_code&) + [&](error_code const&, std::size_t) { }); ios.run(); diff --git a/test/doc/http_snippets.cpp b/test/doc/http_snippets.cpp index aa8a63fe..a4e9397f 100644 --- a/test/doc/http_snippets.cpp +++ b/test/doc/http_snippets.cpp @@ -83,8 +83,9 @@ void fxx() { flat_buffer buffer; response res; async_read(sock, buffer, res, - [&](error_code ec) + [&](error_code ec, std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); std::cerr << ec.message() << std::endl; }); @@ -124,8 +125,9 @@ void fxx() { //[http_snippet_8 async_write(sock, res, - [&](error_code) + [&](error_code ec, std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); if(ec) std::cerr << ec.message() << std::endl; });