Go to the documentation of this file. 34 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 35 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "net.http" 38 #define CHAIN_HTTP_TO_MAP2(context_type) bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, \ 39 epee::net_utils::http::http_response_info& response, \ 40 context_type& m_conn_context) \ 42 MINFO("HTTP [" << m_conn_context.m_remote_address.host_str() << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \ 43 response.m_response_code = 200; \ 44 response.m_response_comment = "Ok"; \ 45 if(!handle_http_request_map(query_info, response, m_conn_context)) \ 46 {response.m_response_code = 404;response.m_response_comment = "Not found";} \ 51 #define BEGIN_URI_MAP2() template<class t_context> bool handle_http_request_map(const epee::net_utils::http::http_request_info& query_info, \ 52 epee::net_utils::http::http_response_info& response_info, \ 53 t_context& m_conn_context) { \ 54 bool handled = false; \ 55 if(false) return true; //just a stub to have "else if" 57 #define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, &m_conn_context); 59 #define MAP_URI_AUTO_XML2(s_pattern, callback_f, command_type) //TODO: don't think i ever again will use xml - ambiguous and "overtagged" format 61 #define MAP_URI_AUTO_JON2_IF(s_pattern, callback_f, command_type, cond) \ 62 else if((query_info.m_URI == s_pattern) && (cond)) \ 65 uint64_t ticks = misc_utils::get_tick_count(); \ 66 boost::value_initialized<command_type::request> req; \ 67 bool parse_res = epee::serialization::load_t_from_json(static_cast<command_type::request&>(req), query_info.m_body); \ 68 CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse json: \r\n" << query_info.m_body); \ 69 uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ 70 boost::value_initialized<command_type::response> resp;\ 71 MINFO(m_conn_context << "calling " << s_pattern); \ 72 if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ 74 LOG_ERROR("Failed to " << #callback_f << "()"); \ 75 response_info.m_response_code = 500; \ 76 response_info.m_response_comment = "Internal Server Error"; \ 79 uint64_t ticks2 = epee::misc_utils::get_tick_count(); \ 80 epee::serialization::store_t_to_json(static_cast<command_type::response&>(resp), response_info.m_body); \ 81 uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ 82 response_info.m_mime_tipe = "application/json"; \ 83 response_info.m_header_info.m_content_type = " application/json"; \ 84 MDEBUG( s_pattern << " processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); \ 87 #define MAP_URI_AUTO_JON2(s_pattern, callback_f, command_type) MAP_URI_AUTO_JON2_IF(s_pattern, callback_f, command_type, true) 89 #define MAP_URI_AUTO_BIN2(s_pattern, callback_f, command_type) \ 90 else if(query_info.m_URI == s_pattern) \ 93 uint64_t ticks = misc_utils::get_tick_count(); \ 94 boost::value_initialized<command_type::request> req; \ 95 bool parse_res = epee::serialization::load_t_from_binary(static_cast<command_type::request&>(req), epee::strspan<uint8_t>(query_info.m_body)); \ 96 CHECK_AND_ASSERT_MES(parse_res, false, "Failed to parse bin body data, body size=" << query_info.m_body.size()); \ 97 uint64_t ticks1 = misc_utils::get_tick_count(); \ 98 boost::value_initialized<command_type::response> resp;\ 99 MINFO(m_conn_context << "calling " << s_pattern); \ 100 if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ 102 LOG_ERROR("Failed to " << #callback_f << "()"); \ 103 response_info.m_response_code = 500; \ 104 response_info.m_response_comment = "Internal Server Error"; \ 107 uint64_t ticks2 = misc_utils::get_tick_count(); \ 108 epee::serialization::store_t_to_binary(static_cast<command_type::response&>(resp), response_info.m_body); \ 109 uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ 110 response_info.m_mime_tipe = " application/octet-stream"; \ 111 response_info.m_header_info.m_content_type = " application/octet-stream"; \ 112 MDEBUG( s_pattern << "() processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); \ 115 #define CHAIN_URI_MAP2(callback) else {callback(query_info, response_info, m_conn_context);handled = true;} 117 #define END_URI_MAP2() return handled;} 120 #define BEGIN_JSON_RPC_MAP(uri) else if(query_info.m_URI == uri) \ 122 uint64_t ticks = epee::misc_utils::get_tick_count(); \ 123 epee::serialization::portable_storage ps; \ 124 if(!ps.load_from_json(query_info.m_body)) \ 126 boost::value_initialized<epee::json_rpc::error_response> rsp; \ 127 static_cast<epee::json_rpc::error_response&>(rsp).jsonrpc = "2.0"; \ 128 static_cast<epee::json_rpc::error_response&>(rsp).error.code = -32700; \ 129 static_cast<epee::json_rpc::error_response&>(rsp).error.message = "Parse error"; \ 130 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \ 133 epee::serialization::storage_entry id_; \ 134 id_ = epee::serialization::storage_entry(std::string()); \ 135 ps.get_value("id", id_, nullptr); \ 136 std::string callback_name; \ 137 if(!ps.get_value("method", callback_name, nullptr)) \ 139 epee::json_rpc::error_response rsp; \ 140 rsp.jsonrpc = "2.0"; \ 141 rsp.error.code = -32600; \ 142 rsp.error.message = "Invalid Request"; \ 143 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \ 146 if(false) return true; //just a stub to have "else if" 149 #define PREPARE_OBJECTS_FROM_JSON(command_type) \ 151 boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \ 152 epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\ 155 epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ 156 fail_resp.jsonrpc = "2.0"; \ 157 fail_resp.id = req.id; \ 158 fail_resp.error.code = -32602; \ 159 fail_resp.error.message = "Invalid params"; \ 160 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ 163 uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ 164 boost::value_initialized<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> > resp_; \ 165 epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error>& resp = static_cast<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> &>(resp_); \ 166 resp.jsonrpc = "2.0"; \ 169 #define FINALIZE_OBJECTS_TO_JSON(method_name) \ 170 uint64_t ticks2 = epee::misc_utils::get_tick_count(); \ 171 epee::serialization::store_t_to_json(resp, response_info.m_body); \ 172 uint64_t ticks3 = epee::misc_utils::get_tick_count(); \ 173 response_info.m_mime_tipe = "application/json"; \ 174 response_info.m_header_info.m_content_type = " application/json"; \ 175 MDEBUG( query_info.m_URI << "[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms"); 177 #define MAP_JON_RPC_WE_IF(method_name, callback_f, command_type, cond) \ 178 else if((callback_name == method_name) && (cond)) \ 180 PREPARE_OBJECTS_FROM_JSON(command_type) \ 181 epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ 182 fail_resp.jsonrpc = "2.0"; \ 183 fail_resp.id = req.id; \ 184 MINFO(m_conn_context << "Calling RPC method " << method_name); \ 185 if(!callback_f(req.params, resp.result, fail_resp.error, &m_conn_context)) \ 187 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ 190 FINALIZE_OBJECTS_TO_JSON(method_name) \ 194 #define MAP_JON_RPC_WE(method_name, callback_f, command_type) MAP_JON_RPC_WE_IF(method_name, callback_f, command_type, true) 196 #define MAP_JON_RPC_WERI(method_name, callback_f, command_type) \ 197 else if(callback_name == method_name) \ 199 PREPARE_OBJECTS_FROM_JSON(command_type) \ 200 epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ 201 fail_resp.jsonrpc = "2.0"; \ 202 fail_resp.id = req.id; \ 203 MINFO(m_conn_context << "calling RPC method " << method_name); \ 204 if(!callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context)) \ 206 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ 209 FINALIZE_OBJECTS_TO_JSON(method_name) \ 213 #define MAP_JON_RPC(method_name, callback_f, command_type) \ 214 else if(callback_name == method_name) \ 216 PREPARE_OBJECTS_FROM_JSON(command_type) \ 217 MINFO(m_conn_context << "calling RPC method " << method_name); \ 218 if(!callback_f(req.params, resp.result, &m_conn_context)) \ 220 epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ 221 fail_resp.jsonrpc = "2.0"; \ 222 fail_resp.id = req.id; \ 223 fail_resp.error.code = -32603; \ 224 fail_resp.error.message = "Internal error"; \ 225 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ 228 FINALIZE_OBJECTS_TO_JSON(method_name) \ 232 #define END_JSON_RPC_MAP() \ 233 epee::json_rpc::error_response rsp; \ 235 rsp.jsonrpc = "2.0"; \ 236 rsp.error.code = -32601; \ 237 rsp.error.message = "Method not found"; \ 238 epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \