From de9ee9fc76de587b1fddd05e10f3dbeddcc753a3 Mon Sep 17 00:00:00 2001 From: serkixenos Date: Wed, 20 Oct 2021 14:31:03 +0200 Subject: [PATCH] cURL based HTTP/HTTPS RPC client for Hive --- .../peerplays_sidechain/CMakeLists.txt | 2 +- .../peerplays_sidechain/common/rpc_client.cpp | 80 ++++++++++++++++--- .../peerplays_sidechain/common/rpc_client.hpp | 8 +- .../sidechain_net_handler_hive.cpp | 16 ++-- 4 files changed, 87 insertions(+), 19 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/CMakeLists.txt b/libraries/plugins/peerplays_sidechain/CMakeLists.txt index 48dd44f1..bb74df29 100755 --- a/libraries/plugins/peerplays_sidechain/CMakeLists.txt +++ b/libraries/plugins/peerplays_sidechain/CMakeLists.txt @@ -43,7 +43,7 @@ endif() unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS) unset(ENABLE_PEERPLAYS_ASSET_DEPOSITS CACHE) -target_link_libraries( peerplays_sidechain PRIVATE graphene_plugin zmq ) +target_link_libraries( peerplays_sidechain PRIVATE curl graphene_plugin zmq ) target_include_directories( peerplays_sidechain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) diff --git a/libraries/plugins/peerplays_sidechain/common/rpc_client.cpp b/libraries/plugins/peerplays_sidechain/common/rpc_client.cpp index cb7c5251..cad283a7 100644 --- a/libraries/plugins/peerplays_sidechain/common/rpc_client.cpp +++ b/libraries/plugins/peerplays_sidechain/common/rpc_client.cpp @@ -1,13 +1,16 @@ #include #include +#include #include #include +#include + #include #include -#include +//#include namespace graphene { namespace peerplays_sidechain { @@ -99,19 +102,78 @@ std::string rpc_client::send_post_request(std::string method, std::string params return ""; } -fc::http::reply rpc_client::send_post_request(std::string body, bool show_log) { - fc::http::connection conn; - conn.connect_to(fc::ip::endpoint(fc::ip::address(ip), port)); +//fc::http::reply rpc_client::send_post_request(std::string body, bool show_log) { +// fc::http::connection conn; +// conn.connect_to(fc::ip::endpoint(fc::ip::address(ip), port)); +// +// std::string url = "http://" + ip + ":" + std::to_string(port); +// +// //if (wallet.length() > 0) { +// // url = url + "/wallet/" + wallet; +// //} +// +// fc::http::reply reply = conn.request("POST", url, body, fc::http::headers{authorization}); +// +// 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())); +// } +// +// return reply; +//} - std::string url = "http://" + ip + ":" + std::to_string(port); +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; +} - //if (wallet.length() > 0) { - // url = url + "/wallet/" + wallet; - //} +rpc_reply rpc_client::send_post_request(std::string body, bool show_log) { - fc::http::reply reply = conn.request("POST", url, body, fc::http::headers{authorization}); + 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"); + + CURL *curl = curl_easy_init(); + if (ip.find("https://", 0) != 0) { + curl_easy_setopt(curl, CURLOPT_URL, ip.c_str()); + curl_easy_setopt(curl, CURLOPT_PORT, port); + } else { + std::string full_address = ip + ":" + std::to_string(port); + curl_easy_setopt(curl, CURLOPT_URL, full_address.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); + } + if (!user.empty()) { + curl_easy_setopt(curl, CURLOPT_USERNAME, user.c_str()); + curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str()); + } + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str()); + + //curl_easy_setopt(curl, CURLOPT_VERBOSE, true); + + 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); if (show_log) { + std::string url = ip + ":" + std::to_string(port); ilog("### Request URL: ${url}", ("url", url)); ilog("### Request: ${body}", ("body", body)); std::stringstream ss(std::string(reply.body.begin(), reply.body.end())); diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/common/rpc_client.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/common/rpc_client.hpp index c3edd145..f61bdb3f 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/common/rpc_client.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/common/rpc_client.hpp @@ -7,6 +7,11 @@ namespace graphene { namespace peerplays_sidechain { +struct rpc_reply { + uint16_t status; + std::string body; +}; + class rpc_client { public: rpc_client(std::string _ip, uint32_t _port, std::string _user, std::string _password, bool _debug_rpc_calls); @@ -27,7 +32,8 @@ protected: fc::http::header authorization; private: - fc::http::reply send_post_request(std::string body, bool show_log); + //fc::http::reply send_post_request(std::string body, bool show_log); + rpc_reply send_post_request(std::string body, bool show_log); }; }} // namespace graphene::peerplays_sidechain diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp index b1945588..e1a5c329 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_hive.cpp @@ -35,7 +35,7 @@ hive_node_rpc_client::hive_node_rpc_client(std::string _ip, uint32_t _port, std: } std::string hive_node_rpc_client::account_history_api_get_transaction(std::string transaction_id) { - std::string params = "{ \"id\": \"" + transaction_id + "\" }"; + std::string params = "{ \"id\": \"" + transaction_id + "\", \"include_reversible\": \"true\" }"; return send_post_request("account_history_api.get_transaction", params, debug_rpc_calls); } @@ -145,13 +145,13 @@ sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugi } } - fc::http::connection conn; - try { - conn.connect_to(fc::ip::endpoint(fc::ip::address(node_ip), node_rpc_port)); - } catch (fc::exception &e) { - elog("No Hive node running at ${ip} or wrong rpc port: ${port}", ("ip", node_ip)("port", node_rpc_port)); - FC_ASSERT(false); - } + //fc::http::connection conn; + //try { + // conn.connect_to(fc::ip::endpoint(fc::ip::address(node_ip), node_rpc_port)); + //} catch (fc::exception &e) { + // elog("No Hive node running at ${ip} or wrong rpc port: ${port}", ("ip", node_ip)("port", node_rpc_port)); + // FC_ASSERT(false); + //} node_rpc_client = new hive_node_rpc_client(node_ip, node_rpc_port, node_rpc_user, node_rpc_password, debug_rpc_calls);