1
0
Fork 0
forked from lthn/blockchain

implemented https support and tokens whitelisting(just inital declaration)

This commit is contained in:
cryptozoidberg 2022-11-16 22:16:15 +01:00
parent a493ace766
commit e839761ae9
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
4 changed files with 667 additions and 747 deletions

View file

@ -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

View file

@ -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

View file

@ -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