diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 83e9e6dee..dcf56da4c 100755 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -173,3 +173,7 @@ ELSE() MESSAGE(FATAL_ERROR "${BoldRed}Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent${ColourReset}") ENDIF() ENDIF() + +set(NET_SKELETON_SRCS net_skeleton/net_skeleton.c) +add_library(net_skeleton ${NET_SKELETON_SRCS}) + diff --git a/external/net_skeleton b/external/net_skeleton new file mode 160000 index 000000000..f7b138a4c --- /dev/null +++ b/external/net_skeleton @@ -0,0 +1 @@ +Subproject commit f7b138a4ce9299651fa30b5fdfeb68811317d3c0 diff --git a/src/rpc/json_rpc_http_server.cpp b/src/rpc/json_rpc_http_server.cpp new file mode 100644 index 000000000..d66eed830 --- /dev/null +++ b/src/rpc/json_rpc_http_server.cpp @@ -0,0 +1,75 @@ +#include "json_rpc_http_server.h" + +#include + +namespace RPC +{ + Json_rpc_http_server::Json_rpc_http_server(const std::string &ip, const std::string &port) + { + m_ip = ip; + m_port = port; + m_is_running = false; + m_method_count = 0; + } + + Json_rpc_http_server::~Json_rpc_http_server() + { + stop(); + } + + void Json_rpc_http_server::start() + { + m_is_running = true; + server_thread = new boost::thread(&Json_rpc_http_server::poll, this); + } + + void Json_rpc_http_server::poll() + { + ns_mgr_init(&mgr, NULL); + nc = ns_bind(&mgr, (m_ip + ":" + m_port).c_str(), std::bind(&Json_rpc_http_server::ev_handler, this)); + ns_set_protocol_http_websocket(nc); + while (m_is_running) { + ns_mgr_poll(&mgr, 1000); + } + } + + void Json_rpc_http_server::stop() + { + m_is_running = false; + server_thread->join(); + delete server_thread; + ns_mgr_free(&mgr); + } + + void Json_rpc_http_server::ev_handler(struct ns_connection *nc, int ev, void *ev_data) + { + struct http_message *hm = (struct http_message *) ev_data; + char buf[100]; + switch (ev) { + case NS_HTTP_REQUEST: + ns_rpc_dispatch(hm->body.p, hm->body.len, buf, sizeof(buf), + m_method_names, m_handlers); + ns_printf(nc, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n" + "Content-Type: application/json\r\n\r\n%s", + (int) strlen(buf), buf); + nc->flags |= NSF_FINISHED_SENDING_DATA; + break; + default: + break; + } + } + + bool Json_rpc_http_server::add_handler(const std::string &method_name, + int (*hander)(char *buf, int len, struct ns_rpc_request *req)) + { + if (m_method_count == MAX_METHODS) + { + return false; + } + m_method_names[m_method_count] = new char[method_name.length() + 1]; + strcpy(m_method_names[m_method_count], method_name.c_str()); + m_handlers[m_method_count] = hander; + m_method_count++; + return true; + } +} diff --git a/src/rpc/json_rpc_http_server.h b/src/rpc/json_rpc_http_server.h new file mode 100644 index 000000000..e9cb01deb --- /dev/null +++ b/src/rpc/json_rpc_http_server.h @@ -0,0 +1,30 @@ +#include "net_skeleton/net_skeleton.h" +#include +#include + +#define MAX_METHODS 100 + +namespace RPC +{ + class Json_rpc_http_server + { + struct ns_mgr mgr; + struct ns_connection *nc; + boost::thread *server_thread; + void ev_handler(struct ns_connection *nc, int ev, void *ev_data); + void poll(); + std::string m_ip; + std::string m_port; + bool m_is_running; + char *m_method_names[MAX_METHODS]; + ns_rpc_handler_t m_handlers[MAX_METHODS]; + int m_method_count; + public: + Json_rpc_http_server(const std::string &ip, const std::string &port); + ~Json_rpc_http_server(); + void start(); + void stop(); + bool add_handler(const std::string &method_name, + int (*hander)(char *buf, int len, struct ns_rpc_request *req)); + }; +}