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
214 piece_of_transfer.clear();
226 return invoke(
uri,
"GET", body, timeout, ppresponse_info, additional_params);
230 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
237 MWARNING(
"Auto connect attempt to " <<
m_host_buff <<
":" <<
m_port <<
" disabled");
240 MDEBUG(
"Reconnecting...");
248 std::string req_buff{};
249 req_buff.reserve(2048);
250 req_buff.append(method.data(), method.size()).append(
" ").append(
uri.data(),
uri.size()).append(
" HTTP/1.1\r\n");
252 add_field(req_buff,
"Content-Length", std::to_string(body.size()));
255 for(
const auto& field : additional_params)
258 for (
unsigned sends = 0; sends < 2; ++sends)
260 const std::size_t initial_size = req_buff.size();
261 const auto auth =
m_auth.get_auth_field(method,
uri);
269 CHECK_AND_ASSERT_MES(
res,
false,
"HTTP_CLIENT: Failed to SEND");
272 CHECK_AND_ASSERT_MES(
res,
false,
"HTTP_CLIENT: Failed to SEND");
294 LOG_ERROR(
"Bad server response for authentication");
297 req_buff.resize(initial_size);
299 LOG_ERROR(
"Client has incorrect username/password for server requiring authentication");
306 return invoke(
uri,
"POST", body, timeout, ppresponse_info, additional_params);
309 bool test(
const std::string &
s, std::chrono::milliseconds timeout)
337 bool keep_handling =
true;
338 bool need_more_data =
true;
339 std::string recv_buffer;
346 MERROR(
"Unexpected recv fail");
349 if(!recv_buffer.size())
357 need_more_data =
false;
374 keep_handling =
false;
377 keep_handling =
false;
392 LOG_PRINT_L3(
"Returning false because of wrong state machine. state: " <<
m_state);
402 if(!recv_buff.size())
404 LOG_ERROR(
"Connection closed at handle_header");
412 if(pos != std::string::npos)
424 MDEBUG(
"Connection cancelled by on_header");
430 need_more_data =
true;
434 need_more_data =
true;
442 if(!recv_buff.size())
444 MERROR(
"Warning: Content-Len mode, but connection unexpectedly closed");
448 CHECK_AND_ASSERT_MES(
m_len_in_remain >= recv_buff.size(),
false,
"m_len_in_remain >= recv_buff.size()");
459 need_more_data =
true;
468 if(!recv_buff.size())
473 need_more_data =
true;
483 if( (ch >=
'0' && ch <=
'9')||(ch >=
'A' && ch <=
'F')||(ch >=
'a' && ch <=
'f'))
492 std::stringstream str_stream;
493 str_stream << std::hex;
494 if(!(str_stream << chunk_head && str_stream >> result_size))
505 for(std::string::iterator it = buff.begin(); it!= buff.end(); it++, offset++)
509 if(*it ==
'\r' || *it ==
' ' )
516 std::string chunk_head = buff.substr(0, offset);
526 for(it++;it != buff.end(); it++)
534 LOG_ERROR(
"http_stream_filter: Wrong last chunk terminator");
543 buff.erase(buff.begin(), ++it);
560 if(!recv_buff.size())
562 MERROR(
"Warning: CHUNKED mode, but connection unexpectedly closed");
568 bool is_matched =
false;
574 need_more_data =
true;
592 LOG_ERROR(
"http_stream_filter::handle_chunked(*) Failed to get length from chunked head:" <<
m_chunked_cache);
599 need_more_data =
true;
615 std::string chunk_body;
642 LOG_ERROR(
"http_stream_filter::handle_chunked(): Wrong state" <<
m_chunked_state);
652 MTRACE(
"http_stream_filter::parse_cached_header(*)");
655 while(cur < m_cache_to_process.size())
657 const size_t line_end = m_cache_to_process.find(
'\n', cur);
658 CHECK_AND_ASSERT_MES(line_end != std::string::npos,
false,
"http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process);
660 boost::string_view line(m_cache_to_process.data() + cur, line_end - cur);
663 if(line ==
"\r" || line.empty())
666 boost::string_view name;
667 boost::string_view
value;
668 CHECK_AND_ASSERT_MES(
detail::parse_header_line(line, name,
value),
false,
"http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process);
670 std::string
key(name.data(), name.size());
685 body_info.
m_host = std::move(val);
687 body_info.
m_cookie = std::move(val);
691 body_info.
m_origin = std::move(val);
702 CHECK_AND_ASSERT_MES(!memcmp(ptr,
"HTTP/", 5),
false,
"Invalid first response line: " +
m_header_cache);
707 ul = strtoul(ptr, &end, 10);
708 CHECK_AND_ASSERT_MES(ul <= INT_MAX && *end ==
'.',
false,
"Invalid first response line: " +
m_header_cache);
712 ul = strtoul(ptr, &end, 10);
713 CHECK_AND_ASSERT_MES(ul <= INT_MAX && isblank(*end),
false,
"Invalid first response line: " +
m_header_cache +
", ptr: " << ptr);
716 while (isblank(*ptr))
719 ul = strtoul(ptr, &end, 10);
720 CHECK_AND_ASSERT_MES(ul >= 100 && ul <= 999 &&
isspace(*end),
false,
"Invalid first response line: " +
m_header_cache);
724 while (*ptr !=
'\r' && *ptr !=
'\n')
728 CHECK_AND_ASSERT_MES(*ptr ==
'\n',
false,
"Invalid first response line: " <<
m_header_cache);
737 STATIC_REGEXP_EXPR_1(rexp_match_gzip,
"^.*?((gzip)|(deflate))", boost::regex::icase | boost::regex::normal);
739 if(boost::regex_search(
m_response_info.m_header_info.m_content_encoding,
result, rexp_match_gzip, boost::match_default) &&
result[0].matched)
742 LOG_ERROR(
"GZIP encoding not supported");
757 std::string fake_str;
760 CHECK_AND_ASSERT_MES(
res,
false,
"http_stream_filter::analize_cached_reply_header_and_invoke_state(): failed to anilize reply header: " <<
m_header_cache);
765 bool content_len_valid =
false;
782 LOG_ERROR(
"Wrong Transfer-Encoding:" <<
m_response_info.m_header_info.m_transfer_encoding);
793 if(!content_len_valid)
795 LOG_ERROR(
"http_stream_filter::analize_cached_reply_header_and_invoke_state(): Failed to get_len_from_content_lenght();, m_query_info.m_content_length="<<
m_response_info.m_header_info.m_content_length);
816 LOG_ERROR(
"Unsupported MULTIPART BODY.");
821 MERROR(
"Undefined transfer type, consider http_body_transfer_connection_close method. header: " <<
m_header_cache);
829 STATIC_REGEXP_EXPR_1(rexp_match_close,
"^\\s*close", boost::regex::icase | boost::regex::normal);
831 if(boost::regex_search( str,
result, rexp_match_close, boost::match_default) &&
result[0].matched)
840 STATIC_REGEXP_EXPR_1(rexp_match_multipart_type,
"^\\s*multipart/([\\w\\-]+); boundary=((\"(.*?)\")|(\\\\\"(.*?)\\\\\")|([^\\s;]*))", boost::regex::icase | boost::regex::normal);
842 if(boost::regex_search(head_info.
m_content_type,
result, rexp_match_multipart_type, boost::match_default) &&
result[0].matched)
846 else if(
result[6].matched)
848 else if(
result[7].matched)
852 LOG_ERROR(
"Failed to match boundary in content-type=" << head_info.
m_content_type);
#define s(x, c)
Definition aesb.c:47
Definition http_client_base.h:61
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
@ kSuccess
Definition http_auth.h:97
@ kParseFailure
Definition http_auth.h:97
@ kBadPassword
Definition http_auth.h:97
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:753
bool set_reply_content_encoder()
Definition http_client.h:735
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 is_multipart_body(const http_header_info &head_info, OUT std::string &boundary)
Definition http_client.h:837
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:210
bool handle_body_connection_close(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:465
bool is_connected(bool *ssl=NULL) override
Definition http_client.h:204
bool test(const std::string &s, std::chrono::milliseconds timeout)
Definition http_client.h:309
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:650
bool handle_body_content_len(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:439
void wipe_response()
Definition http_client.h:327
bool get_len_from_chunk_head(const std::string &chunk_head, size_t &result_size)
Definition http_client.h:490
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:223
bool handle_body_body_chunked(std::string &recv_buff, bool &need_more_data)
Definition http_client.h:557
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:303
uint64_t get_bytes_received() const override
Definition http_client.h:322
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:230
bool handle_reciev(std::chrono::milliseconds timeout)
Definition http_client.h:334
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:480
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:501
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:218
bool is_connection_close_field(const std::string &str)
Definition http_client.h:827
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:398
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:317
bool analize_first_response_line()
Definition http_client.h:698
const char * res
Definition hmac_keccak.cpp:42
const char * key
Definition hmac_keccak.cpp:40
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
static void add_field(std::string &out, boost::string_view name, boost::string_view value)
Definition http_base.h:73
http_simple_client_template< blocked_mode_client > http_simple_client
Definition http_client.h:863
std::list< std::pair< std::string, std::string > > fields_list
Definition http_base.h:67
@ e_ssl_support_autodetect
Definition net_ssl.h:52
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
Definition http_client_base.h:54
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153