Bitcoin ABC  0.24.10
P2P Digital Currency
httprpc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2015-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <httprpc.h>
6 
7 #include <chainparams.h>
8 #include <config.h>
9 #include <crypto/hmac_sha256.h>
10 #include <rpc/protocol.h>
11 #include <util/ref.h>
12 #include <util/strencodings.h>
13 #include <util/system.h>
14 #include <util/translation.h>
15 #include <walletinitinterface.h>
16 
17 #include <boost/algorithm/string.hpp> // boost::trim
18 
19 #include <algorithm>
20 #include <cstdio>
21 #include <iterator>
22 #include <map>
23 #include <memory>
24 #include <set>
25 #include <string>
26 
28 static const char *WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\"";
29 
31 static const int64_t RPC_AUTH_BRUTE_FORCE_DELAY = 250;
32 
37 class HTTPRPCTimer : public RPCTimerBase {
38 public:
39  HTTPRPCTimer(struct event_base *eventBase, std::function<void()> &func,
40  int64_t millis)
41  : ev(eventBase, false, func) {
42  struct timeval tv;
43  tv.tv_sec = millis / 1000;
44  tv.tv_usec = (millis % 1000) * 1000;
45  ev.trigger(&tv);
46  }
47 
48 private:
50 };
51 
53 public:
54  explicit HTTPRPCTimerInterface(struct event_base *_base) : base(_base) {}
55 
56  const char *Name() override { return "HTTP"; }
57 
58  RPCTimerBase *NewTimer(std::function<void()> &func,
59  int64_t millis) override {
60  return new HTTPRPCTimer(base, func, millis);
61  }
62 
63 private:
64  struct event_base *base;
65 };
66 
67 /* Pre-base64-encoded authentication token */
68 static std::string strRPCUserColonPass;
69 /* Pre-base64-encoded authentication token */
70 static std::string strRPCCORSDomain;
71 /* Stored RPC timer interface (for unregistration) */
72 static std::unique_ptr<HTTPRPCTimerInterface> httpRPCTimerInterface;
73 /* RPC Auth Whitelist */
74 static std::map<std::string, std::set<std::string>> g_rpc_whitelist;
75 static bool g_rpc_whitelist_default = false;
76 
77 static void JSONErrorReply(HTTPRequest *req, const UniValue &objError,
78  const UniValue &id) {
79  // Send error reply from json-rpc error object.
80  int nStatus = HTTP_INTERNAL_SERVER_ERROR;
81  int code = find_value(objError, "code").get_int();
82 
83  if (code == RPC_INVALID_REQUEST) {
84  nStatus = HTTP_BAD_REQUEST;
85  } else if (code == RPC_METHOD_NOT_FOUND) {
86  nStatus = HTTP_NOT_FOUND;
87  }
88 
89  std::string strReply = JSONRPCReply(NullUniValue, objError, id);
90 
91  req->WriteHeader("Content-Type", "application/json");
92  req->WriteReply(nStatus, strReply);
93 }
94 
95 /*
96  * This function checks username and password against -rpcauth entries from
97  * config file.
98  */
99 static bool multiUserAuthorized(std::string strUserPass) {
100  if (strUserPass.find(':') == std::string::npos) {
101  return false;
102  }
103  std::string strUser = strUserPass.substr(0, strUserPass.find(':'));
104  std::string strPass = strUserPass.substr(strUserPass.find(':') + 1);
105 
106  for (const std::string &strRPCAuth : gArgs.GetArgs("-rpcauth")) {
107  // Search for multi-user login/pass "rpcauth" from config
108  std::vector<std::string> vFields;
109  boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
110  if (vFields.size() != 3) {
111  // Incorrect formatting in config file
112  continue;
113  }
114 
115  std::string strName = vFields[0];
116  if (!TimingResistantEqual(strName, strUser)) {
117  continue;
118  }
119 
120  std::string strSalt = vFields[1];
121  std::string strHash = vFields[2];
122 
123  static const unsigned int KEY_SIZE = 32;
124  uint8_t out[KEY_SIZE];
125 
126  CHMAC_SHA256(reinterpret_cast<const uint8_t *>(strSalt.data()),
127  strSalt.size())
128  .Write(reinterpret_cast<const uint8_t *>(strPass.data()),
129  strPass.size())
130  .Finalize(out);
131  std::vector<uint8_t> hexvec(out, out + KEY_SIZE);
132  std::string strHashFromPass = HexStr(hexvec);
133 
134  if (TimingResistantEqual(strHashFromPass, strHash)) {
135  return true;
136  }
137  }
138  return false;
139 }
140 
141 static bool RPCAuthorized(const std::string &strAuth,
142  std::string &strAuthUsernameOut) {
143  // Belt-and-suspenders measure if InitRPCAuthentication was not called.
144  if (strRPCUserColonPass.empty()) {
145  return false;
146  }
147 
148  if (strAuth.substr(0, 6) != "Basic ") {
149  return false;
150  }
151 
152  std::string strUserPass64 = strAuth.substr(6);
153  boost::trim(strUserPass64);
154  std::string strUserPass = DecodeBase64(strUserPass64);
155 
156  if (strUserPass.find(':') != std::string::npos) {
157  strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(':'));
158  }
159 
160  // Check if authorized under single-user field
161  if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
162  return true;
163  }
164  return multiUserAuthorized(strUserPass);
165 }
166 
167 static bool checkCORS(HTTPRequest *req) {
168  // https://www.w3.org/TR/cors/#resource-requests
169 
170  // 1. If the Origin header is not present terminate this set of steps.
171  // The request is outside the scope of this specification.
172  std::pair<bool, std::string> origin = req->GetHeader("origin");
173  if (!origin.first) {
174  return false;
175  }
176 
177  // 2. If the value of the Origin header is not a case-sensitive match for
178  // any of the values in list of origins do not set any additional headers
179  // and terminate this set of steps.
180  // Note: Always matching is acceptable since the list of origins can be
181  // unbounded.
182  if (origin.second != strRPCCORSDomain) {
183  return false;
184  }
185 
186  if (req->GetRequestMethod() == HTTPRequest::OPTIONS) {
187  // 6.2 Preflight Request
188  // In response to a preflight request the resource indicates which
189  // methods and headers (other than simple methods and simple
190  // headers) it is willing to handle and whether it supports
191  // credentials.
192  // Resources must use the following set of steps to determine which
193  // additional headers to use in the response:
194 
195  // 3. Let method be the value as result of parsing the
196  // Access-Control-Request-Method header.
197  // If there is no Access-Control-Request-Method header or if parsing
198  // failed, do not set any additional headers and terminate this set
199  // of steps. The request is outside the scope of this specification.
200  std::pair<bool, std::string> method =
201  req->GetHeader("access-control-request-method");
202  if (!method.first) {
203  return false;
204  }
205 
206  // 4. Let header field-names be the values as result of parsing
207  // the Access-Control-Request-Headers headers.
208  // If there are no Access-Control-Request-Headers headers let header
209  // field-names be the empty list.
210  // If parsing failed do not set any additional headers and terminate
211  // this set of steps. The request is outside the scope of this
212  // specification.
213  std::pair<bool, std::string> header_field_names =
214  req->GetHeader("access-control-request-headers");
215 
216  // 5. If method is not a case-sensitive match for any of the
217  // values in list of methods do not set any additional headers
218  // and terminate this set of steps.
219  // Note: Always matching is acceptable since the list of methods
220  // can be unbounded.
221  if (method.second != "POST") {
222  return false;
223  }
224 
225  // 6. If any of the header field-names is not a ASCII case-
226  // insensitive match for any of the values in list of headers do not
227  // set any additional headers and terminate this set of steps.
228  // Note: Always matching is acceptable since the list of headers can
229  // be unbounded.
230  const std::string &list_of_headers = "authorization,content-type";
231 
232  // 7. If the resource supports credentials add a single
233  // Access-Control-Allow-Origin header, with the value of the Origin
234  // header as value, and add a single
235  // Access-Control-Allow-Credentials header with the case-sensitive
236  // string "true" as value.
237  req->WriteHeader("Access-Control-Allow-Origin", origin.second);
238  req->WriteHeader("Access-Control-Allow-Credentials", "true");
239 
240  // 8. Optionally add a single Access-Control-Max-Age header with as
241  // value the amount of seconds the user agent is allowed to cache
242  // the result of the request.
243 
244  // 9. If method is a simple method this step may be skipped.
245  // Add one or more Access-Control-Allow-Methods headers consisting
246  // of (a subset of) the list of methods.
247  // If a method is a simple method it does not need to be listed, but
248  // this is not prohibited.
249  // Note: Since the list of methods can be unbounded, simply
250  // returning the method indicated by
251  // Access-Control-Request-Method (if supported) can be enough.
252  req->WriteHeader("Access-Control-Allow-Methods", method.second);
253 
254  // 10. If each of the header field-names is a simple header and none
255  // is Content-Type, this step may be skipped.
256  // Add one or more Access-Control-Allow-Headers headers consisting
257  // of (a subset of) the list of headers.
258  req->WriteHeader("Access-Control-Allow-Headers",
259  header_field_names.first ? header_field_names.second
260  : list_of_headers);
261  req->WriteReply(HTTP_OK);
262  return true;
263  }
264 
265  // 6.1 Simple Cross-Origin Request, Actual Request, and Redirects
266  // In response to a simple cross-origin request or actual request the
267  // resource indicates whether or not to share the response.
268  // If the resource has been relocated, it indicates whether to share its
269  // new URL.
270  // Resources must use the following set of steps to determine which
271  // additional headers to use in the response:
272 
273  // 3. If the resource supports credentials add a single
274  // Access-Control-Allow-Origin header, with the value of the Origin
275  // header as value, and add a single Access-Control-Allow-Credentials
276  // header with the case-sensitive string "true" as value.
277  req->WriteHeader("Access-Control-Allow-Origin", origin.second);
278  req->WriteHeader("Access-Control-Allow-Credentials", "true");
279 
280  // 4. If the list of exposed headers is not empty add one or more
281  // Access-Control-Expose-Headers headers, with as values the header
282  // field names given in the list of exposed headers.
283  req->WriteHeader("Access-Control-Expose-Headers", "WWW-Authenticate");
284 
285  return false;
286 }
287 
289  // First, check and/or set CORS headers
290  if (checkCORS(req)) {
291  return true;
292  }
293 
294  // JSONRPC handles only POST
295  if (req->GetRequestMethod() != HTTPRequest::POST) {
297  "JSONRPC server handles only POST requests");
298  return false;
299  }
300  // Check authorization
301  std::pair<bool, std::string> authHeader = req->GetHeader("authorization");
302  if (!authHeader.first) {
303  req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
305  return false;
306  }
307 
308  JSONRPCRequest jreq(context);
309  jreq.peerAddr = req->GetPeer().ToString();
310  if (!RPCAuthorized(authHeader.second, jreq.authUser)) {
311  LogPrintf("ThreadRPCServer incorrect password attempt from %s\n",
312  jreq.peerAddr);
313 
320  std::chrono::milliseconds{RPC_AUTH_BRUTE_FORCE_DELAY});
321 
322  req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA);
324  return false;
325  }
326 
327  try {
328  // Parse request
329  UniValue valRequest;
330  if (!valRequest.read(req->ReadBody())) {
331  throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
332  }
333 
334  // Set the URI
335  jreq.URI = req->GetURI();
336 
337  std::string strReply;
338  bool user_has_whitelist = g_rpc_whitelist.count(jreq.authUser);
339  if (!user_has_whitelist && g_rpc_whitelist_default) {
340  LogPrintf("RPC User %s not allowed to call any methods\n",
341  jreq.authUser);
343  return false;
344 
345  // singleton request
346  } else if (valRequest.isObject()) {
347  jreq.parse(valRequest);
348  if (user_has_whitelist &&
349  !g_rpc_whitelist[jreq.authUser].count(jreq.strMethod)) {
350  LogPrintf("RPC User %s not allowed to call method %s\n",
351  jreq.authUser, jreq.strMethod);
353  return false;
354  }
355  UniValue result = rpcServer.ExecuteCommand(config, jreq);
356 
357  // Send reply
358  strReply = JSONRPCReply(result, NullUniValue, jreq.id);
359 
360  // array of requests
361  } else if (valRequest.isArray()) {
362  if (user_has_whitelist) {
363  for (unsigned int reqIdx = 0; reqIdx < valRequest.size();
364  reqIdx++) {
365  if (!valRequest[reqIdx].isObject()) {
367  "Invalid Request object");
368  } else {
369  const UniValue &request = valRequest[reqIdx].get_obj();
370  // Parse method
371  std::string strMethod =
372  find_value(request, "method").get_str();
373  if (!g_rpc_whitelist[jreq.authUser].count(strMethod)) {
374  LogPrintf(
375  "RPC User %s not allowed to call method %s\n",
376  jreq.authUser, strMethod);
378  return false;
379  }
380  }
381  }
382  }
383  strReply = JSONRPCExecBatch(config, rpcServer, jreq,
384  valRequest.get_array());
385  } else {
386  throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
387  }
388 
389  req->WriteHeader("Content-Type", "application/json");
390  req->WriteReply(HTTP_OK, strReply);
391  } catch (const UniValue &objError) {
392  JSONErrorReply(req, objError, jreq.id);
393  return false;
394  } catch (const std::exception &e) {
395  JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
396  return false;
397  }
398  return true;
399 }
400 
401 static bool InitRPCAuthentication() {
402  if (gArgs.GetArg("-rpcpassword", "") == "") {
403  LogPrintf("Using random cookie authentication.\n");
405  return false;
406  }
407  } else {
408  LogPrintf("Config options rpcuser and rpcpassword will soon be "
409  "deprecated. Locally-run instances may remove rpcuser to use "
410  "cookie-based auth, or may be replaced with rpcauth. Please "
411  "see share/rpcauth for rpcauth auth generation.\n");
412  strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" +
413  gArgs.GetArg("-rpcpassword", "");
414  }
415 
416  strRPCCORSDomain = gArgs.GetArg("-rpccorsdomain", "");
417 
418  if (gArgs.GetArg("-rpcauth", "") != "") {
419  LogPrintf("Using rpcauth authentication.\n");
420  }
421 
422  g_rpc_whitelist_default = gArgs.GetBoolArg("-rpcwhitelistdefault",
423  gArgs.IsArgSet("-rpcwhitelist"));
424  for (const std::string &strRPCWhitelist : gArgs.GetArgs("-rpcwhitelist")) {
425  auto pos = strRPCWhitelist.find(':');
426  std::string strUser = strRPCWhitelist.substr(0, pos);
427  bool intersect = g_rpc_whitelist.count(strUser);
428  std::set<std::string> &whitelist = g_rpc_whitelist[strUser];
429  if (pos != std::string::npos) {
430  std::string strWhitelist = strRPCWhitelist.substr(pos + 1);
431  std::set<std::string> new_whitelist;
432  boost::split(new_whitelist, strWhitelist, boost::is_any_of(", "));
433  if (intersect) {
434  std::set<std::string> tmp_whitelist;
435  std::set_intersection(
436  new_whitelist.begin(), new_whitelist.end(),
437  whitelist.begin(), whitelist.end(),
438  std::inserter(tmp_whitelist, tmp_whitelist.end()));
439  new_whitelist = std::move(tmp_whitelist);
440  }
441  whitelist = std::move(new_whitelist);
442  }
443  }
444 
445  return true;
446 }
447 
448 bool StartHTTPRPC(HTTPRPCRequestProcessor &httpRPCRequestProcessor) {
449  LogPrint(BCLog::RPC, "Starting HTTP RPC server\n");
450  if (!InitRPCAuthentication()) {
451  return false;
452  }
453 
454  const std::function<bool(Config &, HTTPRequest *, const std::string &)>
455  &rpcFunction =
457  &httpRPCRequestProcessor, std::placeholders::_2);
458  RegisterHTTPHandler("/", true, rpcFunction);
460  RegisterHTTPHandler("/wallet/", false, rpcFunction);
461  }
462  struct event_base *eventBase = EventBase();
463  assert(eventBase);
464  httpRPCTimerInterface = std::make_unique<HTTPRPCTimerInterface>(eventBase);
466  return true;
467 }
468 
470  LogPrint(BCLog::RPC, "Interrupting HTTP RPC server\n");
471 }
472 
473 void StopHTTPRPC() {
474  LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
475  UnregisterHTTPHandler("/", true);
477  UnregisterHTTPHandler("/wallet/", false);
478  }
479  if (httpRPCTimerInterface) {
481  httpRPCTimerInterface.reset();
482  }
483 }
RPC_METHOD_NOT_FOUND
@ RPC_METHOD_NOT_FOUND
Definition: protocol.h:29
RPC_INVALID_REQUEST
@ RPC_INVALID_REQUEST
Standard JSON-RPC 2.0 errors.
Definition: protocol.h:26
multiUserAuthorized
static bool multiUserAuthorized(std::string strUserPass)
Definition: httprpc.cpp:99
HTTPRPCTimer
Simple one-shot callback timer to be used by the RPC mechanism to e.g.
Definition: httprpc.cpp:37
HTTPRequest::GetRequestMethod
RequestMethod GetRequestMethod() const
Get request method.
Definition: httpserver.cpp:661
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:601
ref.h
hmac_sha256.h
HTTPRPCRequestProcessor::config
Config & config
Definition: httprpc.h:19
g_rpc_whitelist
static std::map< std::string, std::set< std::string > > g_rpc_whitelist
Definition: httprpc.cpp:74
UnregisterHTTPHandler
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
Definition: httpserver.cpp:685
HTTP_BAD_METHOD
@ HTTP_BAD_METHOD
Definition: protocol.h:16
JSONErrorReply
static void JSONErrorReply(HTTPRequest *req, const UniValue &objError, const UniValue &id)
Definition: httprpc.cpp:77
GenerateAuthCookie
bool GenerateAuthCookie(std::string *cookie_out)
Generate a new RPC authentication cookie and write it to disk.
Definition: request.cpp:76
HTTPRPCTimerInterface
Definition: httprpc.cpp:52
RPCTimerInterface
RPC timer "driver".
Definition: server.h:100
JSONRPCReply
std::string JSONRPCReply(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:46
RPCUnsetTimerInterface
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:579
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
HTTPRPCTimer::ev
HTTPEvent ev
Definition: httprpc.cpp:49
RPC_AUTH_BRUTE_FORCE_DELAY
static const int64_t RPC_AUTH_BRUTE_FORCE_DELAY
RPC auth failure delay to make brute-forcing expensive.
Definition: httprpc.cpp:31
CHMAC_SHA256
A hasher class for HMAC-SHA-256.
Definition: hmac_sha256.h:14
EventBase
struct event_base * EventBase()
Return evhttp event base.
Definition: httpserver.cpp:523
HTTP_BAD_REQUEST
@ HTTP_BAD_REQUEST
Definition: protocol.h:12
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:482
HTTPRequest::GetPeer
CService GetPeer() const
Get CService (address:ip) for the origin of the http request.
Definition: httpserver.cpp:644
WalletInitInterface::HasWalletSupport
virtual bool HasWalletSupport() const =0
Is the wallet component enabled.
DecodeBase64
std::vector< uint8_t > DecodeBase64(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:155
RPCTimerBase
Opaque base class for timers returned by NewTimerFunc.
Definition: server.h:92
HTTPRPCRequestProcessor
Definition: httprpc.h:17
protocol.h
CHMAC_SHA256::Finalize
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition: hmac_sha256.cpp:30
UniValue::read
bool read(const char *raw, size_t len)
Definition: univalue_read.cpp:259
InterruptHTTPRPC
void InterruptHTTPRPC()
Interrupt HTTP RPC subsystem.
Definition: httprpc.cpp:469
chainparams.h
HTTPRequest::WriteHeader
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
Definition: httpserver.cpp:601
HTTPRequest::GetURI
std::string GetURI() const
Get requested URI.
Definition: httpserver.cpp:657
HTTPRequest::GetHeader
std::pair< bool, std::string > GetHeader(const std::string &hdr) const
Get the request header specified by hdr, or an empty string.
Definition: httpserver.cpp:566
UniValue
Definition: univalue.h:23
HTTPRequest::OPTIONS
@ OPTIONS
Definition: httpserver.h:83
JSONRPCRequest::peerAddr
std::string peerAddr
Definition: request.h:41
BCLog::RPC
@ RPC
Definition: logging.h:45
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
strencodings.h
Config
Definition: config.h:17
HTTPRequest::POST
@ POST
Definition: httpserver.h:83
CService::ToString
std::string ToString() const
Definition: netaddress.cpp:1023
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:135
RPCServer::ExecuteCommand
UniValue ExecuteCommand(const Config &config, const JSONRPCRequest &request) const
Attempts to execute an RPC command from the given request.
Definition: server.cpp:66
HTTPRequest
In-flight HTTP request.
Definition: httpserver.h:74
HTTP_FORBIDDEN
@ HTTP_FORBIDDEN
Definition: protocol.h:14
eventBase
static struct event_base * eventBase
HTTP module state.
Definition: httpserver.cpp:142
RPCAuthorized
static bool RPCAuthorized(const std::string &strAuth, std::string &strAuthUsernameOut)
Definition: httprpc.cpp:141
JSONRPCRequest::id
UniValue id
Definition: request.h:35
JSONRPCRequest::strMethod
std::string strMethod
Definition: request.h:36
HTTPRequest::ReadBody
std::string ReadBody()
Read request body.
Definition: httpserver.cpp:577
StopHTTPRPC
void StopHTTPRPC()
Stop HTTP RPC subsystem.
Definition: httprpc.cpp:473
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:582
g_rpc_whitelist_default
static bool g_rpc_whitelist_default
Definition: httprpc.cpp:75
HTTP_UNAUTHORIZED
@ HTTP_UNAUTHORIZED
Definition: protocol.h:13
walletinitinterface.h
HTTPRPCTimerInterface::Name
const char * Name() override
Implementation name.
Definition: httprpc.cpp:56
LogPrint
#define LogPrint(category,...)
Definition: logging.h:193
UniValue::isArray
bool isArray() const
Definition: univalue.h:95
TimingResistantEqual
bool TimingResistantEqual(const T &a, const T &b)
Timing-attack-resistant comparison.
Definition: strencodings.h:172
HTTPRPCTimer::HTTPRPCTimer
HTTPRPCTimer(struct event_base *eventBase, std::function< void()> &func, int64_t millis)
Definition: httprpc.cpp:39
JSONRPCRequest::parse
void parse(const UniValue &valRequest)
Definition: request.cpp:158
UninterruptibleSleep
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:20
system.h
httprpc.h
HTTPRPCRequestProcessor::ProcessHTTPRequest
bool ProcessHTTPRequest(HTTPRequest *request)
Definition: httprpc.cpp:288
HTTP_OK
@ HTTP_OK
Definition: protocol.h:11
checkCORS
static bool checkCORS(HTTPRequest *req)
Definition: httprpc.cpp:167
HTTPRPCTimerInterface::NewTimer
RPCTimerBase * NewTimer(std::function< void()> &func, int64_t millis) override
Factory function for timers.
Definition: httprpc.cpp:58
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
JSONRPCExecBatch
std::string JSONRPCExecBatch(const Config &config, RPCServer &rpcServer, const JSONRPCRequest &jreq, const UniValue &vReq)
Definition: server.cpp:430
HTTPRPCRequestProcessor::DelegateHTTPRequest
static bool DelegateHTTPRequest(HTTPRPCRequestProcessor *requestProcessor, HTTPRequest *request)
Definition: httprpc.h:31
WWW_AUTH_HEADER_DATA
static const char * WWW_AUTH_HEADER_DATA
WWW-Authenticate to present with 401 Unauthorized response.
Definition: httprpc.cpp:28
translation.h
HTTPEvent::trigger
void trigger(struct timeval *tv)
Trigger the event.
Definition: httpserver.cpp:545
InitRPCAuthentication
static bool InitRPCAuthentication()
Definition: httprpc.cpp:401
JSONRPCError
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:52
HTTPEvent
Event class.
Definition: httpserver.h:139
strRPCUserColonPass
static std::string strRPCUserColonPass
Definition: httprpc.cpp:68
gArgs
ArgsManager gArgs
Definition: system.cpp:76
CHMAC_SHA256::Write
CHMAC_SHA256 & Write(const uint8_t *data, size_t len)
Definition: hmac_sha256.h:23
strRPCCORSDomain
static std::string strRPCCORSDomain
Definition: httprpc.cpp:70
HTTP_NOT_FOUND
@ HTTP_NOT_FOUND
Definition: protocol.h:15
HTTPRPCRequestProcessor::context
const util::Ref & context
Definition: httprpc.h:25
config.h
g_wallet_init_interface
const WalletInitInterface & g_wallet_init_interface
Definition: dummywallet.cpp:40
UniValue::size
size_t size() const
Definition: univalue.h:80
StartHTTPRPC
bool StartHTTPRPC(HTTPRPCRequestProcessor &httpRPCRequestProcessor)
Start HTTP RPC subsystem.
Definition: httprpc.cpp:448
JSONRPCRequest::URI
std::string URI
Definition: request.h:39
JSONRPCRequest
Definition: request.h:33
find_value
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:234
ArgsManager::GetArgs
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:473
HTTPRPCTimerInterface::HTTPRPCTimerInterface
HTTPRPCTimerInterface(struct event_base *_base)
Definition: httprpc.cpp:54
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:142
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:656
RegisterHTTPHandler
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
Definition: httpserver.cpp:678
HTTPRequest::WriteReply
void WriteReply(int nStatus, const std::string &strReply="")
Write HTTP reply.
Definition: httpserver.cpp:613
httpRPCTimerInterface
static std::unique_ptr< HTTPRPCTimerInterface > httpRPCTimerInterface
Definition: httprpc.cpp:72
HTTPRPCRequestProcessor::rpcServer
RPCServer & rpcServer
Definition: httprpc.h:20
JSONRPCRequest::authUser
std::string authUser
Definition: request.h:40
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
RPC_PARSE_ERROR
@ RPC_PARSE_ERROR
Definition: protocol.h:34
RPCSetTimerInterface
void RPCSetTimerInterface(RPCTimerInterface *iface)
Set the factory function for timers.
Definition: server.cpp:575
UniValue::isObject
bool isObject() const
Definition: univalue.h:96
HTTPRPCTimerInterface::base
struct event_base * base
Definition: httprpc.cpp:64
HTTP_INTERNAL_SERVER_ERROR
@ HTTP_INTERNAL_SERVER_ERROR
Definition: protocol.h:17