Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
http_server_handlers_map2.h
Go to the documentation of this file.
1
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
// * Redistributions of source code must retain the above copyright
7
// notice, this list of conditions and the following disclaimer.
8
// * Redistributions in binary form must reproduce the above copyright
9
// notice, this list of conditions and the following disclaimer in the
10
// documentation and/or other materials provided with the distribution.
11
// * Neither the name of the Andrey N. Sabelnikov nor the
12
// names of its contributors may be used to endorse or promote products
13
// derived from this software without specific prior written permission.
14
//
15
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
//
26
27
28
#pragma once
29
#include "
http_base.h
"
30
#include "
jsonrpc_structs.h
"
31
#include "
storages/portable_storage.h
"
32
#include "
storages/portable_storage_template_helper.h
"
33
34
#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
35
#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "net.http"
36
37
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) \
41
{\
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";} \
47
return true; \
48
}
49
50
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"
56
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);
58
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
60
61
#define MAP_URI_AUTO_JON2_IF(s_pattern, callback_f, command_type, cond) \
62
else if((query_info.m_URI == s_pattern) && (cond)) \
63
{ \
64
handled = true; \
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)) \
73
{ \
74
LOG_ERROR("Failed to " << #callback_f << "()"); \
75
response_info.m_response_code = 500; \
76
response_info.m_response_comment = "Internal Server Error"; \
77
return true; \
78
} \
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"); \
85
}
86
87
#define MAP_URI_AUTO_JON2(s_pattern, callback_f, command_type) MAP_URI_AUTO_JON2_IF(s_pattern, callback_f, command_type, true)
88
89
#define MAP_URI_AUTO_BIN2(s_pattern, callback_f, command_type) \
90
else if(query_info.m_URI == s_pattern) \
91
{ \
92
handled = true; \
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)) \
101
{ \
102
LOG_ERROR("Failed to " << #callback_f << "()"); \
103
response_info.m_response_code = 500; \
104
response_info.m_response_comment = "Internal Server Error"; \
105
return true; \
106
} \
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"); \
113
}
114
115
#define CHAIN_URI_MAP2(callback) else {callback(query_info, response_info, m_conn_context);handled = true;}
116
117
#define END_URI_MAP2() return handled;}
118
119
120
#define BEGIN_JSON_RPC_MAP(uri) else if(query_info.m_URI == uri) \
121
{ \
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)) \
125
{ \
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); \
131
return true; \
132
} \
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)) \
138
{ \
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); \
144
return true; \
145
} \
146
if(false) return true;
//just a stub to have "else if"
147
148
149
#define PREPARE_OBJECTS_FROM_JSON(command_type) \
150
handled = true; \
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_);\
153
if(!req.load(ps)) \
154
{ \
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); \
161
return true; \
162
} \
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"; \
167
resp.id = req.id;
168
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");
176
177
#define MAP_JON_RPC_WE_IF(method_name, callback_f, command_type, cond) \
178
else if((callback_name == method_name) && (cond)) \
179
{ \
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)) \
186
{ \
187
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
188
return true; \
189
} \
190
FINALIZE_OBJECTS_TO_JSON(method_name) \
191
return true;\
192
}
193
194
#define MAP_JON_RPC_WE(method_name, callback_f, command_type) MAP_JON_RPC_WE_IF(method_name, callback_f, command_type, true)
195
196
#define MAP_JON_RPC_WERI(method_name, callback_f, command_type) \
197
else if(callback_name == method_name) \
198
{ \
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)) \
205
{ \
206
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
207
return true; \
208
} \
209
FINALIZE_OBJECTS_TO_JSON(method_name) \
210
return true;\
211
}
212
213
#define MAP_JON_RPC(method_name, callback_f, command_type) \
214
else if(callback_name == method_name) \
215
{ \
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)) \
219
{ \
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); \
226
return true; \
227
} \
228
FINALIZE_OBJECTS_TO_JSON(method_name) \
229
return true;\
230
}
231
232
#define END_JSON_RPC_MAP() \
233
epee::json_rpc::error_response rsp; \
234
rsp.id = id_; \
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); \
239
return true; \
240
}
241
242
http_base.h
jsonrpc_structs.h
portable_storage.h
portable_storage_template_helper.h
contrib
epee
include
net
http_server_handlers_map2.h
Generated on
for Electroneum by
1.17.0