28#include <boost/regex.hpp>
29#include <boost/lexical_cast.hpp>
37#undef MONERO_DEFAULT_LOG_CATEGORY
38#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
40#define HTTP_MAX_URI_LEN 9000
41#define HTTP_MAX_HEADER_LEN 100000
42#define HTTP_MAX_STARTING_NEWLINES 8
62 STATIC_REGEXP_EXPR_1(rexp_match_boundary,
"boundary=(.*?)(($)|([;\\s,]))", boost::regex::icase | boost::regex::normal);
65 if(boost::regex_search(content_type,
result, rexp_match_boundary, boost::match_default) &&
result[0].matched)
78 "\n?((Content-Disposition)|(Content-Type)"
80 "|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
82 boost::regex::icase | boost::regex::normal);
85 std::string::const_iterator it_current_bound = it_begin;
86 std::string::const_iterator it_end_bound = it_end;
89 while( boost::regex_search( it_current_bound, it_end_bound,
result, rexp_mach_field, boost::match_default) &&
result[0].matched)
91 const size_t field_val = 6;
92 const size_t field_etc_name = 4;
96 entry.m_content_disposition =
result[field_val];
98 entry.m_content_type =
result[field_val];
99 else if(
result[i++].matched)
100 entry.m_etc_header_fields.push_back(std::pair<std::string, std::string>(
result[field_etc_name],
result[field_val]));
103 LOG_ERROR(
"simple_http_connection_handler::parse_header() not matched last entry in:"<<std::string(it_current_bound, it_end));
114 std::string end_str =
"\r\n\r\n";
115 std::string::const_iterator end_header_it = std::search(it_begin, it_end, end_str.begin(), end_str.end());
116 if(end_header_it == it_end)
124 LOG_ERROR(
"Failed to parse header:" << std::string(it_begin, end_header_it+2));
128 entry.
m_body.assign(end_header_it+4, it_end);
134 bool parse_multipart_body(
const std::string& content_type,
const std::string& body, std::list<multipart_entry>& out_values)
138 std::string boundary;
141 MERROR(
"Failed to match boundary in content type: " << content_type);
146 bool is_stop =
false;
147 bool first_step =
true;
149 std::string::const_iterator it_begin = body.begin();
150 std::string::const_iterator it_end;
153 std::string::size_type pos = body.find(boundary, std::distance(body.begin(), it_begin));
155 if(std::string::npos == pos)
158 boundary.erase(boundary.size()-2, 2);
160 pos = body.find(boundary, std::distance(body.begin(), it_begin));
161 if(std::string::npos == pos)
163 MERROR(
"Error: Filed to match closing multipart tag");
167 it_end = body.begin() + pos;
170 it_end = body.begin() + pos;
173 if(first_step && !is_stop)
176 it_begin = it_end + boundary.size();
177 std::string temp =
"\r\n--";
178 boundary = temp + boundary;
185 MERROR(
"Failed to handle_part_of_multipart");
189 it_begin = it_end + boundary.size();
199 template<
class t_connection_context>
217 template<
class t_connection_context>
228 if (elem !=
m_config.m_connections.end())
230 if (elem->second == 1 || elem->second == 0)
241 template<
class t_connection_context>
251 template<
class t_connection_context>
264 template<
class t_connection_context>
267 std::string
buf((
const char*)ptr, cb);
277 template<
class t_connection_context>
286 LOG_ERROR(
"simple_http_connection_handler::handle_buff_in: Too much data: got " <<
m_bytes_read);
308 ndel =
m_cache.find_first_not_of(
"\r\n");
316 LOG_ERROR(
"simple_http_connection_handler::handle_buff_out: Too many starting newlines");
324 if(std::string::npos !=
m_cache.find(
'\n', 0))
340 if(std::string::npos == pos)
376 CHECK_AND_ASSERT_MES(
result[0].matched,
false,
"simple_http_connection_handler::analize_http_method() assert failed...");
377 if (!boost::conversion::try_lexical_convert<int>(
result[11], http_ver_major))
379 if (!boost::conversion::try_lexical_convert<int>(
result[12], http_ver_minor))
384 else if(
result[4].matched)
386 else if(
result[5].matched)
388 else if(
result[6].matched)
390 else if(
result[7].matched)
399 template<
class t_connection_context>
402 STATIC_REGEXP_EXPR_1(rexp_match_command_line,
"^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+)\\.(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
406 if(boost::regex_search(
m_cache,
result, rexp_match_command_line, boost::match_default) &&
result[0].matched)
411 MERROR(
"Failed to analyze method");
418 MERROR(
"Failed to parse URI: m_query_info.m_URI");
439 template<
class t_connection_context>
444 std::string::size_type
res =
buf.find(
"\r\n\r\n");
445 if(std::string::npos !=
res)
448 if(std::string::npos !=
res)
453 template<
class t_connection_context>
456 LOG_PRINT_L3(
"HTTP HEAD:\r\n" <<
m_cache.substr(0, pos));
463 LOG_ERROR_CC(
m_conn_context,
"simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): failed to anilize request header: " <<
m_cache);
470 std::string req_command_str =
m_query_info.m_full_request_str;
479 LOG_ERROR_CC(
m_conn_context,
"simple_http_connection_handler<t_connection_context>::analize_cached_request_header_and_invoke_state(): Failed to get_len_from_content_lenght();, m_query_info.m_content_length="<<
m_query_info.m_header_info.m_content_length);
500 template<
class t_connection_context>
520 template<
class t_connection_context>
546 template<
class t_connection_context>
550 "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)|(User-Agent)|(Origin)"
552 "|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
554 boost::regex::icase | boost::regex::normal);
557 std::string::const_iterator it_current_bound = m_cache_to_process.begin();
558 std::string::const_iterator it_end_bound = m_cache_to_process.begin()+pos;
563 while( boost::regex_search( it_current_bound, it_end_bound,
result, rexp_mach_field, boost::match_default) &&
result[0].matched)
565 const size_t field_val = 14;
566 const size_t field_etc_name = 12;
571 else if(
result[i++].matched)
573 else if(
result[i++].matched)
575 else if(
result[i++].matched)
577 else if(
result[i++].matched)
579 else if(
result[i++].matched)
581 else if(
result[i++].matched)
583 else if(
result[i++].matched)
585 else if(
result[i++].matched)
587 else if(
result[i++].matched)
589 else if(
result[i++].matched)
593 LOG_ERROR_CC(
m_conn_context,
"simple_http_connection_handler<t_connection_context>::parse_cached_header() not matched last entry in:" << m_cache_to_process);
601 template<
class t_connection_context>
607 if(!(boost::regex_search(
str,
result, rexp_mach_field, boost::match_default) &&
result[0].matched))
610 try { len = boost::lexical_cast<size_t>(
result[0]); }
611 catch(...) {
return false; }
615 template<
class t_connection_context>
639 LOG_PRINT_L3(
"HTTP_RESPONSE_HEAD: << \r\n" << response_data);
642 response_data += response.
m_body;
649 template<
class t_connection_context>
654 if(
"/" == uri_to_path)
655 uri_to_path =
"/index.html";
659 std::string destination_file_path =
m_config.m_folder + uri_to_path;
679 template<
class t_connection_context>
682 std::string
buf =
"HTTP/1.1 ";
684 "Server: Epee-based\r\n"
686 buf += boost::lexical_cast<std::string>(response.
m_body.size()) +
"\r\n";
690 buf +=
"Content-Type: ";
694 buf +=
"Last-Modified: ";
698 buf +=
"Accept-Ranges: bytes\r\n";
707 buf +=
"Connection: close\r\n";
716 if (std::binary_search(
m_config.m_access_control_origins.begin(),
m_config.m_access_control_origins.end(),
"*") || std::binary_search(
m_config.m_access_control_origins.begin(),
m_config.m_access_control_origins.end(),
m_query_info.m_header_info.m_origin))
718 buf +=
"Access-Control-Allow-Origin: ";
721 buf +=
"Access-Control-Expose-Headers: www-authenticate\r\n";
723 buf +=
"Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With\r\n";
724 buf +=
"Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS\r\n";
730 buf += it->first +
": " + it->second +
"\r\n";
737 template<
class t_connection_context>
751 result =
"application/x-javascript";
755 result =
"application/xml";
763 template<
class t_connection_context>
767 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
769 "<title>404 Not Found</title>\r\n"
771 "<h1>Not Found</h1>\r\n"
772 "<p>The requested URL \r\n";
774 body +=
"was not found on this server.</p>\r\n"
775 "</body></html>\r\n";
780 template<
class t_connection_context>
783 for(std::string::iterator it =
str.begin(); it!=
str.end(); it++)
Definition byte_slice.h:69
size_t m_bytes_read
Definition http_protocol_handler.h:148
config_type & m_config
Definition http_protocol_handler.h:145
bool get_len_from_content_lenght(const std::string &str, size_t &len)
Definition http_protocol_handler.inl:602
bool parse_cached_header(http_header_info &body_info, const std::string &m_cache_to_process, size_t pos)
Definition http_protocol_handler.inl:547
@ http_body_transfer_measure
Definition http_protocol_handler.h:110
@ http_body_transfer_undefined
Definition http_protocol_handler.h:114
@ http_body_transfer_connection_close
Definition http_protocol_handler.h:112
@ http_body_transfer_multipart
Definition http_protocol_handler.h:113
@ http_body_transfer_chunked
Definition http_protocol_handler.h:109
i_service_endpoint * m_psnd_hndlr
Definition http_protocol_handler.h:150
bool after_init_connection()
Definition http_protocol_handler.inl:242
virtual ~simple_http_connection_handler()
Definition http_protocol_handler.inl:218
std::string m_cache
Definition http_protocol_handler.h:139
bool handle_retriving_query_body()
Definition http_protocol_handler.inl:501
bool slash_to_back_slash(std::string &str)
Definition http_protocol_handler.inl:781
@ http_state_retriving_body
Definition http_protocol_handler.h:103
@ http_state_connection_close
Definition http_protocol_handler.h:104
@ http_state_error
Definition http_protocol_handler.h:105
@ http_state_retriving_header
Definition http_protocol_handler.h:102
@ http_state_retriving_comand_line
Definition http_protocol_handler.h:101
size_t m_newlines
Definition http_protocol_handler.h:147
http::http_request_info m_query_info
Definition http_protocol_handler.h:143
machine_state m_state
Definition http_protocol_handler.h:140
bool m_initialized
Definition http_protocol_handler.h:152
std::string get_file_mime_tipe(const std::string &path)
Definition http_protocol_handler.inl:738
bool handle_invoke_query_line()
Definition http_protocol_handler.inl:400
bool handle_buff_in(std::string &buf)
Definition http_protocol_handler.inl:278
bool handle_query_measure()
Definition http_protocol_handler.inl:521
body_transfer_type m_body_transfer_type
Definition http_protocol_handler.h:141
bool set_ready_state()
Definition http_protocol_handler.inl:252
bool handle_request_and_send_response(const http::http_request_info &query_info)
Definition http_protocol_handler.inl:616
size_t m_len_remain
Definition http_protocol_handler.h:144
t_connection_context & m_conn_context
Definition http_protocol_handler.h:151
bool analize_cached_request_header_and_invoke_state(size_t pos)
Definition http_protocol_handler.inl:454
std::string get_response_header(const http_response_info &response)
Definition http_protocol_handler.inl:680
std::string::size_type match_end_of_header(const std::string &buf)
Definition http_protocol_handler.inl:440
virtual bool handle_request(const http::http_request_info &query_info, http_response_info &response)
Definition http_protocol_handler.inl:650
bool m_is_stop_handling
Definition http_protocol_handler.h:142
virtual bool handle_recv(const void *ptr, size_t cb)
Definition http_protocol_handler.inl:265
http_server_config config_type
Definition http_protocol_handler.h:76
bool m_want_close
Definition http_protocol_handler.h:146
std::string get_not_found_response_body(const std::string &URI)
Definition http_protocol_handler.inl:764
simple_http_connection_handler(i_service_endpoint *psnd_hndlr, config_type &config, t_connection_context &conn_context)
Definition http_protocol_handler.inl:200
size_t m_len_summary
Definition http_protocol_handler.h:144
const char * res
Definition hmac_keccak.cpp:42
#define HTTP_MAX_STARTING_NEWLINES
Definition http_protocol_handler.inl:42
#define HTTP_MAX_URI_LEN
Definition http_protocol_handler.inl:40
#define HTTP_MAX_HEADER_LEN
Definition http_protocol_handler.inl:41
Definition cryptonote_config.h:221
bool load_file_to_string(const std::string &path_to_file, std::string &target_str, size_t max_size=1000000000)
Definition file_io_utils.cpp:105
std::string get_internet_time_str(const time_t &time_)
Definition time_helper.h:49
http_method
Definition http_base.h:49
@ http_method_head
Definition http_base.h:54
@ http_method_etc
Definition http_base.h:55
@ http_method_put
Definition http_base.h:53
@ http_method_get
Definition http_base.h:51
@ http_method_post
Definition http_base.h:52
@ http_method_options
Definition http_base.h:50
bool match_boundary(const std::string &content_type, std::string &boundary)
Definition http_protocol_handler.inl:60
bool parse_header(std::string::const_iterator it_begin, std::string::const_iterator it_end, multipart_entry &entry)
Definition http_protocol_handler.inl:75
bool parse_multipart_body(const std::string &content_type, const std::string &body, std::list< multipart_entry > &out_values)
Definition http_protocol_handler.inl:134
bool analize_http_method(const boost::smatch &result, http::http_method &method, int &http_ver_major, int &http_ver_minor)
Definition http_protocol_handler.inl:374
bool handle_part_of_multipart(std::string::const_iterator it_begin, std::string::const_iterator it_end, multipart_entry &entry)
Definition http_protocol_handler.inl:112
bool parse_uri(const std::string uri, http::uri_content &content)
Definition net_parse_helpers.cpp:102
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
#define LOG_ERROR_CC(ct, message)
Definition net_utils_base.h:469
const char *const str
Definition portlistingparse.c:23
#define STATIC_REGEXP_EXPR_1(var_name, xpr_text, reg_exp_flags)
Definition reg_exp_definer.h:48
tools::wallet2::message_signature_result_t result
Definition signature.cpp:62
const char * buf
Definition slow_memmem.cpp:73
Definition http_base.h:133
std::string m_full_request_str
Definition http_base.h:144
uri_content m_uri_content
Definition http_base.h:151
http_method m_http_method
Definition http_base.h:141
std::string m_URI
Definition http_base.h:142
Definition http_base.h:164
std::string m_response_comment
Definition http_base.h:166
std::string m_mime_tipe
Definition http_base.h:169
int m_response_code
Definition http_base.h:165
std::string m_body
Definition http_base.h:168
fields_list m_additional_fields
Definition http_base.h:167
Definition http_protocol_handler.inl:52
std::string m_body
Definition http_protocol_handler.inl:56
std::list< std::pair< std::string, std::string > > m_etc_header_fields
Definition http_protocol_handler.inl:53
std::string m_content_type
Definition http_protocol_handler.inl:55
std::string m_content_disposition
Definition http_protocol_handler.inl:54
std::string m_path
Definition http_base.h:116
Definition net_utils_base.h:442
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153