Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/bitcoin/network/impl/messages/json_body.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ size_t CLASS::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
TEMPLATE
void CLASS::reader::finish(boost_code& ec) NOEXCEPT
{
using namespace network::error;
if (!done())
{
ec = to_http_code(http_error_t::partial_message);
return;
}

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
parser_.finish(ec);
BC_POP_WARNING()
Expand All @@ -107,7 +114,6 @@ void CLASS::reader::finish(boost_code& ec) NOEXCEPT
catch (...)
{
// As a catch-all we blame alloc.
using namespace network::error;
ec = to_http_code(http_error_t::bad_alloc);
}

Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/network/messages/rpc/body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct BCT_API body

size_t put(const buffer_type& buffer, boost_code& ec) NOEXCEPT override;
void finish(boost_code& ec) NOEXCEPT override;
bool done() const NOEXCEPT override;

private:
const bool terminated_{};
Expand Down
48 changes: 27 additions & 21 deletions src/messages/rpc/body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <variant>
#include <bitcoin/network/define.hpp>
#include <bitcoin/network/messages/messages.hpp>
////#include <bitcoin/network/messages/messages.hpp>

namespace libbitcoin {
namespace network {
Expand Down Expand Up @@ -65,46 +64,45 @@ put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
if (!terminated_)
return parsed;

// There is no terminator.
// There is no terminator (terminal).
if (is_zero(parsed))
{
ec = to_http_code(http_error_t::end_of_stream);
return parsed;
}

// There are extra characters.
if (size > parsed)
{
ec = to_http_code(http_error_t::unexpected_body);
return parsed;
}

// boost::json consumes whitespace, so terminator is always last.
// boost::json consumes whitespace, and leaves any subsequent chars
// unparsed, so terminator must be in the parsed segment of the buffer.
const auto data = pointer_cast<const char>(buffer.data());
if (data[sub1(parsed)] == '\n')
for (auto index = parsed; !is_zero(index);)
{
has_terminator_ = true;
return parsed;
if (data[--index] == '\n')
{
// There may be unparsed characters (ok, next message).
has_terminator_ = true;
return parsed;
}
}

// There is no terminator.
ec = to_http_code(http_error_t::end_of_stream);
// There is no terminator (yet).
return parsed;
}

template <>
bool body<rpc::request_t>::reader::
done() const NOEXCEPT
{
// Parser may be done but with terminator still outstanding.
return parser_.done() && (!terminated_ || has_terminator_);
}

template <>
void body<rpc::request_t>::reader::
finish(boost_code& ec) NOEXCEPT
{
base::reader::finish(ec);
if (ec) return;

if (terminated_ && !has_terminator_)
{
ec = to_http_code(http_error_t::end_of_stream);
return;
}

try
{
value_.message = value_to<rpc::request_t>(value_.model);
Expand Down Expand Up @@ -162,6 +160,14 @@ finish(boost_code&) NOEXCEPT
BC_ASSERT(false);
}

template <>
bool body<rpc::response_t>::reader::
done() const NOEXCEPT
{
BC_ASSERT(false);
return {};
}

// rpc::body::writer
// ----------------------------------------------------------------------------

Expand Down
8 changes: 0 additions & 8 deletions src/net/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,18 +686,10 @@ void socket::handle_rpc_read(boost_code ec, size_t size, size_t total,
const auto parsed = in->reader.put(data, ec);
if (!ec)
{
if (parsed < data.size())
{
handler(error::unexpected_body, total);
return;
}

in->value.buffer->consume(parsed);
if (in->reader.done())
{
in->reader.finish(ec);

// Finished.
if (!ec)
{
handler(error::success, total);
Expand Down
Loading