21 #include <sys/types.h>
27 #include <event2/event.h>
28 #include <event2/http.h>
29 #include <event2/thread.h>
30 #include <event2/buffer.h>
31 #include <event2/bufferevent.h>
32 #include <event2/util.h>
33 #include <event2/keyvalq_struct.h>
35 #ifdef EVENT__HAVE_NETINET_IN_H
36 #include <netinet/in.h>
37 #ifdef _XOPEN_SOURCE_EXTENDED
38 #include <arpa/inet.h>
43 static const size_t MAX_HEADERS_SIZE = 8192;
58 std::unique_ptr<HTTPRequest>
req;
68 template <
typename WorkItem>
74 std::condition_variable
cond;
88 std::lock_guard<std::mutex> lock(
wq.
cs);
93 std::lock_guard<std::mutex> lock(
wq.
cs);
110 while (!
queue.empty()) {
111 delete queue.front();
118 std::unique_lock<std::mutex> lock(
cs);
122 queue.push_back(item);
133 std::unique_lock<std::mutex> lock(
cs);
148 std::unique_lock<std::mutex> lock(
cs);
155 std::unique_lock<std::mutex> lock(
cs);
163 std::unique_lock<std::mutex> lock(
cs);
182 static struct event_base* eventBase = 0;
187 static std::vector<CSubNet> rpc_allow_subnets;
195 static bool ClientAllowed(
const CNetAddr& netaddr)
199 for (
const CSubNet& subnet : rpc_allow_subnets)
200 if (subnet.
Match(netaddr))
206 static bool InitHTTPAllowList()
208 rpc_allow_subnets.clear();
213 rpc_allow_subnets.push_back(
CSubNet(localv4, 8));
214 rpc_allow_subnets.push_back(
CSubNet(localv6));
216 const std::vector<std::string>& vAllow =
mapMultiArgs[
"-rpcallowip"];
217 for (std::string strAllow : vAllow) {
222 strprintf(
"Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
226 rpc_allow_subnets.push_back(subnet);
229 std::string strAllowed;
230 for (
const CSubNet& subnet : rpc_allow_subnets)
231 strAllowed += subnet.
ToString() +
" ";
258 static void http_request_cb(
struct evhttp_request* req,
void* arg)
261 if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
262 evhttp_connection* conn = evhttp_request_get_connection(req);
264 bufferevent* bev = evhttp_connection_get_bufferevent(conn);
266 bufferevent_disable(bev, EV_READ);
270 std::unique_ptr<HTTPRequest> hreq(
new HTTPRequest(req));
273 RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString());
276 if (!ClientAllowed(hreq->GetPeer())) {
283 hreq->WriteReply(HTTP_BADMETHOD);
288 std::string strURI = hreq->GetURI();
290 std::vector<HTTPPathHandler>::const_iterator i =
pathHandlers.begin();
291 std::vector<HTTPPathHandler>::const_iterator iend =
pathHandlers.end();
292 for (; i != iend; ++i) {
295 match = (strURI == i->prefix);
297 match = (strURI.substr(0, i->prefix.size()) == i->prefix);
299 path = strURI.substr(i->prefix.size());
306 std::unique_ptr<HTTPWorkItem> item(
new HTTPWorkItem(hreq.release(), path, i->handler));
308 if (workQueue->Enqueue(item.get()))
311 item->req->WriteReply(HTTP_INTERNAL,
"Work queue depth exceeded");
313 hreq->WriteReply(HTTP_NOTFOUND);
318 static void http_reject_request_cb(
struct evhttp_request* req,
void*)
321 evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
324 static bool ThreadHTTP(
struct event_base* base,
struct evhttp* http)
328 event_base_dispatch(base);
331 return event_base_got_break(base) == 0;
335 static bool HTTPBindAddresses(
struct evhttp* http)
338 std::vector<std::pair<std::string, uint16_t> > endpoints;
341 if (!
mapArgs.count(
"-rpcallowip")) {
342 endpoints.push_back(std::make_pair(
"::1", defaultPort));
343 endpoints.push_back(std::make_pair(
"127.0.0.1", defaultPort));
344 if (
mapArgs.count(
"-rpcbind")) {
345 LogPrintf(
"WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
347 }
else if (
mapArgs.count(
"-rpcbind")) {
348 const std::vector<std::string>& vbind =
mapMultiArgs[
"-rpcbind"];
349 for (std::vector<std::string>::const_iterator i = vbind.begin(); i != vbind.end(); ++i) {
350 int port = defaultPort;
353 endpoints.push_back(std::make_pair(host, port));
356 endpoints.push_back(std::make_pair(
"::", defaultPort));
357 endpoints.push_back(std::make_pair(
"0.0.0.0", defaultPort));
361 for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) {
363 evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second);
367 LogPrintf(
"Binding RPC on address %s port %i failed.\n", i->first, i->second);
381 static void libevent_log_cb(
int severity,
const char *msg)
383 #ifndef EVENT_LOG_WARN
385 # define EVENT_LOG_WARN _EVENT_LOG_WARN
395 struct evhttp* http = 0;
396 struct event_base* base = 0;
398 if (!InitHTTPAllowList())
403 "SSL mode for RPC (-rpcssl) is no longer supported.",
409 event_set_log_callback(&libevent_log_cb);
418 evthread_use_windows_threads();
420 evthread_use_pthreads();
423 base = event_base_new();
425 LogPrintf(
"Couldn't create an event_base: exiting\n");
430 http = evhttp_new(base);
432 LogPrintf(
"couldn't create evhttp. Exiting.\n");
433 event_base_free(base);
437 evhttp_set_timeout(http,
GetArg(
"-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
438 evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
439 evhttp_set_max_body_size(http, MAX_SIZE);
440 evhttp_set_gencb(http, http_request_cb, NULL);
442 if (!HTTPBindAddresses(http)) {
443 LogPrintf(
"Unable to bind any endpoint for RPC server\n");
445 event_base_free(base);
450 int workQueueDepth = std::max((
long)
GetArg(
"-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1
L);
451 LogPrintf(
"HTTP: creating work queue of depth %d\n", workQueueDepth);
460 #if LIBEVENT_VERSION_NUMBER >= 0x02010100
462 event_enable_debug_logging(EVENT_DBG_ALL);
464 event_enable_debug_logging(EVENT_DBG_NONE);
479 int rpcThreads = std::max((
long)
GetArg(
"-rpcthreads", DEFAULT_HTTP_THREADS), 1
L);
480 LogPrintf(
"HTTP: starting %d worker threads\n", rpcThreads);
481 std::packaged_task<bool(event_base*, evhttp*)> task(ThreadHTTP);
485 for (
int i = 0; i < rpcThreads; i++) {
486 std::thread rpc_worker(HTTPWorkQueueRun, workQueue);
497 evhttp_del_accept_socket(
eventHTTP, socket);
499 evhttp_set_gencb(
eventHTTP, http_reject_request_cb, NULL);
502 workQueue->Interrupt();
510 workQueue->WaitExit();
522 if (
threadResult.valid() &&
threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
523 LogPrintf(
"HTTP event loop did not exit within allotted time, sending loopbreak\n");
524 event_base_loopbreak(eventBase);
534 event_base_free(eventBase);
545 static void httpevent_callback_fn(evutil_socket_t,
short,
void* data)
550 if (self->deleteWhenTriggered)
557 ev = event_new(base, -1, 0, httpevent_callback_fn,
this);
567 event_active(
ev, 0, 0);
579 LogPrintf(
"%s: Unhandled request\n", __func__);
580 WriteReply(HTTP_INTERNAL,
"Unhandled request");
587 const struct evkeyvalq* headers = evhttp_request_get_input_headers(
req);
589 const char* val = evhttp_find_header(headers, hdr.c_str());
591 return std::make_pair(
true, val);
593 return std::make_pair(
false,
"");
598 struct evbuffer* buf = evhttp_request_get_input_buffer(
req);
601 size_t size = evbuffer_get_length(buf);
608 const char* data = (
const char*)evbuffer_pullup(buf, size);
611 std::string rv(data, size);
612 evbuffer_drain(buf, size);
618 struct evkeyvalq* headers = evhttp_request_get_output_headers(
req);
620 evhttp_add_header(headers, hdr.c_str(), value.c_str());
632 struct evbuffer* evb = evhttp_request_get_output_buffer(
req);
634 evbuffer_add(evb, strReply.data(), strReply.size());
637 evhttp_send_reply(req_copy, nStatus,
nullptr,
nullptr);
640 if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
641 evhttp_connection* conn = evhttp_request_get_connection(req_copy);
643 bufferevent* bev = evhttp_connection_get_bufferevent(conn);
645 bufferevent_enable(bev, EV_READ | EV_WRITE);
657 evhttp_connection* con = evhttp_request_get_connection(
req);
661 const char* address =
"";
663 evhttp_connection_get_peer(con, (
char**)&address, &port);
671 return evhttp_request_get_uri(
req);
676 switch (evhttp_request_get_command(
req)) {
680 case EVHTTP_REQ_POST:
683 case EVHTTP_REQ_HEAD:
703 std::vector<HTTPPathHandler>::iterator i =
pathHandlers.begin();
704 std::vector<HTTPPathHandler>::iterator iend =
pathHandlers.end();
705 for (; i != iend; ++i)
706 if (i->prefix ==
prefix && i->exactMatch == exactMatch)