mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 04:47:29 +02:00
Return std::size_t from Body::writer::put (API Change)
`put` returns the number of bytes actually transferred from the input buffers. Actions Required: * Return the number of bytes actually transferred from the input buffers in user defined `Body::writer::put` functions.
This commit is contained in:
@ -15,6 +15,15 @@ WebSockets:
|
|||||||
* Fix websocket write op
|
* Fix websocket write op
|
||||||
* Add cmake options for examples and tests
|
* Add cmake options for examples and tests
|
||||||
|
|
||||||
|
API Changes:
|
||||||
|
|
||||||
|
* Return `std::size_t` from `Body::writer::put`
|
||||||
|
|
||||||
|
Actions Required:
|
||||||
|
|
||||||
|
* Return the number of bytes actually transferred from the
|
||||||
|
input buffers in user defined `Body::writer::put` functions.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 70:
|
Version 70:
|
||||||
|
@ -174,6 +174,10 @@ file(GLOB_RECURSE COMMON_INCLUDES
|
|||||||
${PROJECT_SOURCE_DIR}/example/common/*.hpp
|
${PROJECT_SOURCE_DIR}/example/common/*.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE EXAMPLE_INCLUDES
|
||||||
|
${PROJECT_SOURCE_DIR}/example/*.hpp
|
||||||
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE EXTRAS_INCLUDES
|
file(GLOB_RECURSE EXTRAS_INCLUDES
|
||||||
${PROJECT_SOURCE_DIR}/extras/beast/*.hpp
|
${PROJECT_SOURCE_DIR}/extras/beast/*.hpp
|
||||||
${PROJECT_SOURCE_DIR}/extras/beast/*.ipp
|
${PROJECT_SOURCE_DIR}/extras/beast/*.ipp
|
||||||
|
@ -120,4 +120,19 @@ the response:
|
|||||||
|
|
||||||
[http_snippet_13]
|
[http_snippet_13]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[section Incremental Read]
|
||||||
|
|
||||||
|
This function uses
|
||||||
|
[link beast.ref.beast__http__buffer_body `buffer_body`]
|
||||||
|
and parser stream operations to read a message body progressively
|
||||||
|
using a small, fixed-size buffer:
|
||||||
|
|
||||||
|
[example_incremental_read]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@ -57,10 +57,13 @@ In this table:
|
|||||||
]
|
]
|
||||||
][
|
][
|
||||||
[`a.put(b,ec)`]
|
[`a.put(b,ec)`]
|
||||||
[]
|
[`std::size_t`]
|
||||||
[
|
[
|
||||||
This function is called to append the buffers specified by `b`
|
This function is called to append some or all of the buffers
|
||||||
into the body representation.
|
specified by `b` into the body representation. The number of
|
||||||
|
bytes inserted from `b` is returned. If the number of bytes
|
||||||
|
inserted is less than the total input, the remainder of the
|
||||||
|
input will be presented in the next call to `put`.
|
||||||
The function will ensure that `!ec` is `true` if there was
|
The function will ensure that `!ec` is `true` if there was
|
||||||
no error or set to the appropriate error code if there was one.
|
no error or set to the appropriate error code if there was one.
|
||||||
]
|
]
|
||||||
|
@ -255,7 +255,7 @@ public:
|
|||||||
// buffer sequences corresponding to the incoming body.
|
// buffer sequences corresponding to the incoming body.
|
||||||
//
|
//
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers, beast::error_code& ec);
|
put(ConstBufferSequence const& buffers, beast::error_code& ec);
|
||||||
|
|
||||||
// This function is called when writing is complete.
|
// This function is called when writing is complete.
|
||||||
@ -307,16 +307,20 @@ writer(beast::http::message<isRequest, file_body, Fields>& m,
|
|||||||
// This will get called one or more times with body buffers
|
// This will get called one or more times with body buffers
|
||||||
//
|
//
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
file_body::writer::
|
file_body::writer::
|
||||||
put(ConstBufferSequence const& buffers, beast::error_code& ec)
|
put(ConstBufferSequence const& buffers, beast::error_code& ec)
|
||||||
{
|
{
|
||||||
|
// This function must return the total number of
|
||||||
|
// bytes transferred from the input buffers.
|
||||||
|
std::size_t bytes_transferred = 0;
|
||||||
|
|
||||||
// Loop over all the buffers in the sequence,
|
// Loop over all the buffers in the sequence,
|
||||||
// and write each one to the file.
|
// and write each one to the file.
|
||||||
for(boost::asio::const_buffer buffer : buffers)
|
for(boost::asio::const_buffer buffer : buffers)
|
||||||
{
|
{
|
||||||
// Write this buffer to the file
|
// Write this buffer to the file
|
||||||
fwrite(
|
bytes_transferred += fwrite(
|
||||||
boost::asio::buffer_cast<void const*>(buffer), 1,
|
boost::asio::buffer_cast<void const*>(buffer), 1,
|
||||||
boost::asio::buffer_size(buffer),
|
boost::asio::buffer_size(buffer),
|
||||||
file_);
|
file_);
|
||||||
@ -327,12 +331,14 @@ put(ConstBufferSequence const& buffers, beast::error_code& ec)
|
|||||||
// Convert the old-school `errno` into
|
// Convert the old-school `errno` into
|
||||||
// an error code using the generic category.
|
// an error code using the generic category.
|
||||||
ec = beast::error_code{errno, beast::generic_category()};
|
ec = beast::error_code{errno, beast::generic_category()};
|
||||||
return;
|
return bytes_transferred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate success
|
// Indicate success
|
||||||
ec = {};
|
ec = {};
|
||||||
|
|
||||||
|
return bytes_transferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after writing is done when there's no error.
|
// Called after writing is done when there's no error.
|
||||||
|
@ -120,7 +120,7 @@ struct mutable_body
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers,
|
put(ConstBufferSequence const& buffers,
|
||||||
beast::error_code& ec)
|
beast::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -135,10 +135,10 @@ struct mutable_body
|
|||||||
catch(std::length_error const&)
|
catch(std::length_error const&)
|
||||||
{
|
{
|
||||||
ec = beast::http::error::buffer_overflow;
|
ec = beast::http::error::buffer_overflow;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
buffer_copy(boost::asio::buffer(
|
return buffer_copy(boost::asio::buffer(
|
||||||
&body_[0] + len, n), buffers);
|
&body_[0] + len, n), buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <beast.hpp>
|
#include <beast.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
/* This file contains the functions and classes found in the documentation
|
/* This file contains the functions and classes found in the documentation
|
||||||
|
|
||||||
@ -917,12 +918,15 @@ class custom_parser
|
|||||||
content_length, // Content length if known, else `boost::none`
|
content_length, // Content length if known, else `boost::none`
|
||||||
error_code& ec); // The error returned to the caller, if any
|
error_code& ec); // The error returned to the caller, if any
|
||||||
|
|
||||||
/// Called for each piece of the body, if a body exists.
|
/** Called for each piece of the body, if a body exists.
|
||||||
//
|
|
||||||
// If present, the chunked Transfer-Encoding will be removed
|
If present, the chunked Transfer-Encoding will be removed
|
||||||
// before this callback is invoked.
|
before this callback is invoked. The function returns
|
||||||
//
|
the number of bytes consumed from the input buffer.
|
||||||
void
|
Any input octets not consumed will be will be presented
|
||||||
|
on subsequent calls.
|
||||||
|
*/
|
||||||
|
std::size_t
|
||||||
on_data(
|
on_data(
|
||||||
string_view s, // A portion of the body
|
string_view s, // A portion of the body
|
||||||
error_code& ec); // The error returned to the caller, if any
|
error_code& ec); // The error returned to the caller, if any
|
||||||
@ -990,11 +994,12 @@ on_body(boost::optional<std::uint64_t> const& content_length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool isRequest>
|
template<bool isRequest>
|
||||||
void custom_parser<isRequest>::
|
std::size_t custom_parser<isRequest>::
|
||||||
on_data(string_view s, error_code& ec)
|
on_data(string_view s, error_code& ec)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(s);
|
boost::ignore_unused(s);
|
||||||
ec = {};
|
ec = {};
|
||||||
|
return s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool isRequest>
|
template<bool isRequest>
|
||||||
@ -1013,5 +1018,47 @@ on_complete(error_code& ec)
|
|||||||
ec = {};
|
ec = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Example: Incremental Read
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//[example_incremental_read
|
||||||
|
|
||||||
|
/* This function reads a message using a fixed size buffer to hold
|
||||||
|
portions of the body, and prints the body contents to a `std::ostream`.
|
||||||
|
*/
|
||||||
|
template<
|
||||||
|
bool isRequest,
|
||||||
|
class SyncReadStream,
|
||||||
|
class DynamicBuffer>
|
||||||
|
void
|
||||||
|
read_and_print_body(
|
||||||
|
std::ostream& os,
|
||||||
|
SyncReadStream& stream,
|
||||||
|
DynamicBuffer& buffer,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
parser<isRequest, buffer_body> p;
|
||||||
|
read_header(stream, buffer, p, ec);
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
|
while(! p.is_done())
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
p.get().body.data = buf;
|
||||||
|
p.get().body.size = sizeof(buf);
|
||||||
|
read(stream, buffer, p, ec);
|
||||||
|
if(ec == error::need_buffer)
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
|
os.write(buf, sizeof(buf) - p.get().body.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//]
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@ -161,25 +161,28 @@ struct buffer_body
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers,
|
put(ConstBufferSequence const& buffers,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
auto const n = buffer_size(buffers);
|
if(! body_.data)
|
||||||
if(! body_.data || n > body_.size)
|
|
||||||
{
|
{
|
||||||
ec = error::need_buffer;
|
ec = error::need_buffer;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
ec.assign(0, ec.category());
|
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
buffer_copy(boost::asio::buffer(
|
buffer_copy(boost::asio::buffer(
|
||||||
body_.data, body_.size), buffers);
|
body_.data, body_.size), buffers);
|
||||||
body_.data = reinterpret_cast<char*>(
|
body_.data = reinterpret_cast<char*>(
|
||||||
body_.data) + bytes_transferred;
|
body_.data) + bytes_transferred;
|
||||||
body_.size -= bytes_transferred;
|
body_.size -= bytes_transferred;
|
||||||
|
if(bytes_transferred == buffer_size(buffers))
|
||||||
|
ec.assign(0, ec.category());
|
||||||
|
else
|
||||||
|
ec = error::need_buffer;
|
||||||
|
return bytes_transferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <beast/http/error.hpp>
|
#include <beast/http/error.hpp>
|
||||||
#include <beast/http/message.hpp>
|
#include <beast/http/message.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
@ -86,26 +87,35 @@ struct basic_dynamic_body
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers,
|
put(ConstBufferSequence const& buffers,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
|
auto const n = buffer_size(buffers);
|
||||||
|
if(body_.size() > body_.max_size() - n)
|
||||||
|
{
|
||||||
|
ec = error::buffer_overflow;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
boost::optional<typename
|
boost::optional<typename
|
||||||
DynamicBuffer::mutable_buffers_type> b;
|
DynamicBuffer::mutable_buffers_type> b;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
b.emplace(body_.prepare(
|
b.emplace(body_.prepare((std::min)(n,
|
||||||
buffer_size(buffers)));
|
body_.max_size() - body_.size())));
|
||||||
}
|
}
|
||||||
catch(std::length_error const&)
|
catch(std::length_error const&)
|
||||||
{
|
{
|
||||||
ec = error::buffer_overflow;
|
ec = error::buffer_overflow;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
body_.commit(buffer_copy(*b, buffers));
|
auto const bytes_transferred =
|
||||||
|
buffer_copy(*b, buffers);
|
||||||
|
body_.commit(bytes_transferred);
|
||||||
|
return bytes_transferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -85,11 +85,12 @@ struct empty_body
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const&,
|
put(ConstBufferSequence const&,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
ec = error::unexpected_body;
|
ec = error::unexpected_body;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -523,12 +523,12 @@ basic_parser<isRequest, Derived>::
|
|||||||
parse_body(char const*& p,
|
parse_body(char const*& p,
|
||||||
std::size_t n, error_code& ec)
|
std::size_t n, error_code& ec)
|
||||||
{
|
{
|
||||||
n = beast::detail::clamp(len_, n);
|
n = impl().on_data(string_view{p,
|
||||||
impl().on_data(string_view{p, n}, ec);
|
beast::detail::clamp(len_, n)}, ec);
|
||||||
if(ec)
|
|
||||||
return;
|
|
||||||
p += n;
|
p += n;
|
||||||
len_ -= n;
|
len_ -= n;
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
if(len_ > 0)
|
if(len_ > 0)
|
||||||
return;
|
return;
|
||||||
impl().on_complete(ec);
|
impl().on_complete(ec);
|
||||||
@ -550,10 +550,10 @@ parse_body_to_eof(char const*& p,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
body_limit_ = body_limit_ - n;
|
body_limit_ = body_limit_ - n;
|
||||||
impl().on_data(string_view{p, n}, ec);
|
n = impl().on_data(string_view{p, n}, ec);
|
||||||
|
p += n;
|
||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
p += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool isRequest, class Derived>
|
template<bool isRequest, class Derived>
|
||||||
@ -701,12 +701,12 @@ basic_parser<isRequest, Derived>::
|
|||||||
parse_chunk_body(char const*& p,
|
parse_chunk_body(char const*& p,
|
||||||
std::size_t n, error_code& ec)
|
std::size_t n, error_code& ec)
|
||||||
{
|
{
|
||||||
n = beast::detail::clamp(len_, n);
|
n = impl().on_data(string_view{p,
|
||||||
impl().on_data(string_view{p, n}, ec);
|
beast::detail::clamp(len_, n)}, ec);
|
||||||
if(ec)
|
|
||||||
return;
|
|
||||||
p += n;
|
p += n;
|
||||||
len_ -= n;
|
len_ -= n;
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
if(len_ > 0)
|
if(len_ > 0)
|
||||||
return;
|
return;
|
||||||
state_ = state::chunk_header;
|
state_ = state::chunk_header;
|
||||||
|
@ -288,10 +288,10 @@ private:
|
|||||||
wr_.emplace(m_, content_length, ec);
|
wr_.emplace(m_, content_length, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::size_t
|
||||||
on_data(string_view s, error_code& ec)
|
on_data(string_view s, error_code& ec)
|
||||||
{
|
{
|
||||||
wr_->put(boost::asio::buffer(
|
return wr_->put(boost::asio::buffer(
|
||||||
s.data(), s.size()), ec);
|
s.data(), s.size()), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ struct string_body
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers,
|
put(ConstBufferSequence const& buffers,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
@ -120,10 +120,10 @@ struct string_body
|
|||||||
catch(std::length_error const&)
|
catch(std::length_error const&)
|
||||||
{
|
{
|
||||||
ec = error::buffer_overflow;
|
ec = error::buffer_overflow;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
buffer_copy(boost::asio::buffer(
|
return buffer_copy(boost::asio::buffer(
|
||||||
&body_[0] + len, n), buffers);
|
&body_[0] + len, n), buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +122,10 @@ struct is_body_writer : std::false_type {};
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_body_writer<T, beast::detail::void_t<decltype(
|
struct is_body_writer<T, beast::detail::void_t<decltype(
|
||||||
std::declval<typename T::writer&>().put(
|
std::declval<std::size_t&>() =
|
||||||
std::declval<boost::asio::const_buffers_1>(),
|
std::declval<typename T::writer&>().put(
|
||||||
std::declval<error_code&>()),
|
std::declval<boost::asio::const_buffers_1>(),
|
||||||
|
std::declval<error_code&>()),
|
||||||
std::declval<typename T::writer&>().finish(
|
std::declval<typename T::writer&>().finish(
|
||||||
std::declval<error_code&>()),
|
std::declval<error_code&>()),
|
||||||
(void)0)>> : std::integral_constant<bool,
|
(void)0)>> : std::integral_constant<bool,
|
||||||
|
@ -199,11 +199,11 @@ public:
|
|||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::size_t
|
||||||
on_data(string_view,
|
on_data(string_view s, error_code& ec)
|
||||||
error_code& ec)
|
|
||||||
{
|
{
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
|
return s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Part of Beast
|
# Part of Beast
|
||||||
|
|
||||||
GroupSources(examples examples)
|
GroupSources(example example)
|
||||||
GroupSources(extras/beast extras)
|
GroupSources(extras/beast extras)
|
||||||
GroupSources(include/beast beast)
|
GroupSources(include/beast beast)
|
||||||
|
|
||||||
|
@ -125,9 +125,11 @@ struct BodyWriter
|
|||||||
@param buffers The constant buffer sequence to store.
|
@param buffers The constant buffer sequence to store.
|
||||||
|
|
||||||
@param ec Set to the error, if any occurred.
|
@param ec Set to the error, if any occurred.
|
||||||
|
|
||||||
|
@return The number of bytes transferred from the input buffers.
|
||||||
*/
|
*/
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
std::size_t
|
||||||
put(ConstBufferSequence const& buffers, error_code& ec)
|
put(ConstBufferSequence const& buffers, error_code& ec)
|
||||||
{
|
{
|
||||||
// The specification requires this to indicate "no error"
|
// The specification requires this to indicate "no error"
|
||||||
|
@ -49,13 +49,13 @@ BOOST_STATIC_ASSERT(::detail::is_mutable_container<string_view>::value == false)
|
|||||||
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::vector<char>>::value == true);
|
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::vector<char>>::value == true);
|
||||||
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::list<char>>::value == false);
|
BOOST_STATIC_ASSERT(::detail::is_mutable_container<std::list<char>>::value == false);
|
||||||
|
|
||||||
class doc_http_samples_test
|
class doc_examples_test
|
||||||
: public beast::unit_test::suite
|
: public beast::unit_test::suite
|
||||||
, public beast::test::enable_yield_to
|
, public beast::test::enable_yield_to
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// two threads, for some examples using a pipe
|
// two threads, for some examples using a pipe
|
||||||
doc_http_samples_test()
|
doc_examples_test()
|
||||||
: enable_yield_to(2)
|
: enable_yield_to(2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -386,6 +386,27 @@ public:
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void
|
||||||
|
doIncrementalRead()
|
||||||
|
{
|
||||||
|
test::pipe c{ios_};
|
||||||
|
std::string s(2048, '*');
|
||||||
|
ostream(c.server.buffer) <<
|
||||||
|
"HTTP/1.1 200 OK\r\n"
|
||||||
|
"Content-Length: 2048\r\n"
|
||||||
|
"Server: test\r\n"
|
||||||
|
"\r\n" <<
|
||||||
|
s;
|
||||||
|
error_code ec;
|
||||||
|
flat_buffer b;
|
||||||
|
std::stringstream ss;
|
||||||
|
read_and_print_body<false>(ss, c.server, b, ec);
|
||||||
|
if(BEAST_EXPECTS(! ec, ec.message()))
|
||||||
|
BEAST_EXPECT(ss.str() == s);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
void
|
void
|
||||||
run()
|
run()
|
||||||
{
|
{
|
||||||
@ -399,10 +420,11 @@ public:
|
|||||||
doDeferredBody();
|
doDeferredBody();
|
||||||
doFileBody();
|
doFileBody();
|
||||||
doConstAndMutableBody();
|
doConstAndMutableBody();
|
||||||
|
doIncrementalRead();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(doc_http_samples,http,beast);
|
BEAST_DEFINE_TESTSUITE(doc_examples,http,beast);
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@ -118,7 +118,7 @@ public:
|
|||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::size_t
|
||||||
on_data(string_view s,
|
on_data(string_view s,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
@ -127,6 +127,7 @@ public:
|
|||||||
fc_->fail(ec);
|
fc_->fail(ec);
|
||||||
else
|
else
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
|
return s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Reference in New Issue
Block a user