Monero
http_abstract_invoke.h
Go to the documentation of this file.
1 
2 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Andrey N. Sabelnikov nor the
13 // names of its contributors may be used to endorse or promote products
14 // derived from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
20 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 //
27 
28 #pragma once
29 #include <boost/utility/string_ref.hpp>
30 #include <chrono>
31 #include <string>
32 #include "byte_slice.h"
34 #include "net/http_base.h"
36 
37 namespace epee
38 {
39  namespace net_utils
40  {
41  template<class t_request, class t_response, class t_transport>
42  bool invoke_http_json(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
43  {
44  std::string req_param;
45  if(!serialization::store_t_to_json(out_struct, req_param))
46  return false;
47 
48  http::fields_list additional_params;
49  additional_params.push_back(std::make_pair("Content-Type","application/json; charset=utf-8"));
50 
51  const http::http_response_info* pri = NULL;
52  if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri), std::move(additional_params)))
53  {
54  LOG_PRINT_L1("Failed to invoke http request to " << uri);
55  return false;
56  }
57 
58  if(!pri)
59  {
60  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
61  return false;
62  }
63 
64  if(pri->m_response_code != 200)
65  {
66  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
67  return false;
68  }
69 
70  return serialization::load_t_from_json(result_struct, pri->m_body);
71  }
72 
73 
74 
75  template<class t_request, class t_response, class t_transport>
76  bool invoke_http_bin(const boost::string_ref uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "POST")
77  {
78  byte_slice req_param;
79  if(!serialization::store_t_to_binary(out_struct, req_param, 16 * 1024))
80  return false;
81 
82  const http::http_response_info* pri = NULL;
83  if(!transport.invoke(uri, method, boost::string_ref{reinterpret_cast<const char*>(req_param.data()), req_param.size()}, timeout, std::addressof(pri)))
84  {
85  LOG_PRINT_L1("Failed to invoke http request to " << uri);
86  return false;
87  }
88 
89  if(!pri)
90  {
91  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
92  return false;
93  }
94 
95  if(pri->m_response_code != 200)
96  {
97  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
98  return false;
99  }
100 
101  static const constexpr epee::serialization::portable_storage::limits_t default_http_bin_limits = {
102  65536 * 3, // objects
103  65536 * 3, // fields
104  65536 * 3, // strings
105  };
106  return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body), &default_http_bin_limits);
107  }
108 
109  template<class t_request, class t_response, class t_transport>
110  bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, epee::json_rpc::error &error_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
111  {
113  req_t.jsonrpc = "2.0";
114  req_t.id = req_id;
115  req_t.method = std::move(method_name);
116  req_t.params = out_struct;
118  if(!epee::net_utils::invoke_http_json(uri, req_t, resp_t, transport, timeout, http_method))
119  {
120  error_struct = {};
121  return false;
122  }
123  if(resp_t.error.code || resp_t.error.message.size())
124  {
125  error_struct = resp_t.error;
126  LOG_ERROR("RPC call of \"" << req_t.method << "\" returned error: " << resp_t.error.code << ", message: " << resp_t.error.message);
127  return false;
128  }
129  result_struct = resp_t.result;
130  return true;
131  }
132 
133  template<class t_request, class t_response, class t_transport>
134  bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
135  {
136  epee::json_rpc::error error_struct;
137  return invoke_http_json_rpc(uri, method_name, out_struct, result_struct, error_struct, transport, timeout, http_method, req_id);
138  }
139 
140  template<class t_command, class t_transport>
141  bool invoke_http_json_rpc(const boost::string_ref uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref http_method = "POST", const std::string& req_id = "0")
142  {
143  return invoke_http_json_rpc(uri, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
144  }
145 
146  }
147 }
std::list< std::pair< std::string, std::string > > fields_list
Definition: http_base.h:66
int64_t code
Definition: jsonrpc_structs.h:33
bool store_t_to_binary(t_struct &str_in, byte_slice &binary_buff, size_t initial_buffer_size=8192)
Definition: portable_storage_template_helper.h:118
std::string jsonrpc
Definition: jsonrpc_structs.h:16
Definition: jsonrpc_structs.h:31
epee::serialization::storage_entry id
Definition: jsonrpc_structs.h:18
::std::string string
Definition: gtest-port.h:1097
http_method
Definition: http_base.h:48
bool invoke_http_json_rpc(const boost::string_ref uri, std::string method_name, const t_request &out_struct, t_response &result_struct, epee::json_rpc::error &error_struct, t_transport &transport, std::chrono::milliseconds timeout=std::chrono::seconds(15), const boost::string_ref http_method="POST", const std::string &req_id="0")
Definition: http_abstract_invoke.h:110
bool invoke_http_json(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct, t_transport &transport, std::chrono::milliseconds timeout=std::chrono::seconds(15), const boost::string_ref method="POST")
Definition: http_abstract_invoke.h:42
const char * method_name
Definition: daemon_handler.cpp:55
bool store_t_to_json(t_struct &str_in, std::string &json_buff, size_t indent=0, bool insert_newlines=true)
Definition: portable_storage_template_helper.h:66
std::string method
Definition: jsonrpc_structs.h:17
bool load_t_from_json(t_struct &out, const std::string &json_buff)
Definition: portable_storage_template_helper.h:45
std::string message
Definition: jsonrpc_structs.h:34
Definition: byte_slice.h:68
int m_response_code
Definition: http_base.h:164
Definition: jsonrpc_structs.h:14
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
const T & move(const T &t)
Definition: gtest-port.h:1317
t_error error
Definition: jsonrpc_structs.h:62
#define AUTO_VAL_INIT(v)
Definition: misc_language.h:36
Definition: uri.py:1
std::string m_body
Definition: http_base.h:167
t_param result
Definition: jsonrpc_structs.h:60
t_param params
Definition: jsonrpc_structs.h:19
bool load_t_from_binary(t_struct &out, const epee::span< const uint8_t > binary_buff, const epee::serialization::portable_storage::limits_t *limits=NULL)
Definition: portable_storage_template_helper.h:91
Definition: portable_storage.h:52
bool invoke_http_bin(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct, t_transport &transport, std::chrono::milliseconds timeout=std::chrono::seconds(15), const boost::string_ref method="POST")
Definition: http_abstract_invoke.h:76
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1231
Definition: jsonrpc_structs.h:57