31#include <boost/shared_ptr.hpp>
32#include <boost/regex.hpp>
33#include <boost/optional/optional.hpp>
34#include <boost/utility/string_ref.hpp>
55#undef MONERO_DEFAULT_LOG_CATEGORY
56#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
106 template<
typename net_client_type>
192 bool connect(std::chrono::milliseconds timeout)
override
219 piece_of_transfer.clear();
231 return invoke(
uri,
"GET", body, timeout, ppresponse_info, additional_params);
235 inline bool invoke(
const boost::string_ref
uri,
const boost::string_ref method,
const boost::string_ref body, std::chrono::milliseconds timeout,
const http_response_info** ppresponse_info = NULL,
const fields_list& additional_params =
fields_list())
override
242 MWARNING(
"Auto connect attempt to " <<
m_host_buff <<
":" <<
m_port <<
" disabled");
245 MDEBUG(
"Reconnecting...");
253 std::string req_buff{};
254 req_buff.reserve(2048);
255 req_buff.append(method.data(), method.size()).append(
" ").append(
uri.data(),
uri.size()).append(
" HTTP/1.1\r\n");
257 add_field(req_buff,
"Content-Length", std::to_string(body.size()));
260 for(
const auto& field : additional_params)
261 add_field(req_buff, field);
263 for (
unsigned sends = 0; sends < 2; ++sends)
265 const std::size_t initial_size = req_buff.size();
268 add_field(req_buff, *auth);
274 CHECK_AND_ASSERT_MES(res,
false,
"HTTP_CLIENT: Failed to SEND");
277 CHECK_AND_ASSERT_MES(res,
false,
"HTTP_CLIENT: Failed to SEND");
299 LOG_ERROR(
"Bad server response for authentication");
302 req_buff.resize(initial_size);
304 LOG_ERROR(
"Client has incorrect username/password for server requiring authentication");
311 return invoke(
uri,
"POST", body, timeout, ppresponse_info, additional_params);
314 bool test(
const std::string &
s, std::chrono::milliseconds timeout)
342 bool keep_handling =
true;
343 bool need_more_data =
true;
344 std::string recv_buffer;
351 MERROR(
"Unexpected recv fail");
354 if(!recv_buffer.size())
362 need_more_data =
false;
379 keep_handling =
false;
382 keep_handling =
false;
397 LOG_PRINT_L3(
"Returning false because of wrong state machine. state: " <<
m_state);
407 if(!recv_buff.size())
409 LOG_ERROR(
"Connection closed at handle_header");
417 if(pos != std::string::npos)
429 MDEBUG(
"Connection cancelled by on_header");
435 need_more_data =
true;
439 need_more_data =
true;
447 if(!recv_buff.size())
449 MERROR(
"Warning: Content-Len mode, but connection unexpectedly closed");
453 CHECK_AND_ASSERT_MES(
m_len_in_remain >= recv_buff.size(),
false,
"m_len_in_remain >= recv_buff.size()");
464 need_more_data =
true;
473 if(!recv_buff.size())
478 need_more_data =
true;
488 if( (ch >=
'0' && ch <=
'9')||(ch >=
'A' && ch <=
'F')||(ch >=
'a' && ch <=
'f'))
497 std::stringstream str_stream;
498 str_stream << std::hex;
499 if(!(str_stream << chunk_head && str_stream >> result_size))
510 for(std::string::iterator it = buff.begin(); it!= buff.end(); it++, offset++)
514 if(*it ==
'\r' || *it ==
' ' )
521 std::string chunk_head = buff.substr(0, offset);
531 for(it++;it != buff.end(); it++)
539 LOG_ERROR(
"http_stream_filter: Wrong last chunk terminator");
548 buff.erase(buff.begin(), ++it);
565 if(!recv_buff.size())
567 MERROR(
"Warning: CHUNKED mode, but connection unexpectedly closed");
573 bool is_matched =
false;
579 need_more_data =
true;
597 LOG_ERROR(
"http_stream_filter::handle_chunked(*) Failed to get length from chunked head (" <<
m_chunked_cache.size() <<
" bytes)");
604 need_more_data =
true;
620 std::string chunk_body;
647 LOG_ERROR(
"http_stream_filter::handle_chunked(): Wrong state" <<
m_chunked_state);
657 MTRACE(
"http_stream_filter::parse_cached_header(*)");
660 while(cur < m_cache_to_process.size())
662 const size_t line_end = m_cache_to_process.find(
'\n', cur);
663 CHECK_AND_ASSERT_MES(line_end != std::string::npos,
false,
"http_stream_filter::parse_cached_header() invalid header (" << m_cache_to_process.size() <<
" bytes)");
665 boost::string_view line(m_cache_to_process.data() + cur, line_end - cur);
668 if(line ==
"\r" || line.empty())
671 boost::string_view name;
672 boost::string_view
value;
673 CHECK_AND_ASSERT_MES(
detail::parse_header_line(line, name,
value),
false,
"http_stream_filter::parse_cached_header() invalid header (" << m_cache_to_process.size() <<
" bytes)");
675 std::string key(name.data(), name.size());
690 body_info.
m_host = std::move(val);
692 body_info.
m_cookie = std::move(val);
696 body_info.
m_origin = std::move(val);
698 body_info.
m_etc_fields.emplace_back(std::move(key), std::move(val));
707 CHECK_AND_ASSERT_MES(!memcmp(ptr,
"HTTP/", 5),
false,
"Invalid first response line (" <<
m_header_cache.size() <<
" header bytes)");
712 ul = strtoul(ptr, &end, 10);
713 CHECK_AND_ASSERT_MES(ul <= INT_MAX && *end ==
'.',
false,
"Invalid first response line (" <<
m_header_cache.size() <<
" header bytes)");
717 ul = strtoul(ptr, &end, 10);
718 CHECK_AND_ASSERT_MES(ul <= INT_MAX && isblank(*end),
false,
"Invalid first response line (" <<
m_header_cache.size() <<
" header bytes)");
721 while (isblank(*ptr))
724 ul = strtoul(ptr, &end, 10);
725 CHECK_AND_ASSERT_MES(ul >= 100 && ul <= 999 &&
isspace(*end),
false,
"Invalid first response line (" <<
m_header_cache.size() <<
" header bytes)");
729 while (*ptr !=
'\r' && *ptr !=
'\n')
733 CHECK_AND_ASSERT_MES(*ptr ==
'\n',
false,
"Invalid first response line (" <<
m_header_cache.size() <<
" header bytes)");
742 STATIC_REGEXP_EXPR_1(rexp_match_gzip,
"^.*?((gzip)|(deflate))", boost::regex::icase | boost::regex::normal);
747 LOG_ERROR(
"GZIP encoding not supported");
762 std::string fake_str;
765 CHECK_AND_ASSERT_MES(res,
false,
"http_stream_filter::analize_cached_reply_header_and_invoke_state(): failed to anilize reply header (" <<
m_header_cache.size() <<
" bytes)");
770 bool content_len_valid =
false;
798 if(!content_len_valid)
821 LOG_ERROR(
"Unsupported MULTIPART BODY.");
826 MERROR(
"Undefined transfer type, consider http_body_transfer_connection_close method (" <<
m_header_cache.size() <<
" header bytes)");
834 STATIC_REGEXP_EXPR_1(rexp_match_close,
"^\\s*close", boost::regex::icase | boost::regex::normal);
836 if(boost::regex_search( str,
result, rexp_match_close, boost::match_default) &&
result[0].matched)
845 STATIC_REGEXP_EXPR_1(rexp_match_multipart_type,
"^\\s*multipart/([\\w\\-]+); boundary=((\"(.*?)\")|(\\\\\"(.*?)\\\\\")|([^\\s;]*))", boost::regex::icase | boost::regex::normal);
847 if(boost::regex_search(head_info.
m_content_type,
result, rexp_match_multipart_type, boost::match_default) &&
result[0].matched)
851 else if(
result[6].matched)
853 else if(
result[7].matched)
857 LOG_ERROR(
"Failed to match boundary in content-type (" << head_info.
m_content_type.size() <<
" bytes)");
#define s(x, c)
Definition aesb.c:47
do_nothing_sub_handler(i_target_handler *powner_filter)
Definition http_client_base.h:63
abstract_http_client()
Definition abstract_http_client.h:64
bool set_server(const std::string &address, boost::optional< login > user, ssl_options_t ssl_options=ssl_support_t::e_ssl_support_autodetect)
Definition abstract_http_client.cpp:134
Implements RFC 2617 digest auth. Digests from RFC 7616 can be added.
Definition http_auth.h:95
status handle_401(const http_response_info &response)
Definition http_auth.h:143
@ kSuccess
Definition http_auth.h:97
@ kParseFailure
Definition http_auth.h:97
@ kBadPassword
Definition http_auth.h:97
boost::optional< std::pair< std::string, std::string > > get_auth_field(const boost::string_ref method, const boost::string_ref uri)
Definition http_auth.h:157
Definition http_client.h:108
void set_connector(F connector)
Definition http_client.h:186
critical_section m_lock
Definition http_client.h:144
void set_auto_connect(bool auto_connect) override
Definition http_client.h:180
bool analize_cached_header_and_invoke_state()
Definition http_client.h:758
bool set_reply_content_encoder()
Definition http_client.h:740
blocked_mode_client m_net_client
Definition http_client.h:130
boost::shared_ptr< i_sub_handler > m_pcontent_encoding_handler
Definition http_client.h:139
http_simple_client_template()
Definition http_client.h:147
bool shutdown() override
Definition http_client.h:204
bool is_multipart_body(const http_header_info &head_info, OUT std::string &boundary)
Definition http_client.h:842
std::string m_chunked_cache
Definition http_client.h:142
bool m_auto_connect
Definition http_client.h:143
virtual bool handle_target_data(std::string &piece_of_transfer) override
Definition http_client.h:215
bool handle_body_connection_close(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:470
bool is_connected(bool *ssl=NULL) override
Definition http_client.h:209
bool test(const std::string &s, std::chrono::milliseconds timeout)
Definition http_client.h:314
size_t m_len_in_summary
Definition http_client.h:136
bool connect(std::chrono::milliseconds timeout) override
Definition http_client.h:192
chunked_state m_chunked_state
Definition http_client.h:141
std::string m_header_cache
Definition http_client.h:134
bool parse_header(http_header_info &body_info, const std::string &m_cache_to_process)
Definition http_client.h:655
bool handle_body_content_len(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:444
void wipe_response()
Definition http_client.h:332
bool get_len_from_chunk_head(const std::string &chunk_head, size_t &result_size)
Definition http_client.h:495
chunked_state
Definition http_client.h:122
@ http_chunked_state_done
Definition http_client.h:125
@ http_chunked_state_chunk_head
Definition http_client.h:123
@ http_chunked_state_undefined
Definition http_client.h:126
@ http_chunked_state_chunk_body
Definition http_client.h:124
bool invoke_get(const boost::string_ref uri, std::chrono::milliseconds timeout, const std::string &body=std::string(), const http_response_info **ppresponse_info=NULL, const fields_list &additional_params=fields_list()) override
Definition http_client.h:228
bool handle_body_body_chunked(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:562
void set_server(std::string host, std::string port, boost::optional< login > user, ssl_options_t ssl_options=ssl_support_t::e_ssl_support_autodetect) override
Definition http_client.h:170
bool invoke_post(const boost::string_ref uri, const std::string &body, std::chrono::milliseconds timeout, const http_response_info **ppresponse_info=NULL, const fields_list &additional_params=fields_list()) override
Definition http_client.h:308
uint64_t get_bytes_received() const override
Definition http_client.h:327
bool invoke(const boost::string_ref uri, const boost::string_ref method, const boost::string_ref body, std::chrono::milliseconds timeout, const http_response_info **ppresponse_info=NULL, const fields_list &additional_params=fields_list()) override
Definition http_client.h:235
bool handle_reciev(std::chrono::milliseconds timeout)
Definition http_client.h:339
http_response_info m_response_info
Definition http_client.h:135
size_t m_len_in_remain
Definition http_client.h:137
bool is_hex_symbol(char ch)
Definition http_client.h:485
reciev_machine_state m_state
Definition http_client.h:140
bool disconnect() override
Definition http_client.h:198
bool get_chunk_head(std::string &buff, size_t &chunk_size, bool &is_matched)
Definition http_client.h:506
reciev_machine_state
Definition http_client.h:111
@ reciev_machine_state_body_connection_close
Definition http_client.h:114
@ reciev_machine_state_error
Definition http_client.h:117
@ reciev_machine_state_body_content_len
Definition http_client.h:113
@ reciev_machine_state_header
Definition http_client.h:112
@ reciev_machine_state_body_chunked
Definition http_client.h:115
@ reciev_machine_state_done
Definition http_client.h:116
const std::string & get_host() const
Definition http_client.h:165
virtual bool on_header(const http_response_info &headers)
Definition http_client.h:223
bool is_connection_close_field(const std::string &str)
Definition http_client.h:832
http_client_auth m_auth
Definition http_client.h:133
const std::string & get_port() const
Definition http_client.h:166
bool handle_header(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:403
std::string m_port
Definition http_client.h:132
std::string m_host_buff
Definition http_client.h:131
uint64_t get_bytes_sent() const override
Definition http_client.h:322
bool analize_first_response_line()
Definition http_client.h:703
epee::critical_section gregexp_lock
bool isdigit(char c)
Definition parserse_base_utils.h:91
bool isspace(char c)
Definition parserse_base_utils.h:86
bool parse_header_line(boost::string_view line, boost::string_view &name, boost::string_view &value)
Definition http_base.h:85
http_simple_client_template< blocked_mode_client > http_simple_client
Definition http_client.h:868
std::list< std::pair< std::string, std::string > > fields_list
Definition http_base.h:67
@ e_ssl_support_autodetect
Definition net_ssl.h:53
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
#define STATIC_REGEXP_EXPR_1(var_name, xpr_text, reg_exp_flags)
Definition reg_exp_definer.h:48
#define F(w, k)
Definition sha512-blocks.c:61
tools::wallet2::message_signature_result_t result
Definition signature.cpp:62
unsigned __int64 uint64_t
Definition stdint.h:136
Definition http_base.h:200
int m_http_ver_lo
Definition http_base.h:208
void clear()
Definition http_base.h:210
int m_http_ver_hi
Definition http_base.h:207
void wipe()
Definition http_base.h:216
int m_response_code
Definition http_base.h:201
http_header_info m_header_info
Definition http_base.h:206
std::string m_body
Definition http_base.h:204
Definition http_client_base.h:54
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153