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
16 changes: 9 additions & 7 deletions include/bitcoin/network/channels/channel_http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class BCT_API channel_http
using interface = rpc::interface::http;
using dispatcher = rpc::dispatcher<interface>;

/// Subscribe to request from client (requires strand).
/// Subscribe to message from client (requires strand).
/// Event handler is always invoked on the channel strand.
template <class Request>
inline void subscribe(auto&& handler) NOEXCEPT
Expand All @@ -53,8 +53,7 @@ class BCT_API channel_http
}

// TODO: network.minimum_buffer is being overloaded here.
/// response_buffer_ is initialized to default size, see set_buffer().
/// Construct client channel to encapsulate and communicate on the socket.
/// Construct http channel to encapsulate and communicate on the socket.
inline channel_http(const logger& log, const socket::ptr& socket,
uint64_t identifier, const settings_t& settings,
const options_t& options) NOEXCEPT
Expand All @@ -70,7 +69,7 @@ class BCT_API channel_http
/// Must call after successful message handling if no stop.
virtual void receive() NOEXCEPT;

/// Serialize and write http response to client (requires strand).
/// Serialize and write http message to client (requires strand).
/// Completion handler is always invoked on the channel strand.
virtual void send(http::response&& response,
result_handler&& handler) NOEXCEPT;
Expand All @@ -91,12 +90,15 @@ class BCT_API channel_http
/// Handlers.
virtual void handle_receive(const code& ec, size_t bytes,
const http::request_cptr& request) NOEXCEPT;
virtual void handle_send(const code& ec, size_t bytes, http::response_ptr&,
virtual void handle_send(const code& ec, size_t bytes,
const http::response_cptr& response,
const result_handler& handler) NOEXCEPT;

private:
void log_message(const http::request& request) const NOEXCEPT;
void log_message(const http::response& response) const NOEXCEPT;
void log_message(const http::request& request,
size_t bytes) const NOEXCEPT;
void log_message(const http::response& response,
size_t bytes) const NOEXCEPT;

// These are protected by strand.
http::flat_buffer_ptr response_buffer_;
Expand Down
59 changes: 56 additions & 3 deletions include/bitcoin/network/channels/channel_rpc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#include <memory>
#include <bitcoin/network/channels/channel.hpp>
#include <bitcoin/network/define.hpp>
#include <bitcoin/network/interface/interface.hpp>
#include <bitcoin/network/log/log.hpp>
#include <bitcoin/network/messages/messages.hpp>
#include <bitcoin/network/net/net.hpp>

namespace libbitcoin {
Expand All @@ -35,10 +37,27 @@ class BCT_API channel_rpc
public:
typedef std::shared_ptr<channel_rpc> ptr;

// TODO: implement in node.
using interface = rpc::interface::http;
using dispatcher = rpc::dispatcher<interface>;

/// Subscribe to request from client (requires strand).
/// Event handler is always invoked on the channel strand.
template <class Handler>
inline void subscribe(Handler&& handler) NOEXCEPT
{
BC_ASSERT(stranded());
dispatcher_.subscribe(std::forward<Handler>(handler));
}

// TODO: network.minimum_buffer is being overloaded here.
/// Construct rpc channel to encapsulate and communicate on the socket.
inline channel_rpc(const logger& log, const socket::ptr& socket,
uint64_t identifier, const settings_t& settings,
const options_t& options) NOEXCEPT
: channel(log, socket, identifier, settings, options)
: channel(log, socket, identifier, settings, options),
response_buffer_(system::to_shared<http::flat_buffer>()),
request_buffer_(settings.minimum_buffer)
{
}

Expand All @@ -48,9 +67,43 @@ class BCT_API channel_rpc
/// Must call after successful message handling if no stop.
virtual void receive() NOEXCEPT;

/// Serialize and write rpc response to client (requires strand).
/// Serialize and write response to client (requires strand).
/// Completion handler is always invoked on the channel strand.
virtual void send() NOEXCEPT;
virtual void send(rpc::response_t&& message, size_t size_hint,
result_handler&& handler) NOEXCEPT;

protected:
/// Stranded handler invoked from stop().
void stopping(const code& ec) NOEXCEPT override;

/// Read request buffer (not thread safe).
virtual http::flat_buffer& request_buffer() NOEXCEPT;

/// Dispatch request to subscribers by requested method.
virtual void dispatch(const rpc::request_cptr& request) NOEXCEPT;

/// Size and assign response_buffer_ (value type is json-rpc::json).
virtual rpc::response_ptr assign_message(rpc::response_t&& message,
size_t size_hint) NOEXCEPT;

/// Handlers.
virtual void handle_receive(const code& ec, size_t bytes,
const rpc::request_cptr& request) NOEXCEPT;
virtual void handle_send(const code& ec, size_t bytes,
const rpc::response_cptr& response,
const result_handler& handler) NOEXCEPT;

private:
void log_message(const rpc::request& request,
size_t bytes) const NOEXCEPT;
void log_message(const rpc::response& response,
size_t bytes) const NOEXCEPT;

// These are protected by strand.
http::flat_buffer_ptr response_buffer_;
http::flat_buffer request_buffer_;
dispatcher dispatcher_{};
bool reading_{};
};

} // namespace network
Expand Down
39 changes: 38 additions & 1 deletion include/bitcoin/network/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ enum error_t : uint8_t
////not_extended,
////network_authentication_required,

// boost beast error
// boost beast http error
end_of_stream,
partial_message,
need_more,
Expand Down Expand Up @@ -196,7 +196,41 @@ enum error_t : uint8_t
stale_parser,
short_read,

// boost beast websocket error
websocket_closed,
websocket_buffer_overflow,
partial_deflate_block,
message_too_big,
bad_http_version,
websocket_bad_method,
no_host,
no_connection,
no_connection_upgrade,
no_upgrade,
no_upgrade_websocket,
no_sec_key,
bad_sec_key,
no_sec_version,
bad_sec_version,
no_sec_accept,
bad_sec_accept,
upgrade_declined,
bad_opcode,
bad_data_frame,
bad_continuation,
bad_reserved_bits,
bad_control_fragment,
bad_control_size,
bad_unmasked_frame,
bad_masked_frame,
bad_size,
bad_frame_payload,
bad_close_code,
bad_close_size,
bad_close_payload,

// rpc error
message_overflow,
undefined_type,
unexpected_method,
unexpected_type,
Expand Down Expand Up @@ -240,6 +274,9 @@ BCT_API code asio_to_error_code(const boost_code& ec) NOEXCEPT;
/// 1:1 mapping of boost::beast:http::error to network (or error::unknown).
BCT_API code http_to_error_code(const boost_code& ec) NOEXCEPT;

/// 1:1 mapping of boost::beast:websocket::error to network (or error::unknown).
BCT_API code ws_to_error_code(const boost_code& ec) NOEXCEPT;

} // namespace error
} // namespace network
} // namespace libbitcoin
Expand Down
30 changes: 13 additions & 17 deletions include/bitcoin/network/messages/http_body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef LIBBITCOIN_NETWORK_MESSAGES_HTTP_BODY_HPP
#define LIBBITCOIN_NETWORK_MESSAGES_HTTP_BODY_HPP

#include <memory>
#include <optional>
#include <variant>
#include <bitcoin/network/async/async.hpp>
Expand Down Expand Up @@ -87,8 +88,8 @@ using body_value = std::variant
buffer_value,
string_value,
json_value,
rpc::in_value,
rpc::out_value
rpc::request,
rpc::response
>;

/// body template for all known message types.
Expand Down Expand Up @@ -117,8 +118,8 @@ struct BCT_API body
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, buffer_value, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, string_value, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, json_value, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, rpc::in_value, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, rpc::out_value, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, rpc::request, inner_)
FORWARD_ALTERNATIVE_VARIANT_ASSIGNMENT(value_type, rpc::response, inner_)

inline bool has_value() const NOEXCEPT
{
Expand Down Expand Up @@ -181,7 +182,7 @@ struct BCT_API body
if (value_.plain_json)
value = json_value{};
else
value = rpc::in_value{};
value = rpc::request{};
break;
case http::media_type::text_plain:
value = string_value{};
Expand All @@ -202,7 +203,7 @@ struct BCT_API body
[&](std::monostate&) NOEXCEPT {},
[&](span_value&) NOEXCEPT {},
[&](buffer_value&) NOEXCEPT {},
[&](rpc::out_value&) NOEXCEPT {},
[&](rpc::response&) NOEXCEPT {},

[&](empty_value& value) NOEXCEPT
{
Expand All @@ -225,7 +226,7 @@ struct BCT_API body
// json_reader not copy or assignable (by contained parser).
reader_.emplace<json_reader>(header, value);
},
[&](rpc::in_value& value) NOEXCEPT
[&](rpc::request& value) NOEXCEPT
{
// json_reader not copy or assignable (by contained parser).
reader_.emplace<rpc::reader>(header, value);
Expand Down Expand Up @@ -298,14 +299,14 @@ struct BCT_API body
return body_writer{ std::in_place_type<json_writer>,
header, value };
},
[&](rpc::out_value& value) NOEXCEPT
[&](rpc::response& value) NOEXCEPT
{
// json_writer is not movable (by contained serializer).
// So requires in-place construction for variant populate.
return body_writer{ std::in_place_type<rpc::writer>,
header, value };
},
[&](rpc::in_value&) NOEXCEPT
[&](rpc::request&) NOEXCEPT
{
return body_writer{ std::monostate{} };
}
Expand All @@ -317,17 +318,12 @@ struct BCT_API body
};
};

} // namespace http
} // namespace network
} // namespace libbitcoin

namespace libbitcoin {
namespace network {
namespace http {

using request = boost::beast::http::request<http::body>;
using request_cptr = std::shared_ptr<const request>;
using request_ptr = std::shared_ptr<request>;

using response = boost::beast::http::response<http::body>;
using response_cptr = std::shared_ptr<const response>;
using response_ptr = std::shared_ptr<response>;

} // namespace http
Expand Down
13 changes: 9 additions & 4 deletions include/bitcoin/network/messages/rpc/body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef LIBBITCOIN_NETWORK_MESSAGES_RPC_BODY_HPP
#define LIBBITCOIN_NETWORK_MESSAGES_RPC_BODY_HPP

#include <memory>
#include <bitcoin/network/define.hpp>
#include <bitcoin/network/messages/json_body.hpp>
#include <bitcoin/network/messages/rpc/model.hpp>
Expand Down Expand Up @@ -98,12 +99,16 @@ struct BCT_API body
};
};

// Only defines that require model.hpp, could move to independent file.
using request_body = body<request_t>;
using response_body = body<response_t>;
using in_value = request_body::value_type;
using out_value = response_body::value_type;
using request = request_body::value_type;
using request_cptr = std::shared_ptr<const request>;
using request_ptr = std::shared_ptr<request>;
using reader = request_body::reader;

using response_body = body<response_t>;
using response = response_body::value_type;
using response_cptr = std::shared_ptr<const response>;
using response_ptr = std::shared_ptr<response>;
using writer = response_body::writer;

} // namespace rpc
Expand Down
32 changes: 19 additions & 13 deletions include/bitcoin/network/net/proxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,12 @@ class BCT_API proxy
/// TCP-RPC (e.g. electrum, stratum_v1).
/// -----------------------------------------------------------------------

/// Read full rpc request from the socket, handler posted to socket strand.
virtual void read(rpc::in_value& out, count_handler&& handler) NOEXCEPT;

/// Write full rpc response to the socket, handler posted to socket strand.
virtual void write(rpc::out_value&& in, count_handler&& handler) NOEXCEPT;

/// HTTP (generic).
/// -----------------------------------------------------------------------

/// Read full http variant request from the socket, using provided buffer.
virtual void read(http::flat_buffer& buffer, http::request& request,
/// Read rpc request from the socket, using provided buffer.
virtual void read(http::flat_buffer& buffer, rpc::request& request,
count_handler&& handler) NOEXCEPT;

/// Write full http variant response to the socket (json buffer in body).
virtual void write(http::response& response,
/// Write rpc response to the socket (json buffer in body).
virtual void write(rpc::response& response,
count_handler&& handler) NOEXCEPT;

/// WS (generic).
Expand All @@ -160,6 +151,21 @@ class BCT_API proxy
virtual void ws_write(const asio::const_buffer& in, bool binary,
count_handler&& handler) NOEXCEPT;

/// WS-RPC (custom).
/// -----------------------------------------------------------------------
/// TODO.

/// HTTP (generic).
/// -----------------------------------------------------------------------

/// Read http request from the socket, using provided buffer.
virtual void read(http::flat_buffer& buffer, http::request& request,
count_handler&& handler) NOEXCEPT;

/// Write http response to the socket (json buffer in body).
virtual void write(http::response& response,
count_handler&& handler) NOEXCEPT;

private:
typedef std::deque<std::pair<asio::const_buffer, count_handler>> queue;

Expand Down
Loading
Loading