Electroneum
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>
33 #include "net/http_base.h"
35 
36 namespace epee
37 {
38  namespace net_utils
39  {
40  template<class t_request, class t_response, class t_transport>
41  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 = "GET")
42  {
43  std::string req_param;
44  if(!serialization::store_t_to_json(out_struct, req_param))
45  return false;
46 
47  http::fields_list additional_params;
48  additional_params.push_back(std::make_pair("Content-Type","application/json; charset=utf-8"));
49 
50  const http::http_response_info* pri = NULL;
51  if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri), std::move(additional_params)))
52  {
53  LOG_PRINT_L1("Failed to invoke http request to " << uri);
54  return false;
55  }
56 
57  if(!pri)
58  {
59  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
60  return false;
61  }
62 
63  if(pri->m_response_code != 200)
64  {
65  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
66  return false;
67  }
68 
69  return serialization::load_t_from_json(result_struct, pri->m_body);
70  }
71 
72  template<class t_response, class t_transport>
73  bool get_http_json(const boost::string_ref uri, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(15), const boost::string_ref method = "GET") {
74 
75  const http::http_response_info* pri = NULL;
76  int retryCount = 0;
77  const int MAX_RETRY_COUNT = 10;
78 
79  //Boost asio read can be temperemental
80  while(!transport.invoke(uri, method, "", timeout, std::addressof(pri)) && retryCount < MAX_RETRY_COUNT) {
82  ++retryCount;
83  LOG_PRINT_L1("Failed to invoke http request. Retrying (" << retryCount << "/" << MAX_RETRY_COUNT << ").");
84  }
85 
86  if(retryCount == MAX_RETRY_COUNT) //Max retries reached
87  {
88  LOG_PRINT_L1("Failed to invoke http request to " << uri);
89  return false;
90  }
91 
92  if(!pri)
93  {
94  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
95  return false;
96  }
97 
98  if(pri->m_response_code != 200)
99  {
100  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
101  return false;
102  }
103 
104  return serialization::load_t_from_json(result_struct, pri->m_body);
105  }
106 
107 
108  template<class t_request, class t_response, class t_transport>
109  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 = "GET")
110  {
111  std::string req_param;
112  if(!serialization::store_t_to_binary(out_struct, req_param))
113  return false;
114 
115  const http::http_response_info* pri = NULL;
116  if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
117  {
118  LOG_PRINT_L1("Failed to invoke http request to " << uri);
119  return false;
120  }
121 
122  if(!pri)
123  {
124  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
125  return false;
126  }
127 
128  if(pri->m_response_code != 200)
129  {
130  LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
131  return false;
132  }
133 
134  return serialization::load_t_from_binary(result_struct, epee::strspan<uint8_t>(pri->m_body));
135  }
136 
137  template<class t_request, class t_response, class t_transport>
138  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 = "GET", const std::string& req_id = "0")
139  {
141  req_t.jsonrpc = "2.0";
142  req_t.id = req_id;
143  req_t.method = std::move(method_name);
144  req_t.params = out_struct;
146  if(!epee::net_utils::invoke_http_json(uri, req_t, resp_t, transport, timeout, http_method))
147  {
148  return false;
149  }
150  if(resp_t.error.code || resp_t.error.message.size())
151  {
152  LOG_ERROR("RPC call of \"" << req_t.method << "\" returned error: " << resp_t.error.code << ", message: " << resp_t.error.message);
153  return false;
154  }
155  result_struct = resp_t.result;
156  return true;
157  }
158 
159  template<class t_command, class t_transport>
160  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 = "GET", const std::string& req_id = "0")
161  {
162  return invoke_http_json_rpc(uri, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
163  }
164 
165  }
166 }
bool store_t_to_binary(t_struct &str_in, std::string &binary_buff, size_t indent=0)
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="GET")
std::list< std::pair< std::string, std::string > > fields_list
Definition: http_base.h:66
#define LOG_PRINT_L1(x)
Definition: misc_log_ex.h:100
epee::serialization::storage_entry id
::std::string string
Definition: gtest-port.h:1097
epee::misc_utils::struct_init< response_t > response
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="GET")
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="GET", const std::string &req_id="0")
bool store_t_to_json(t_struct &str_in, std::string &json_buff, size_t indent=0, bool insert_newlines=true)
bool load_t_from_json(t_struct &out, const std::string &json_buff)
bool load_t_from_binary(t_struct &out, const epee::span< const uint8_t > binary_buff)
bool sleep_no_w(long ms)
const T & move(const T &t)
Definition: gtest-port.h:1317
#define LOG_ERROR(x)
Definition: misc_log_ex.h:98
#define AUTO_VAL_INIT(v)
Definition: misc_language.h:53
bool get_http_json(const boost::string_ref uri, t_response &result_struct, t_transport &transport, std::chrono::milliseconds timeout=std::chrono::seconds(15), const boost::string_ref method="GET")
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1204