forked from lthn/blockchain
implemented https support and tokens whitelisting(just inital declaration)
This commit is contained in:
parent
a493ace766
commit
e839761ae9
4 changed files with 667 additions and 747 deletions
|
|
@ -38,9 +38,9 @@
|
|||
#include "net_helper.h"
|
||||
#include "http_client_base.h"
|
||||
|
||||
//#ifdef HTTP_ENABLE_GZIP
|
||||
#ifdef HTTP_ENABLE_GZIP
|
||||
#include "gzip_encoding.h"
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
#include "string_tools.h"
|
||||
#include "reg_exp_definer.h"
|
||||
|
|
@ -200,8 +200,8 @@ using namespace std;
|
|||
|
||||
namespace http
|
||||
{
|
||||
|
||||
class http_simple_client: public i_target_handler
|
||||
template<bool is_ssl>
|
||||
class http_simple_client_t: public i_target_handler
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -227,14 +227,14 @@ using namespace std;
|
|||
};
|
||||
|
||||
|
||||
blocked_mode_client m_net_client;
|
||||
blocked_mode_client_t<is_ssl> m_net_client;
|
||||
std::string m_host_buff;
|
||||
std::string m_port;
|
||||
//unsigned int m_timeout;
|
||||
unsigned int m_connection_timeout;
|
||||
unsigned int m_recv_timeout;
|
||||
unsigned int m_timeout;
|
||||
std::string m_header_cache;
|
||||
http_response_info m_response_info;
|
||||
size_t m_len_in_summary;
|
||||
size_t m_len_in_remain;
|
||||
//std::string* m_ptarget_buffer;
|
||||
boost::shared_ptr<i_sub_handler> m_pcontent_encoding_handler;
|
||||
reciev_machine_state m_state;
|
||||
|
|
@ -242,10 +242,6 @@ using namespace std;
|
|||
std::string m_chunked_cache;
|
||||
critical_section m_lock;
|
||||
|
||||
protected:
|
||||
uint64_t m_len_in_summary;
|
||||
uint64_t m_len_in_remain;
|
||||
|
||||
public:
|
||||
void set_host_name(const std::string& name)
|
||||
{
|
||||
|
|
@ -253,37 +249,24 @@ using namespace std;
|
|||
m_host_buff = name;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& get_socket()
|
||||
{
|
||||
return m_net_client.get_socket();
|
||||
}
|
||||
//boost::asio::ip::tcp::socket& get_socket()
|
||||
//{
|
||||
// return m_net_client.get_socket();
|
||||
//}
|
||||
|
||||
|
||||
bool connect(const std::string& host, int port, unsigned int timeout)
|
||||
{
|
||||
return connect(host, std::to_string(port), timeout);
|
||||
}
|
||||
|
||||
bool set_timeouts(unsigned int connection_timeout, unsigned int recv_timeout)
|
||||
{
|
||||
m_connection_timeout = connection_timeout;
|
||||
m_recv_timeout = recv_timeout;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool connect(const std::string& host, std::string port)
|
||||
bool connect(const std::string& host, const std::string& port, unsigned int timeout)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
m_host_buff = host;
|
||||
m_port = port;
|
||||
m_timeout = timeout;
|
||||
|
||||
return m_net_client.connect(host, port, m_connection_timeout, m_recv_timeout);
|
||||
}
|
||||
|
||||
bool connect(const std::string& host, const std::string& port, unsigned int timeout)
|
||||
{
|
||||
m_connection_timeout = m_recv_timeout = timeout;
|
||||
return connect(host, port);
|
||||
return m_net_client.connect(host, port, timeout, timeout);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool disconnect()
|
||||
|
|
@ -320,7 +303,7 @@ using namespace std;
|
|||
if(!is_connected())
|
||||
{
|
||||
LOG_PRINT("Reconnecting...", LOG_LEVEL_3);
|
||||
if(!connect(m_host_buff, m_port))
|
||||
if(!connect(m_host_buff, m_port, m_timeout))
|
||||
{
|
||||
LOG_PRINT("Failed to connect to " << m_host_buff << ":" << m_port, LOG_LEVEL_3);
|
||||
return false;
|
||||
|
|
@ -464,14 +447,7 @@ using namespace std;
|
|||
}
|
||||
CHECK_AND_ASSERT_MES(m_len_in_remain >= recv_buff.size(), false, "m_len_in_remain >= recv_buff.size()");
|
||||
m_len_in_remain -= recv_buff.size();
|
||||
bool r = m_pcontent_encoding_handler->update_in(recv_buff);
|
||||
//CHECK_AND_ASSERT_MES(m_len_in_remain >= recv_buff.size(), false, "m_pcontent_encoding_handler->update_in returned false");
|
||||
if (!r)
|
||||
{
|
||||
m_state = reciev_machine_state_error;
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
m_pcontent_encoding_handler->update_in(recv_buff);
|
||||
|
||||
if(m_len_in_remain == 0)
|
||||
m_state = reciev_machine_state_done;
|
||||
|
|
@ -507,7 +483,7 @@ using namespace std;
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline
|
||||
bool get_len_from_chunk_head(const std::string &chunk_head, uint64_t& result_size)
|
||||
bool get_len_from_chunk_head(const std::string &chunk_head, size_t& result_size)
|
||||
{
|
||||
std::stringstream str_stream;
|
||||
str_stream << std::hex;
|
||||
|
|
@ -518,7 +494,7 @@ using namespace std;
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline
|
||||
bool get_chunk_head(std::string& buff, uint64_t& chunk_size, bool& is_matched)
|
||||
bool get_chunk_head(std::string& buff, size_t& chunk_size, bool& is_matched)
|
||||
{
|
||||
is_matched = false;
|
||||
size_t offset = 0;
|
||||
|
|
@ -831,7 +807,7 @@ using namespace std;
|
|||
return false;
|
||||
}else
|
||||
{ //Apparently there are no signs of the form of transfer, will receive data until the connection is closed
|
||||
m_state = reciev_machine_state_body_connection_close;
|
||||
m_state = reciev_machine_state_error;
|
||||
LOG_PRINT("Undefinded transfer type, consider http_body_transfer_connection_close method. header: " << m_header_cache, LOG_LEVEL_2);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -874,13 +850,14 @@ using namespace std;
|
|||
return true;
|
||||
}
|
||||
};
|
||||
// class http_simple_client
|
||||
|
||||
|
||||
typedef http_simple_client_t<false> http_simple_client;
|
||||
typedef http_simple_client_t<true> https_simple_client;
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
//inline
|
||||
template<class t_transport>
|
||||
bool invoke_request(const std::string& url, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
|
||||
{
|
||||
|
|
@ -894,150 +871,13 @@ using namespace std;
|
|||
if(!u_c.port)
|
||||
u_c.port = 80;//default for http
|
||||
|
||||
if (!tr.connect(u_c.host, static_cast<int>(u_c.port), timeout))
|
||||
{
|
||||
LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << u_c.port);
|
||||
return false;
|
||||
}
|
||||
res = tr.connect(u_c.host, static_cast<int>(u_c.port), timeout);
|
||||
CHECK_AND_ASSERT_MES(res, false, "failed to connect " << u_c.host << ":" << u_c.port);
|
||||
}
|
||||
|
||||
return tr.invoke(u_c.uri, method, body, ppresponse_info, additional_params);
|
||||
}
|
||||
|
||||
struct idle_handler_base
|
||||
{
|
||||
virtual bool do_call(const std::string& piece_of_data, uint64_t total_bytes, uint64_t received_bytes) = 0;
|
||||
virtual ~idle_handler_base() {}
|
||||
};
|
||||
|
||||
template <typename callback_t>
|
||||
struct idle_handler : public idle_handler_base
|
||||
{
|
||||
callback_t m_cb;
|
||||
|
||||
idle_handler(callback_t cb) : m_cb(cb) {}
|
||||
virtual bool do_call(const std::string& piece_of_data, uint64_t total_bytes, uint64_t received_bytes)
|
||||
{
|
||||
return m_cb(piece_of_data, total_bytes, received_bytes);
|
||||
}
|
||||
};
|
||||
|
||||
class interruptible_http_client : public http_simple_client
|
||||
{
|
||||
std::shared_ptr<idle_handler_base> m_pcb;
|
||||
bool m_permanent_error = false;
|
||||
|
||||
virtual bool handle_target_data(std::string& piece_of_transfer)
|
||||
{
|
||||
bool r = m_pcb->do_call(piece_of_transfer, m_len_in_summary, m_len_in_summary - m_len_in_remain);
|
||||
piece_of_transfer.clear();
|
||||
return r;
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename callback_t>
|
||||
bool invoke_cb(callback_t cb, const std::string& url, uint64_t timeout, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
|
||||
{
|
||||
m_pcb.reset(new idle_handler<callback_t>(cb));
|
||||
const http_response_info* p_hri = nullptr;
|
||||
bool r = invoke_request(url, *this, timeout, &p_hri, method, body, additional_params);
|
||||
if (p_hri && !(p_hri->m_response_code >= 200 && p_hri->m_response_code < 300))
|
||||
{
|
||||
LOG_PRINT_L0("HTTP request to " << url << " failed with code: " << p_hri->m_response_code);
|
||||
m_permanent_error = true;
|
||||
return false;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename callback_t>
|
||||
bool download(callback_t cb, const std::string& path_for_file, const std::string& url, uint64_t timeout, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
|
||||
{
|
||||
std::ofstream fs;
|
||||
fs.open(path_for_file, std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
if (!fs.is_open())
|
||||
{
|
||||
LOG_ERROR("Fsiled to open " << path_for_file);
|
||||
return false;
|
||||
}
|
||||
auto local_cb = [&](const std::string& piece_of_data, uint64_t total_bytes, uint64_t received_bytes)
|
||||
{
|
||||
fs.write(piece_of_data.data(), piece_of_data.size());
|
||||
return cb(total_bytes, received_bytes);
|
||||
};
|
||||
bool r = this->invoke_cb(local_cb, url, timeout, method, body, additional_params);
|
||||
fs.close();
|
||||
return r;
|
||||
}
|
||||
|
||||
//
|
||||
template<typename callback_t>
|
||||
bool download_and_unzip(callback_t cb, const std::string& path_for_file, const std::string& url, uint64_t timeout, const std::string& method = "GET", const std::string& body = std::string(), uint64_t fails_count = 1000, const fields_list& additional_params = fields_list())
|
||||
{
|
||||
std::ofstream fs;
|
||||
fs.open(path_for_file, std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
if (!fs.is_open())
|
||||
{
|
||||
LOG_ERROR("Fsiled to open " << path_for_file);
|
||||
return false;
|
||||
}
|
||||
std::string buff;
|
||||
gzip_decoder_lambda zip_decoder;
|
||||
uint64_t state_total_bytes = 0;
|
||||
uint64_t state_received_bytes_base = 0;
|
||||
uint64_t state_received_bytes_current = 0;
|
||||
bool stopped = false;
|
||||
auto local_cb = [&](const std::string& piece_of_data, uint64_t total_bytes, uint64_t received_bytes)
|
||||
{
|
||||
//remember total_bytes only for first attempt, where fetched full lenght of the file
|
||||
if (!state_total_bytes)
|
||||
state_total_bytes = total_bytes;
|
||||
|
||||
buff += piece_of_data;
|
||||
return zip_decoder.update_in(buff, [&](const std::string& unpacked_buff)
|
||||
{
|
||||
state_received_bytes_current = received_bytes;
|
||||
fs.write(unpacked_buff.data(), unpacked_buff.size());
|
||||
stopped = !cb(unpacked_buff, state_total_bytes, state_received_bytes_base + received_bytes);
|
||||
return !stopped;
|
||||
});
|
||||
};
|
||||
uint64_t current_err_count = 0;
|
||||
bool r = false;
|
||||
m_permanent_error = false;
|
||||
while (!r && current_err_count < fails_count)
|
||||
{
|
||||
LOG_PRINT_L0("Attempt " << current_err_count + 1 << "/" << fails_count << " to get " << url << " (offset:" << state_received_bytes_base << ")");
|
||||
fields_list additional_params_local = additional_params;
|
||||
additional_params_local.push_back(std::make_pair<std::string, std::string>("Range", std::string("bytes=") + std::to_string(state_received_bytes_base) + "-"));
|
||||
r = this->invoke_cb(local_cb, url, timeout, method, body, additional_params_local);
|
||||
if (!r)
|
||||
{
|
||||
if (stopped || m_permanent_error)
|
||||
break;
|
||||
current_err_count++;
|
||||
state_received_bytes_base += state_received_bytes_current;
|
||||
state_received_bytes_current = 0;
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(2000));
|
||||
}
|
||||
}
|
||||
|
||||
if (current_err_count >= fails_count)
|
||||
{
|
||||
LOG_PRINT_YELLOW("Downloading from " << url << " FAILED as it's reached maximum (" << fails_count << ") number of attempts. Downloaded " << state_received_bytes_base << " bytes.", LOG_LEVEL_0);
|
||||
}
|
||||
else if (m_permanent_error)
|
||||
{
|
||||
LOG_PRINT_YELLOW("Downloading from " << url << " FAILED due to permanent HTTP error. Downloaded " << state_received_bytes_base << " bytes.", LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
fs.close();
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace http
|
||||
|
||||
} // namespace net_utils
|
||||
} // namespace epee
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3154,6 +3154,11 @@ bool wallet2::delete_custom_asset_id(const crypto::hash& asset_id)
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::load_whitelisted_tokens_list()
|
||||
{
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) const
|
||||
|
|
|
|||
|
|
@ -897,7 +897,9 @@ namespace tools
|
|||
void export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions = true);
|
||||
|
||||
bool add_custom_asset_id(const crypto::hash& asset_id);
|
||||
|
||||
bool delete_custom_asset_id(const crypto::hash& asset_id);
|
||||
bool load_whitelisted_tokens_list();
|
||||
|
||||
/*
|
||||
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
|
||||
we use deterministic origin, if given some particular htlc_hash, then we use this hash, and this means that
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue