28#include <boost/algorithm/string/predicate.hpp>
29#include <boost/lexical_cast.hpp>
30#include <boost/regex.hpp>
38#undef MONERO_DEFAULT_LOG_CATEGORY
39#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
41#define HTTP_MAX_URI_LEN 9000
42#define HTTP_MAX_HEADER_LEN 100000
43#define HTTP_MAX_STARTING_NEWLINES 8
63 STATIC_REGEXP_EXPR_1(rexp_match_boundary,
"boundary=(.*?)(($)|([;\\s,]))", boost::regex::icase | boost::regex::normal);
66 if(boost::regex_search(content_type,
result, rexp_match_boundary, boost::match_default) &&
result[0].matched)
79 "\n?((Content-Disposition)|(Content-Type)"
81 "|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
83 boost::regex::icase | boost::regex::normal);
86 std::string::const_iterator it_current_bound = it_begin;
87 std::string::const_iterator it_end_bound = it_end;
90 while( boost::regex_search( it_current_bound, it_end_bound,
result, rexp_mach_field, boost::match_default) &&
result[0].matched)
92 const size_t field_val = 6;
93 const size_t field_etc_name = 4;
98 else if(
result[i++].matched)
100 else if(
result[i++].matched)
104 LOG_ERROR(
"simple_http_connection_handler::parse_header() not matched last entry in:"<<std::string(it_current_bound, it_end));
115 std::string end_str =
"\r\n\r\n";
116 std::string::const_iterator end_header_it = std::search(it_begin, it_end, end_str.begin(), end_str.end());
117 if(end_header_it == it_end)
125 LOG_ERROR(
"Failed to parse header:" << std::string(it_begin, end_header_it+2));
129 entry.
m_body.assign(end_header_it+4, it_end);
135 bool parse_multipart_body(
const std::string& content_type,
const std::string& body, std::list<multipart_entry>& out_values)
139 std::string boundary;
142 MERROR(
"Failed to match boundary in content type: " << content_type);
147 bool is_stop =
false;
148 bool first_step =
true;
150 std::string::const_iterator it_begin = body.begin();
151 std::string::const_iterator it_end;
154 std::string::size_type pos = body.find(boundary, std::distance(body.begin(), it_begin));
156 if(std::string::npos == pos)
159 boundary.erase(boundary.size()-2, 2);
161 pos = body.find(boundary, std::distance(body.begin(), it_begin));
162 if(std::string::npos == pos)
164 MERROR(
"Error: Filed to match closing multipart tag");
168 it_end = body.begin() + pos;
171 it_end = body.begin() + pos;
174 if(first_step && !is_stop)
177 it_begin = it_end + boundary.size();
178 std::string temp =
"\r\n--";
179 boundary = temp + boundary;
186 MERROR(
"Failed to handle_part_of_multipart");
190 it_begin = it_end + boundary.size();
200 template<
class t_connection_context>
218 template<
class t_connection_context>
229 if (elem !=
m_config.m_connections.end())
231 if (elem->second == 1 || elem->second == 0)
242 template<
class t_connection_context>
252 template<
class t_connection_context>
265 template<
class t_connection_context>
268 std::string
buf((
const char*)ptr, cb);
278 template<
class t_connection_context>
287 LOG_ERROR(
"simple_http_connection_handler::handle_buff_in: Too much data: got " <<
m_bytes_read);
309 ndel =
m_cache.find_first_not_of(
"\r\n");
317 LOG_ERROR(
"simple_http_connection_handler::handle_buff_out: Too many starting newlines");
325 if(std::string::npos !=
m_cache.find(
'\n', 0))
341 if(std::string::npos == pos)
377 CHECK_AND_ASSERT_MES(
result[0].matched,
false,
"simple_http_connection_handler::analize_http_method() assert failed...");
378 if (!boost::conversion::try_lexical_convert<int>(
result[11], http_ver_major))
380 if (!boost::conversion::try_lexical_convert<int>(
result[12], http_ver_minor))
385 else if(
result[4].matched)
387 else if(
result[5].matched)
389 else if(
result[6].matched)
391 else if(
result[7].matched)
400 template<
class t_connection_context>
403 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);
407 if(boost::regex_search(
m_cache,
result, rexp_match_command_line, boost::match_default) &&
result[0].matched)
412 MERROR(
"Failed to analyze method");
419 MERROR(
"Failed to parse URI: m_query_info.m_URI");
440 template<
class t_connection_context>
445 std::string::size_type
res =
buf.find(
"\r\n\r\n");
446 if(std::string::npos !=
res)
449 if(std::string::npos !=
res)
454 template<
class t_connection_context>
457 LOG_PRINT_L3(
"HTTP HEAD:\r\n" <<
m_cache.substr(0, pos));
464 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);
471 std::string req_command_str =
m_query_info.m_full_request_str;
480 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);
501 template<
class t_connection_context>
521 template<
class t_connection_context>
547 template<
class t_connection_context>
558 const size_t line_end = m_cache_to_process.find(
'\n', cur);
559 if(line_end == std::string::npos || line_end >= pos)
562 boost::string_view line(m_cache_to_process.data() + cur, line_end - cur);
566 if(line ==
"\r" || line.empty())
569 boost::string_view name;
570 boost::string_view
value;
574 if(boost::iequals(name,
"Connection"))
576 else if(boost::iequals(name,
"Referer"))
578 else if(boost::iequals(name,
"Content-Length"))
580 else if(boost::iequals(name,
"Content-Type"))
582 else if(boost::iequals(name,
"Transfer-Encoding"))
584 else if(boost::iequals(name,
"Content-Encoding"))
586 else if(boost::iequals(name,
"Host"))
588 else if(boost::iequals(name,
"Cookie"))
590 else if(boost::iequals(name,
"User-Agent"))
592 else if(boost::iequals(name,
"Origin"))
595 body_info.
m_etc_fields.push_back(std::make_pair(std::string(name.data(), name.size()), std::string(
value.data(),
value.size())));
600 template<
class t_connection_context>
606 if(!(boost::regex_search( str,
result, rexp_mach_field, boost::match_default) &&
result[0].matched))
609 try { len = boost::lexical_cast<size_t>(
result[0]); }
610 catch(...) {
return false; }
614 template<
class t_connection_context>
638 LOG_PRINT_L3(
"HTTP_RESPONSE_HEAD: << \r\n" << response_data);
641 response_data += response.
m_body;
648 template<
class t_connection_context>
653 if(
"/" == uri_to_path)
654 uri_to_path =
"/index.html";
658 std::string destination_file_path =
m_config.m_folder + uri_to_path;
678 template<
class t_connection_context>
681 std::string
buf =
"HTTP/1.1 ";
683 "Server: Epee-based\r\n"
685 buf += boost::lexical_cast<std::string>(response.
m_body.size()) +
"\r\n";
689 buf +=
"Content-Type: ";
693 buf +=
"Last-Modified: ";
697 buf +=
"Accept-Ranges: bytes\r\n";
706 buf +=
"Connection: close\r\n";
715 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))
717 buf +=
"Access-Control-Allow-Origin: ";
720 buf +=
"Access-Control-Expose-Headers: www-authenticate\r\n";
722 buf +=
"Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With\r\n";
723 buf +=
"Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS\r\n";
729 buf += it->first +
": " + it->second +
"\r\n";
736 template<
class t_connection_context>
750 result =
"application/x-javascript";
754 result =
"application/xml";
762 template<
class t_connection_context>
766 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
768 "<title>404 Not Found</title>\r\n"
770 "<h1>Not Found</h1>\r\n"
771 "<p>The requested URL \r\n";
773 body +=
"was not found on this server.</p>\r\n"
774 "</body></html>\r\n";
779 template<
class t_connection_context>
782 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:601
bool parse_cached_header(http_header_info &body_info, const std::string &m_cache_to_process, size_t pos)
Definition http_protocol_handler.inl:548
@ 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:243
virtual ~simple_http_connection_handler()
Definition http_protocol_handler.inl:219
std::string m_cache
Definition http_protocol_handler.h:139
bool handle_retriving_query_body()
Definition http_protocol_handler.inl:502
bool slash_to_back_slash(std::string &str)
Definition http_protocol_handler.inl:780
@ 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:737
bool handle_invoke_query_line()
Definition http_protocol_handler.inl:401
bool handle_buff_in(std::string &buf)
Definition http_protocol_handler.inl:279
bool handle_query_measure()
Definition http_protocol_handler.inl:522
body_transfer_type m_body_transfer_type
Definition http_protocol_handler.h:141
bool set_ready_state()
Definition http_protocol_handler.inl:253
bool handle_request_and_send_response(const http::http_request_info &query_info)
Definition http_protocol_handler.inl:615
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:455
std::string get_response_header(const http_response_info &response)
Definition http_protocol_handler.inl:679
std::string::size_type match_end_of_header(const std::string &buf)
Definition http_protocol_handler.inl:441
virtual bool handle_request(const http::http_request_info &query_info, http_response_info &response)
Definition http_protocol_handler.inl:649
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:266
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:763
simple_http_connection_handler(i_service_endpoint *psnd_hndlr, config_type &config, t_connection_context &conn_context)
Definition http_protocol_handler.inl:201
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:43
#define HTTP_MAX_URI_LEN
Definition http_protocol_handler.inl:41
#define HTTP_MAX_HEADER_LEN
Definition http_protocol_handler.inl:42
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
bool parse_header_line(boost::string_view line, boost::string_view &name, boost::string_view &value)
Definition http_base.h:85
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:61
bool parse_header(std::string::const_iterator it_begin, std::string::const_iterator it_end, multipart_entry &entry)
Definition http_protocol_handler.inl:76
bool parse_multipart_body(const std::string &content_type, const std::string &body, std::list< multipart_entry > &out_values)
Definition http_protocol_handler.inl:135
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:375
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:113
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 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
tools::wallet2::message_signature_result_t result
Definition signature.cpp:62
const char * buf
Definition slow_memmem.cpp:73
Definition http_base.h:169
std::string m_full_request_str
Definition http_base.h:180
uri_content m_uri_content
Definition http_base.h:187
http_method m_http_method
Definition http_base.h:177
std::string m_URI
Definition http_base.h:178
Definition http_base.h:200
std::string m_response_comment
Definition http_base.h:202
std::string m_mime_tipe
Definition http_base.h:205
int m_response_code
Definition http_base.h:201
std::string m_body
Definition http_base.h:204
fields_list m_additional_fields
Definition http_base.h:203
Definition http_protocol_handler.inl:53
std::string m_body
Definition http_protocol_handler.inl:57
std::list< std::pair< std::string, std::string > > m_etc_header_fields
Definition http_protocol_handler.inl:54
std::string m_content_type
Definition http_protocol_handler.inl:56
std::string m_content_disposition
Definition http_protocol_handler.inl:55
std::string m_path
Definition http_base.h:152
Definition net_utils_base.h:442
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153