http read_some, async_read_some don't return bytes (API Change):

fix #431, fix #430

The read_some and async_read_some HTTP operations no longer
return the number of bytes that the caller should consume.
Instead, the bytes are automatically removed from the dynamic
buffer as indicated by the parser.
This commit is contained in:
Vinnie Falco
2017-06-07 15:21:54 -07:00
parent 6203074c92
commit 38ac1b8364
3 changed files with 26 additions and 49 deletions

View File

@ -23,6 +23,7 @@ API Changes:
* Remove message connection settings * Remove message connection settings
* Remove message free functions * Remove message free functions
* Remove obsolete serializer allocator * Remove obsolete serializer allocator
* http read_some, async_read_some don't return bytes
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -35,7 +35,6 @@ template<class Stream, class DynamicBuffer,
class read_some_op class read_some_op
{ {
int state_ = 0; int state_ = 0;
std::size_t used_ = 0;
Stream& s_; Stream& s_;
DynamicBuffer& b_; DynamicBuffer& b_;
basic_parser<isRequest, Derived>& p_; basic_parser<isRequest, Derived>& p_;
@ -136,7 +135,7 @@ operator()(error_code ec, std::size_t bytes_transferred)
b_.commit(bytes_transferred); b_.commit(bytes_transferred);
do_parse: do_parse:
used_ += p_.put(b_.data(), ec); b_.consume(p_.put(b_.data(), ec));
if(! ec || ec != http::error::need_more) if(! ec || ec != http::error::need_more)
goto do_upcall; goto do_upcall;
ec = {}; ec = {};
@ -167,7 +166,7 @@ operator()(error_code ec, std::size_t bytes_transferred)
break; break;
} }
upcall: upcall:
h_(ec, used_); h_(ec);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -221,7 +220,7 @@ public:
} }
void void
operator()(error_code ec, std::size_t bytes_used); operator()(error_code ec);
friend friend
void* asio_handler_allocate( void* asio_handler_allocate(
@ -266,7 +265,7 @@ template<class Stream, class DynamicBuffer,
void void
read_op<Stream, DynamicBuffer, read_op<Stream, DynamicBuffer,
isRequest, Derived, Condition, Handler>:: isRequest, Derived, Condition, Handler>::
operator()(error_code ec, std::size_t bytes_used) operator()(error_code ec)
{ {
switch(state_) switch(state_)
{ {
@ -275,7 +274,7 @@ operator()(error_code ec, std::size_t bytes_used)
{ {
state_ = 1; state_ = 1;
return s_.get_io_service().post( return s_.get_io_service().post(
bind_handler(std::move(*this), ec, 0)); bind_handler(std::move(*this), ec));
} }
state_ = 2; state_ = 2;
// [[fallthrough]] // [[fallthrough]]
@ -289,7 +288,6 @@ operator()(error_code ec, std::size_t bytes_used)
case 2: case 2:
case 3: case 3:
b_.consume(bytes_used);
if(ec) if(ec)
goto upcall; goto upcall;
if(Condition{}(p_)) if(Condition{}(p_))
@ -346,7 +344,7 @@ public:
} }
void void
operator()(error_code ec, std::size_t bytes_used); operator()(error_code ec);
friend friend
void* asio_handler_allocate( void* asio_handler_allocate(
@ -391,7 +389,7 @@ template<class Stream, class DynamicBuffer,
void void
read_msg_op<Stream, DynamicBuffer, read_msg_op<Stream, DynamicBuffer,
isRequest, Body, Fields, Handler>:: isRequest, Body, Fields, Handler>::
operator()(error_code ec, std::size_t bytes_used) operator()(error_code ec)
{ {
auto& d = *d_; auto& d = *d_;
switch(d.state) switch(d.state)
@ -405,7 +403,6 @@ operator()(error_code ec, std::size_t bytes_used)
case 1: case 1:
case 2: case 2:
d.b.consume(bytes_used);
if(ec) if(ec)
goto upcall; goto upcall;
if(d.p.is_done()) if(d.p.is_done())
@ -428,7 +425,7 @@ template<
class SyncReadStream, class SyncReadStream,
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived> bool isRequest, class Derived>
std::size_t void
read_some( read_some(
SyncReadStream& stream, SyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -440,18 +437,16 @@ read_some(
"DynamicBuffer requirements not met"); "DynamicBuffer requirements not met");
BOOST_ASSERT(! parser.is_done()); BOOST_ASSERT(! parser.is_done());
error_code ec; error_code ec;
auto const bytes_used = read_some(stream, buffer, parser, ec);
read_some(stream, buffer, parser, ec);
if(ec) if(ec)
BOOST_THROW_EXCEPTION(system_error{ec}); BOOST_THROW_EXCEPTION(system_error{ec});
return bytes_used;
} }
template< template<
class SyncReadStream, class SyncReadStream,
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived> bool isRequest, class Derived>
std::size_t void
read_some( read_some(
SyncReadStream& stream, SyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -463,13 +458,12 @@ read_some(
static_assert(is_dynamic_buffer<DynamicBuffer>::value, static_assert(is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met"); "DynamicBuffer requirements not met");
BOOST_ASSERT(! parser.is_done()); BOOST_ASSERT(! parser.is_done());
std::size_t bytes_used = 0;
if(buffer.size() == 0) if(buffer.size() == 0)
goto do_read; goto do_read;
for(;;) for(;;)
{ {
// invoke parser // invoke parser
bytes_used += parser.put(buffer.data(), ec); buffer.consume(parser.put(buffer.data(), ec));
if(! ec) if(! ec)
break; break;
if(ec != http::error::need_more) if(ec != http::error::need_more)
@ -511,7 +505,6 @@ read_some(
break; break;
buffer.commit(bytes_transferred); buffer.commit(bytes_transferred);
} }
return bytes_used;
} }
template< template<
@ -520,7 +513,7 @@ template<
bool isRequest, class Derived, bool isRequest, class Derived,
class ReadHandler> class ReadHandler>
async_return_type< async_return_type<
ReadHandler, void(error_code, std::size_t)> ReadHandler, void(error_code)>
async_read_some( async_read_some(
AsyncReadStream& stream, AsyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -532,8 +525,7 @@ async_read_some(
static_assert(is_dynamic_buffer<DynamicBuffer>::value, static_assert(is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met"); "DynamicBuffer requirements not met");
BOOST_ASSERT(! parser.is_done()); BOOST_ASSERT(! parser.is_done());
async_completion<ReadHandler, async_completion<ReadHandler, void(error_code)> init{handler};
void(error_code, std::size_t)> init{handler};
detail::read_some_op<AsyncReadStream, detail::read_some_op<AsyncReadStream,
DynamicBuffer, isRequest, Derived, handler_type< DynamicBuffer, isRequest, Derived, handler_type<
ReadHandler, void(error_code, std::size_t)>>{ ReadHandler, void(error_code, std::size_t)>>{
@ -582,9 +574,7 @@ read_header(
parser.eager(false); parser.eager(false);
while(! parser.is_header_done()) while(! parser.is_header_done())
{ {
auto const bytes_used = read_some(stream, buffer, parser, ec);
read_some(stream, buffer, parser, ec);
buffer.consume(bytes_used);
if(ec) if(ec)
return; return;
} }
@ -595,8 +585,7 @@ template<
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived, bool isRequest, class Derived,
class ReadHandler> class ReadHandler>
async_return_type< async_return_type<ReadHandler, void(error_code)>
ReadHandler, void(error_code)>
async_read_header( async_read_header(
AsyncReadStream& stream, AsyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -614,7 +603,7 @@ async_read_header(
isRequest, Derived, detail::parser_is_header_done, isRequest, Derived, detail::parser_is_header_done,
handler_type<ReadHandler, void(error_code)>>{ handler_type<ReadHandler, void(error_code)>>{
init.completion_handler, stream, buffer, parser}( init.completion_handler, stream, buffer, parser}(
error_code{}, 0); error_code{});
return init.result.get(); return init.result.get();
} }
@ -658,9 +647,7 @@ read(
parser.eager(true); parser.eager(true);
while(! parser.is_done()) while(! parser.is_done())
{ {
auto const bytes_used = read_some( read_some(stream, buffer, parser, ec);
stream, buffer, parser, ec);
buffer.consume(bytes_used);
if(ec) if(ec)
return; return;
} }
@ -671,8 +658,7 @@ template<
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived, bool isRequest, class Derived,
class ReadHandler> class ReadHandler>
async_return_type< async_return_type<ReadHandler, void(error_code)>
ReadHandler, void(error_code)>
async_read( async_read(
AsyncReadStream& stream, AsyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -690,7 +676,7 @@ async_read(
isRequest, Derived, detail::parser_is_done, isRequest, Derived, detail::parser_is_done,
handler_type<ReadHandler, void(error_code)>>{ handler_type<ReadHandler, void(error_code)>>{
init.completion_handler, stream, buffer, parser}( init.completion_handler, stream, buffer, parser}(
error_code{}, 0); error_code{});
return init.result.get(); return init.result.get();
} }
@ -752,8 +738,7 @@ template<
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Body, class Fields, bool isRequest, class Body, class Fields,
class ReadHandler> class ReadHandler>
async_return_type< async_return_type<ReadHandler, void(error_code)>
ReadHandler, void(error_code)>
async_read( async_read(
AsyncReadStream& stream, AsyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -774,7 +759,7 @@ async_read(
isRequest, Body, Fields, handler_type< isRequest, Body, Fields, handler_type<
ReadHandler, void(error_code)>>{ ReadHandler, void(error_code)>>{
init.completion_handler, stream, buffer, msg}( init.completion_handler, stream, buffer, msg}(
error_code{}, 0); error_code{});
return init.result.get(); return init.result.get();
} }

View File

@ -52,17 +52,13 @@ namespace http {
@param parser The parser to use. @param parser The parser to use.
@return The number of octets processed from the dynamic buffer.
The octets should be removed by calling `consume` on the dynamic
buffer after the read completes, regardless of any error.
@throws system_error Thrown on failure. @throws system_error Thrown on failure.
*/ */
template< template<
class SyncReadStream, class SyncReadStream,
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived> bool isRequest, class Derived>
std::size_t void
read_some( read_some(
SyncReadStream& stream, SyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -108,16 +104,12 @@ read_some(
@param parser The parser to use. @param parser The parser to use.
@param ec Set to the error, if any occurred. @param ec Set to the error, if any occurred.
@return The number of octets processed from the dynamic buffer.
The octets should be removed by calling `consume` on the dynamic
buffer after the read completes, regardless of any error.
*/ */
template< template<
class SyncReadStream, class SyncReadStream,
class DynamicBuffer, class DynamicBuffer,
bool isRequest, class Derived> bool isRequest, class Derived>
std::size_t void
read_some( read_some(
SyncReadStream& stream, SyncReadStream& stream,
DynamicBuffer& buffer, DynamicBuffer& buffer,
@ -168,8 +160,7 @@ read_some(
completes. Copies will be made of the handler as required. completes. Copies will be made of the handler as required.
The equivalent function signature of the handler must be: The equivalent function signature of the handler must be:
@code void handler( @code void handler(
error_code const& error, // result of operation error_code const& error // result of operation
std::size_t bytes_used // the number of bytes to consume
); @endcode ); @endcode
Regardless of whether the asynchronous operation completes Regardless of whether the asynchronous operation completes
immediately or not, the handler will not be invoked from within immediately or not, the handler will not be invoked from within
@ -190,7 +181,7 @@ template<
void_or_deduced void_or_deduced
#else #else
async_return_type< async_return_type<
ReadHandler, void(error_code, std::size_t)> ReadHandler, void(error_code)>
#endif #endif
async_read_some( async_read_some(
AsyncReadStream& stream, AsyncReadStream& stream,