Merge branch 'feature/new-rpc-ws-clients' into feature/son-for-ethereum
This commit is contained in:
commit
73163d2722
2 changed files with 85 additions and 38 deletions
|
|
@ -1,10 +1,15 @@
|
|||
#include <graphene/peerplays_sidechain/common/rpc_client.hpp>
|
||||
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/asio/buffers_iterator.hpp>
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/xpressive/xpressive.hpp>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
|
@ -18,6 +23,35 @@ rpc_client::rpc_client(std::string _url, std::string _user, std::string _passwor
|
|||
password(_password),
|
||||
debug_rpc_calls(_debug_rpc_calls),
|
||||
request_id(0) {
|
||||
|
||||
std::string reg_expr = "^((?P<Protocol>https|http):\\/\\/)?(?P<Host>[a-zA-Z0-9\\-\\.]+)(:(?P<Port>\\d{1,5}))?(?P<Target>\\/.+)?";
|
||||
boost::xpressive::sregex sr = boost::xpressive::sregex::compile(reg_expr);
|
||||
|
||||
boost::xpressive::smatch sm;
|
||||
|
||||
if (boost::xpressive::regex_search(url, sm, sr)) {
|
||||
protocol = sm["Protocol"];
|
||||
if (protocol.empty()) {
|
||||
protocol = "http";
|
||||
}
|
||||
|
||||
host = sm["Host"];
|
||||
if (host.empty()) {
|
||||
host + "localhost";
|
||||
}
|
||||
|
||||
port = sm["Port"];
|
||||
if (port.empty()) {
|
||||
port = "80";
|
||||
}
|
||||
|
||||
target = sm["Target"];
|
||||
if (target.empty()) {
|
||||
target = "/";
|
||||
}
|
||||
} else {
|
||||
elog("Invalid URL: ${url}", ("url", url));
|
||||
}
|
||||
}
|
||||
|
||||
std::string rpc_client::retrieve_array_value_from_reply(std::string reply_str, std::string array_path, uint32_t idx) {
|
||||
|
|
@ -98,57 +132,65 @@ std::string rpc_client::send_post_request(std::string method, std::string params
|
|||
return "";
|
||||
}
|
||||
|
||||
static size_t write_callback(char *ptr, size_t size, size_t nmemb, rpc_reply *reply) {
|
||||
size_t retval = 0;
|
||||
if (reply != nullptr) {
|
||||
reply->body.append(ptr, size * nmemb);
|
||||
retval = size * nmemb;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
rpc_reply rpc_client::send_post_request(std::string body, bool show_log) {
|
||||
|
||||
struct curl_slist *headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Accept: application/json");
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
headers = curl_slist_append(headers, "charset: utf-8");
|
||||
// The io_context is required for all I/O
|
||||
boost::beast::net::io_context ioc;
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
// These objects perform our I/O
|
||||
boost::beast::net::ip::tcp::resolver resolver(ioc);
|
||||
boost::beast::tcp_stream stream(ioc);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
if (url.find("https://", 0) == 0) {
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
// Look up the domain name
|
||||
auto const results = resolver.resolve(host, port);
|
||||
|
||||
if (!user.empty()) {
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, user.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
|
||||
}
|
||||
// Make the connection on the IP address we get from a lookup
|
||||
stream.connect(results);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
||||
// Set up an HTTP GET request message
|
||||
boost::beast::http::request<boost::beast::http::string_body> req{boost::beast::http::verb::post, target, 11};
|
||||
req.set(boost::beast::http::field::host, host + ":" + port);
|
||||
req.set(boost::beast::http::field::accept, "application/json");
|
||||
req.set(boost::beast::http::field::content_type, "application/json");
|
||||
req.set(boost::beast::http::field::content_encoding, "utf-8");
|
||||
req.set(boost::beast::http::field::content_length, body.length());
|
||||
req.body() = body;
|
||||
|
||||
//curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
|
||||
// Send the HTTP request to the remote host
|
||||
boost::beast::http::write(stream, req);
|
||||
|
||||
// This buffer is used for reading and must be persisted
|
||||
boost::beast::flat_buffer buffer;
|
||||
|
||||
// Declare a container to hold the response
|
||||
boost::beast::http::response<boost::beast::http::dynamic_body> res;
|
||||
|
||||
// Receive the HTTP response
|
||||
boost::beast::http::read(stream, buffer, res);
|
||||
|
||||
//// Write the message to standard out
|
||||
//std::cout << res << std::endl;
|
||||
|
||||
// Gracefully close the socket
|
||||
boost::beast::error_code ec;
|
||||
stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
|
||||
// not_connected happens sometimes
|
||||
// so don't bother reporting it.
|
||||
//
|
||||
if (ec && ec != boost::beast::errc::not_connected)
|
||||
throw boost::beast::system_error{ec};
|
||||
|
||||
std::string rbody{boost::asio::buffers_begin(res.body().data()),
|
||||
boost::asio::buffers_end(res.body().data())};
|
||||
rpc_reply reply;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &reply);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &reply.status);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_slist_free_all(headers);
|
||||
reply.status = 200;
|
||||
reply.body = rbody;
|
||||
|
||||
if (show_log) {
|
||||
ilog("### Request URL: ${url}", ("url", url));
|
||||
ilog("### Request: ${body}", ("body", body));
|
||||
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
|
||||
ilog("### Response: ${ss}", ("ss", ss.str()));
|
||||
ilog("### Response: ${rbody}", ("rbody", rbody));
|
||||
}
|
||||
|
||||
return reply;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ protected:
|
|||
std::string send_post_request(std::string method, std::string params, bool show_log);
|
||||
|
||||
std::string url;
|
||||
std::string protocol;
|
||||
std::string host;
|
||||
std::string port;
|
||||
std::string target;
|
||||
|
||||
std::string user;
|
||||
std::string password;
|
||||
bool debug_rpc_calls;
|
||||
|
|
|
|||
Loading…
Reference in a new issue