You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bitcoinrpc.cpp 49KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. // Copyright (c) 2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2013 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "bitcoinrpc.h"
  6. #include "base58.h"
  7. #include "init.h"
  8. #include "main.h"
  9. #include "util.h"
  10. #include "wallet.h"
  11. #include <stdint.h>
  12. #include <boost/algorithm/string.hpp>
  13. #include <boost/asio.hpp>
  14. #include <boost/asio/ssl.hpp>
  15. #include <boost/bind.hpp>
  16. #include <boost/filesystem.hpp>
  17. #include <boost/foreach.hpp>
  18. #include <boost/iostreams/concepts.hpp>
  19. #include <boost/iostreams/stream.hpp>
  20. #include <boost/lexical_cast.hpp>
  21. #include <boost/shared_ptr.hpp>
  22. #include "json/json_spirit_writer_template.h"
  23. using namespace std;
  24. using namespace boost;
  25. using namespace boost::asio;
  26. using namespace json_spirit;
  27. static std::string strRPCUserColonPass;
  28. // These are created by StartRPCThreads, destroyed in StopRPCThreads
  29. static asio::io_service* rpc_io_service = NULL;
  30. static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
  31. static ssl::context* rpc_ssl_context = NULL;
  32. static boost::thread_group* rpc_worker_group = NULL;
  33. Object JSONRPCError(int code, const string& message)
  34. {
  35. Object error;
  36. error.push_back(Pair("code", code));
  37. error.push_back(Pair("message", message));
  38. return error;
  39. }
  40. void RPCTypeCheck(const Array& params,
  41. const list<Value_type>& typesExpected,
  42. bool fAllowNull)
  43. {
  44. unsigned int i = 0;
  45. BOOST_FOREACH(Value_type t, typesExpected)
  46. {
  47. if (params.size() <= i)
  48. break;
  49. const Value& v = params[i];
  50. if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
  51. {
  52. string err = strprintf("Expected type %s, got %s",
  53. Value_type_name[t], Value_type_name[v.type()]);
  54. throw JSONRPCError(RPC_TYPE_ERROR, err);
  55. }
  56. i++;
  57. }
  58. }
  59. void RPCTypeCheck(const Object& o,
  60. const map<string, Value_type>& typesExpected,
  61. bool fAllowNull)
  62. {
  63. BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected)
  64. {
  65. const Value& v = find_value(o, t.first);
  66. if (!fAllowNull && v.type() == null_type)
  67. throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first.c_str()));
  68. if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
  69. {
  70. string err = strprintf("Expected type %s for %s, got %s",
  71. Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]);
  72. throw JSONRPCError(RPC_TYPE_ERROR, err);
  73. }
  74. }
  75. }
  76. int64_t AmountFromValue(const Value& value)
  77. {
  78. double dAmount = value.get_real();
  79. if (dAmount <= 0.0 || dAmount > 21000000.0)
  80. throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
  81. int64_t nAmount = roundint64(dAmount * COIN);
  82. if (!MoneyRange(nAmount))
  83. throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
  84. return nAmount;
  85. }
  86. Value ValueFromAmount(int64_t amount)
  87. {
  88. return (double)amount / (double)COIN;
  89. }
  90. std::string HexBits(unsigned int nBits)
  91. {
  92. union {
  93. int32_t nBits;
  94. char cBits[4];
  95. } uBits;
  96. uBits.nBits = htonl((int32_t)nBits);
  97. return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
  98. }
  99. uint256 ParseHashV(const Value& v, string strName)
  100. {
  101. string strHex;
  102. if (v.type() == str_type)
  103. strHex = v.get_str();
  104. if (!IsHex(strHex)) // Note: IsHex("") is false
  105. throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
  106. uint256 result;
  107. result.SetHex(strHex);
  108. return result;
  109. }
  110. uint256 ParseHashO(const Object& o, string strKey)
  111. {
  112. return ParseHashV(find_value(o, strKey), strKey);
  113. }
  114. vector<unsigned char> ParseHexV(const Value& v, string strName)
  115. {
  116. string strHex;
  117. if (v.type() == str_type)
  118. strHex = v.get_str();
  119. if (!IsHex(strHex))
  120. throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
  121. return ParseHex(strHex);
  122. }
  123. vector<unsigned char> ParseHexO(const Object& o, string strKey)
  124. {
  125. return ParseHexV(find_value(o, strKey), strKey);
  126. }
  127. ///
  128. /// Note: This interface may still be subject to change.
  129. ///
  130. string CRPCTable::help(string strCommand) const
  131. {
  132. string strRet;
  133. set<rpcfn_type> setDone;
  134. for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
  135. {
  136. const CRPCCommand *pcmd = mi->second;
  137. string strMethod = mi->first;
  138. // We already filter duplicates, but these deprecated screw up the sort order
  139. if (strMethod.find("label") != string::npos)
  140. continue;
  141. if (strCommand != "" && strMethod != strCommand)
  142. continue;
  143. if (pcmd->reqWallet && !pwalletMain)
  144. continue;
  145. try
  146. {
  147. Array params;
  148. rpcfn_type pfn = pcmd->actor;
  149. if (setDone.insert(pfn).second)
  150. (*pfn)(params, true);
  151. }
  152. catch (std::exception& e)
  153. {
  154. // Help text is returned in an exception
  155. string strHelp = string(e.what());
  156. if (strCommand == "")
  157. if (strHelp.find('\n') != string::npos)
  158. strHelp = strHelp.substr(0, strHelp.find('\n'));
  159. strRet += strHelp + "\n";
  160. }
  161. }
  162. if (strRet == "")
  163. strRet = strprintf("help: unknown command: %s\n", strCommand.c_str());
  164. strRet = strRet.substr(0,strRet.size()-1);
  165. return strRet;
  166. }
  167. Value help(const Array& params, bool fHelp)
  168. {
  169. if (fHelp || params.size() > 1)
  170. throw runtime_error(
  171. "help [command]\n"
  172. "List commands, or get help for a command.");
  173. string strCommand;
  174. if (params.size() > 0)
  175. strCommand = params[0].get_str();
  176. return tableRPC.help(strCommand);
  177. }
  178. Value stop(const Array& params, bool fHelp)
  179. {
  180. // Accept the deprecated and ignored 'detach' boolean argument
  181. if (fHelp || params.size() > 1)
  182. throw runtime_error(
  183. "stop\n"
  184. "Stop Bitcoin server.");
  185. // Shutdown will take long enough that the response should get back
  186. StartShutdown();
  187. return "Bitcoin server stopping";
  188. }
  189. //
  190. // Call Table
  191. //
  192. static const CRPCCommand vRPCCommands[] =
  193. { // name actor (function) okSafeMode threadSafe reqWallet
  194. // ------------------------ ----------------------- ---------- ---------- ---------
  195. { "help", &help, true, true, false },
  196. { "stop", &stop, true, true, false },
  197. { "getblockcount", &getblockcount, true, false, false },
  198. { "getbestblockhash", &getbestblockhash, true, false, false },
  199. { "getconnectioncount", &getconnectioncount, true, false, false },
  200. { "getpeerinfo", &getpeerinfo, true, false, false },
  201. { "ping", &ping, true, false, false },
  202. { "addnode", &addnode, true, true, false },
  203. { "getaddednodeinfo", &getaddednodeinfo, true, true, false },
  204. { "getnettotals", &getnettotals, true, true, false },
  205. { "getdifficulty", &getdifficulty, true, false, false },
  206. { "getnetworkhashps", &getnetworkhashps, true, false, false },
  207. { "getgenerate", &getgenerate, true, false, false },
  208. { "setgenerate", &setgenerate, true, false, true },
  209. { "gethashespersec", &gethashespersec, true, false, false },
  210. { "getinfo", &getinfo, true, false, false },
  211. { "getmininginfo", &getmininginfo, true, false, false },
  212. { "getnewaddress", &getnewaddress, true, false, true },
  213. { "getaccountaddress", &getaccountaddress, true, false, true },
  214. { "getrawchangeaddress", &getrawchangeaddress, true, false, true },
  215. { "setaccount", &setaccount, true, false, true },
  216. { "getaccount", &getaccount, false, false, true },
  217. { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
  218. { "sendtoaddress", &sendtoaddress, false, false, true },
  219. { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
  220. { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
  221. { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
  222. { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
  223. { "backupwallet", &backupwallet, true, false, true },
  224. { "keypoolrefill", &keypoolrefill, true, false, true },
  225. { "walletpassphrase", &walletpassphrase, true, false, true },
  226. { "walletpassphrasechange", &walletpassphrasechange, false, false, true },
  227. { "walletlock", &walletlock, true, false, true },
  228. { "encryptwallet", &encryptwallet, false, false, true },
  229. { "validateaddress", &validateaddress, true, false, false },
  230. { "getbalance", &getbalance, false, false, true },
  231. { "move", &movecmd, false, false, true },
  232. { "sendfrom", &sendfrom, false, false, true },
  233. { "sendmany", &sendmany, false, false, true },
  234. { "addmultisigaddress", &addmultisigaddress, false, false, true },
  235. { "createmultisig", &createmultisig, true, true , false },
  236. { "getrawmempool", &getrawmempool, true, false, false },
  237. { "getblock", &getblock, false, false, false },
  238. { "getblockhash", &getblockhash, false, false, false },
  239. { "gettransaction", &gettransaction, false, false, true },
  240. { "listtransactions", &listtransactions, false, false, true },
  241. { "listaddressgroupings", &listaddressgroupings, false, false, true },
  242. { "signmessage", &signmessage, false, false, true },
  243. { "verifymessage", &verifymessage, false, false, false },
  244. { "getwork", &getwork, true, false, true },
  245. { "listaccounts", &listaccounts, false, false, true },
  246. { "settxfee", &settxfee, false, false, true },
  247. { "getblocktemplate", &getblocktemplate, true, false, false },
  248. { "submitblock", &submitblock, false, false, false },
  249. { "listsinceblock", &listsinceblock, false, false, true },
  250. { "dumpprivkey", &dumpprivkey, true, false, true },
  251. { "dumpwallet", &dumpwallet, true, false, true },
  252. { "importprivkey", &importprivkey, false, false, true },
  253. { "importwallet", &importwallet, false, false, true },
  254. { "listunspent", &listunspent, false, false, true },
  255. { "getrawtransaction", &getrawtransaction, false, false, false },
  256. { "createrawtransaction", &createrawtransaction, false, false, false },
  257. { "decoderawtransaction", &decoderawtransaction, false, false, false },
  258. { "decodescript", &decodescript, false, false, false },
  259. { "signrawtransaction", &signrawtransaction, false, false, false },
  260. { "sendrawtransaction", &sendrawtransaction, false, false, false },
  261. { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
  262. { "gettxout", &gettxout, true, false, false },
  263. { "lockunspent", &lockunspent, false, false, true },
  264. { "listlockunspent", &listlockunspent, false, false, true },
  265. { "verifychain", &verifychain, true, false, false },
  266. };
  267. CRPCTable::CRPCTable()
  268. {
  269. unsigned int vcidx;
  270. for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
  271. {
  272. const CRPCCommand *pcmd;
  273. pcmd = &vRPCCommands[vcidx];
  274. mapCommands[pcmd->name] = pcmd;
  275. }
  276. }
  277. const CRPCCommand *CRPCTable::operator[](string name) const
  278. {
  279. map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
  280. if (it == mapCommands.end())
  281. return NULL;
  282. return (*it).second;
  283. }
  284. //
  285. // HTTP protocol
  286. //
  287. // This ain't Apache. We're just using HTTP header for the length field
  288. // and to be compatible with other JSON-RPC implementations.
  289. //
  290. string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
  291. {
  292. ostringstream s;
  293. s << "POST / HTTP/1.1\r\n"
  294. << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
  295. << "Host: 127.0.0.1\r\n"
  296. << "Content-Type: application/json\r\n"
  297. << "Content-Length: " << strMsg.size() << "\r\n"
  298. << "Connection: close\r\n"
  299. << "Accept: application/json\r\n";
  300. BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
  301. s << item.first << ": " << item.second << "\r\n";
  302. s << "\r\n" << strMsg;
  303. return s.str();
  304. }
  305. string rfc1123Time()
  306. {
  307. char buffer[64];
  308. time_t now;
  309. time(&now);
  310. struct tm* now_gmt = gmtime(&now);
  311. string locale(setlocale(LC_TIME, NULL));
  312. setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings
  313. strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
  314. setlocale(LC_TIME, locale.c_str());
  315. return string(buffer);
  316. }
  317. static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
  318. {
  319. if (nStatus == HTTP_UNAUTHORIZED)
  320. return strprintf("HTTP/1.0 401 Authorization Required\r\n"
  321. "Date: %s\r\n"
  322. "Server: bitcoin-json-rpc/%s\r\n"
  323. "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
  324. "Content-Type: text/html\r\n"
  325. "Content-Length: 296\r\n"
  326. "\r\n"
  327. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
  328. "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
  329. "<HTML>\r\n"
  330. "<HEAD>\r\n"
  331. "<TITLE>Error</TITLE>\r\n"
  332. "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
  333. "</HEAD>\r\n"
  334. "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
  335. "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
  336. const char *cStatus;
  337. if (nStatus == HTTP_OK) cStatus = "OK";
  338. else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request";
  339. else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden";
  340. else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found";
  341. else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error";
  342. else cStatus = "";
  343. return strprintf(
  344. "HTTP/1.1 %d %s\r\n"
  345. "Date: %s\r\n"
  346. "Connection: %s\r\n"
  347. "Content-Length: %"PRIszu"\r\n"
  348. "Content-Type: application/json\r\n"
  349. "Server: bitcoin-json-rpc/%s\r\n"
  350. "\r\n"
  351. "%s",
  352. nStatus,
  353. cStatus,
  354. rfc1123Time().c_str(),
  355. keepalive ? "keep-alive" : "close",
  356. strMsg.size(),
  357. FormatFullVersion().c_str(),
  358. strMsg.c_str());
  359. }
  360. bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
  361. string& http_method, string& http_uri)
  362. {
  363. string str;
  364. getline(stream, str);
  365. // HTTP request line is space-delimited
  366. vector<string> vWords;
  367. boost::split(vWords, str, boost::is_any_of(" "));
  368. if (vWords.size() < 2)
  369. return false;
  370. // HTTP methods permitted: GET, POST
  371. http_method = vWords[0];
  372. if (http_method != "GET" && http_method != "POST")
  373. return false;
  374. // HTTP URI must be an absolute path, relative to current host
  375. http_uri = vWords[1];
  376. if (http_uri.size() == 0 || http_uri[0] != '/')
  377. return false;
  378. // parse proto, if present
  379. string strProto = "";
  380. if (vWords.size() > 2)
  381. strProto = vWords[2];
  382. proto = 0;
  383. const char *ver = strstr(strProto.c_str(), "HTTP/1.");
  384. if (ver != NULL)
  385. proto = atoi(ver+7);
  386. return true;
  387. }
  388. int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
  389. {
  390. string str;
  391. getline(stream, str);
  392. vector<string> vWords;
  393. boost::split(vWords, str, boost::is_any_of(" "));
  394. if (vWords.size() < 2)
  395. return HTTP_INTERNAL_SERVER_ERROR;
  396. proto = 0;
  397. const char *ver = strstr(str.c_str(), "HTTP/1.");
  398. if (ver != NULL)
  399. proto = atoi(ver+7);
  400. return atoi(vWords[1].c_str());
  401. }
  402. int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
  403. {
  404. int nLen = 0;
  405. while (true)
  406. {
  407. string str;
  408. std::getline(stream, str);
  409. if (str.empty() || str == "\r")
  410. break;
  411. string::size_type nColon = str.find(":");
  412. if (nColon != string::npos)
  413. {
  414. string strHeader = str.substr(0, nColon);
  415. boost::trim(strHeader);
  416. boost::to_lower(strHeader);
  417. string strValue = str.substr(nColon+1);
  418. boost::trim(strValue);
  419. mapHeadersRet[strHeader] = strValue;
  420. if (strHeader == "content-length")
  421. nLen = atoi(strValue.c_str());
  422. }
  423. }
  424. return nLen;
  425. }
  426. int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
  427. string>& mapHeadersRet, string& strMessageRet,
  428. int nProto)
  429. {
  430. mapHeadersRet.clear();
  431. strMessageRet = "";
  432. // Read header
  433. int nLen = ReadHTTPHeaders(stream, mapHeadersRet);
  434. if (nLen < 0 || nLen > (int)MAX_SIZE)
  435. return HTTP_INTERNAL_SERVER_ERROR;
  436. // Read message
  437. if (nLen > 0)
  438. {
  439. vector<char> vch(nLen);
  440. stream.read(&vch[0], nLen);
  441. strMessageRet = string(vch.begin(), vch.end());
  442. }
  443. string sConHdr = mapHeadersRet["connection"];
  444. if ((sConHdr != "close") && (sConHdr != "keep-alive"))
  445. {
  446. if (nProto >= 1)
  447. mapHeadersRet["connection"] = "keep-alive";
  448. else
  449. mapHeadersRet["connection"] = "close";
  450. }
  451. return HTTP_OK;
  452. }
  453. bool HTTPAuthorized(map<string, string>& mapHeaders)
  454. {
  455. string strAuth = mapHeaders["authorization"];
  456. if (strAuth.substr(0,6) != "Basic ")
  457. return false;
  458. string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
  459. string strUserPass = DecodeBase64(strUserPass64);
  460. return TimingResistantEqual(strUserPass, strRPCUserColonPass);
  461. }
  462. //
  463. // JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
  464. // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
  465. // unspecified (HTTP errors and contents of 'error').
  466. //
  467. // 1.0 spec: http://json-rpc.org/wiki/specification
  468. // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
  469. // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
  470. //
  471. string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
  472. {
  473. Object request;
  474. request.push_back(Pair("method", strMethod));
  475. request.push_back(Pair("params", params));
  476. request.push_back(Pair("id", id));
  477. return write_string(Value(request), false) + "\n";
  478. }
  479. Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id)
  480. {
  481. Object reply;
  482. if (error.type() != null_type)
  483. reply.push_back(Pair("result", Value::null));
  484. else
  485. reply.push_back(Pair("result", result));
  486. reply.push_back(Pair("error", error));
  487. reply.push_back(Pair("id", id));
  488. return reply;
  489. }
  490. string JSONRPCReply(const Value& result, const Value& error, const Value& id)
  491. {
  492. Object reply = JSONRPCReplyObj(result, error, id);
  493. return write_string(Value(reply), false) + "\n";
  494. }
  495. void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
  496. {
  497. // Send error reply from json-rpc error object
  498. int nStatus = HTTP_INTERNAL_SERVER_ERROR;
  499. int code = find_value(objError, "code").get_int();
  500. if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
  501. else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
  502. string strReply = JSONRPCReply(Value::null, objError, id);
  503. stream << HTTPReply(nStatus, strReply, false) << std::flush;
  504. }
  505. bool ClientAllowed(const boost::asio::ip::address& address)
  506. {
  507. // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
  508. if (address.is_v6()
  509. && (address.to_v6().is_v4_compatible()
  510. || address.to_v6().is_v4_mapped()))
  511. return ClientAllowed(address.to_v6().to_v4());
  512. if (address == asio::ip::address_v4::loopback()
  513. || address == asio::ip::address_v6::loopback()
  514. || (address.is_v4()
  515. // Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet)
  516. && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000))
  517. return true;
  518. const string strAddress = address.to_string();
  519. const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
  520. BOOST_FOREACH(string strAllow, vAllow)
  521. if (WildcardMatch(strAddress, strAllow))
  522. return true;
  523. return false;
  524. }
  525. //
  526. // IOStream device that speaks SSL but can also speak non-SSL
  527. //
  528. template <typename Protocol>
  529. class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
  530. public:
  531. SSLIOStreamDevice(asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn)
  532. {
  533. fUseSSL = fUseSSLIn;
  534. fNeedHandshake = fUseSSLIn;
  535. }
  536. void handshake(ssl::stream_base::handshake_type role)
  537. {
  538. if (!fNeedHandshake) return;
  539. fNeedHandshake = false;
  540. stream.handshake(role);
  541. }
  542. std::streamsize read(char* s, std::streamsize n)
  543. {
  544. handshake(ssl::stream_base::server); // HTTPS servers read first
  545. if (fUseSSL) return stream.read_some(asio::buffer(s, n));
  546. return stream.next_layer().read_some(asio::buffer(s, n));
  547. }
  548. std::streamsize write(const char* s, std::streamsize n)
  549. {
  550. handshake(ssl::stream_base::client); // HTTPS clients write first
  551. if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
  552. return asio::write(stream.next_layer(), asio::buffer(s, n));
  553. }
  554. bool connect(const std::string& server, const std::string& port)
  555. {
  556. ip::tcp::resolver resolver(stream.get_io_service());
  557. ip::tcp::resolver::query query(server.c_str(), port.c_str());
  558. ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
  559. ip::tcp::resolver::iterator end;
  560. boost::system::error_code error = asio::error::host_not_found;
  561. while (error && endpoint_iterator != end)
  562. {
  563. stream.lowest_layer().close();
  564. stream.lowest_layer().connect(*endpoint_iterator++, error);
  565. }
  566. if (error)
  567. return false;
  568. return true;
  569. }
  570. private:
  571. bool fNeedHandshake;
  572. bool fUseSSL;
  573. asio::ssl::stream<typename Protocol::socket>& stream;
  574. };
  575. class AcceptedConnection
  576. {
  577. public:
  578. virtual ~AcceptedConnection() {}
  579. virtual std::iostream& stream() = 0;
  580. virtual std::string peer_address_to_string() const = 0;
  581. virtual void close() = 0;
  582. };
  583. template <typename Protocol>
  584. class AcceptedConnectionImpl : public AcceptedConnection
  585. {
  586. public:
  587. AcceptedConnectionImpl(
  588. asio::io_service& io_service,
  589. ssl::context &context,
  590. bool fUseSSL) :
  591. sslStream(io_service, context),
  592. _d(sslStream, fUseSSL),
  593. _stream(_d)
  594. {
  595. }
  596. virtual std::iostream& stream()
  597. {
  598. return _stream;
  599. }
  600. virtual std::string peer_address_to_string() const
  601. {
  602. return peer.address().to_string();
  603. }
  604. virtual void close()
  605. {
  606. _stream.close();
  607. }
  608. typename Protocol::endpoint peer;
  609. asio::ssl::stream<typename Protocol::socket> sslStream;
  610. private:
  611. SSLIOStreamDevice<Protocol> _d;
  612. iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
  613. };
  614. void ServiceConnection(AcceptedConnection *conn);
  615. // Forward declaration required for RPCListen
  616. template <typename Protocol, typename SocketAcceptorService>
  617. static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
  618. ssl::context& context,
  619. bool fUseSSL,
  620. AcceptedConnection* conn,
  621. const boost::system::error_code& error);
  622. /**
  623. * Sets up I/O resources to accept and handle a new connection.
  624. */
  625. template <typename Protocol, typename SocketAcceptorService>
  626. static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
  627. ssl::context& context,
  628. const bool fUseSSL)
  629. {
  630. // Accept connection
  631. AcceptedConnectionImpl<Protocol>* conn = new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL);
  632. acceptor->async_accept(
  633. conn->sslStream.lowest_layer(),
  634. conn->peer,
  635. boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
  636. acceptor,
  637. boost::ref(context),
  638. fUseSSL,
  639. conn,
  640. boost::asio::placeholders::error));
  641. }
  642. /**
  643. * Accept and handle incoming connection.
  644. */
  645. template <typename Protocol, typename SocketAcceptorService>
  646. static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
  647. ssl::context& context,
  648. const bool fUseSSL,
  649. AcceptedConnection* conn,
  650. const boost::system::error_code& error)
  651. {
  652. // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
  653. if (error != asio::error::operation_aborted && acceptor->is_open())
  654. RPCListen(acceptor, context, fUseSSL);
  655. AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn);
  656. // TODO: Actually handle errors
  657. if (error)
  658. {
  659. delete conn;
  660. }
  661. // Restrict callers by IP. It is important to
  662. // do this before starting client thread, to filter out
  663. // certain DoS and misbehaving clients.
  664. else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address()))
  665. {
  666. // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
  667. if (!fUseSSL)
  668. conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush;
  669. delete conn;
  670. }
  671. else {
  672. ServiceConnection(conn);
  673. conn->close();
  674. delete conn;
  675. }
  676. }
  677. void StartRPCThreads()
  678. {
  679. strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
  680. if (((mapArgs["-rpcpassword"] == "") ||
  681. (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
  682. {
  683. unsigned char rand_pwd[32];
  684. RAND_bytes(rand_pwd, 32);
  685. string strWhatAmI = "To use bitcoind";
  686. if (mapArgs.count("-server"))
  687. strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
  688. else if (mapArgs.count("-daemon"))
  689. strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
  690. uiInterface.ThreadSafeMessageBox(strprintf(
  691. _("%s, you must set a rpcpassword in the configuration file:\n"
  692. "%s\n"
  693. "It is recommended you use the following random password:\n"
  694. "rpcuser=bitcoinrpc\n"
  695. "rpcpassword=%s\n"
  696. "(you do not need to remember this password)\n"
  697. "The username and password MUST NOT be the same.\n"
  698. "If the file does not exist, create it with owner-readable-only file permissions.\n"
  699. "It is also recommended to set alertnotify so you are notified of problems;\n"
  700. "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
  701. strWhatAmI.c_str(),
  702. GetConfigFile().string().c_str(),
  703. EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
  704. "", CClientUIInterface::MSG_ERROR);
  705. StartShutdown();
  706. return;
  707. }
  708. assert(rpc_io_service == NULL);
  709. rpc_io_service = new asio::io_service();
  710. rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
  711. const bool fUseSSL = GetBoolArg("-rpcssl", false);
  712. if (fUseSSL)
  713. {
  714. rpc_ssl_context->set_options(ssl::context::no_sslv2);
  715. filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
  716. if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
  717. if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
  718. else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
  719. filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
  720. if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
  721. if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
  722. else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
  723. string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
  724. SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
  725. }
  726. // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets
  727. const bool loopback = !mapArgs.count("-rpcallowip");
  728. asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any();
  729. ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", Params().RPCPort()));
  730. boost::system::error_code v6_only_error;
  731. boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
  732. bool fListening = false;
  733. std::string strerr;
  734. try
  735. {
  736. acceptor->open(endpoint.protocol());
  737. acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
  738. // Try making the socket dual IPv6/IPv4 (if listening on the "any" address)
  739. acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);
  740. acceptor->bind(endpoint);
  741. acceptor->listen(socket_base::max_connections);
  742. RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
  743. fListening = true;
  744. }
  745. catch(boost::system::system_error &e)
  746. {
  747. strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what());
  748. }
  749. try {
  750. // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately
  751. if (!fListening || loopback || v6_only_error)
  752. {
  753. bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any();
  754. endpoint.address(bindAddress);
  755. acceptor.reset(new ip::tcp::acceptor(*rpc_io_service));
  756. acceptor->open(endpoint.protocol());
  757. acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
  758. acceptor->bind(endpoint);
  759. acceptor->listen(socket_base::max_connections);
  760. RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
  761. fListening = true;
  762. }
  763. }
  764. catch(boost::system::system_error &e)
  765. {
  766. strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what());
  767. }
  768. if (!fListening) {
  769. uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
  770. StartShutdown();
  771. return;
  772. }
  773. rpc_worker_group = new boost::thread_group();
  774. for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
  775. rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
  776. }
  777. void StopRPCThreads()
  778. {
  779. if (rpc_io_service == NULL) return;
  780. deadlineTimers.clear();
  781. rpc_io_service->stop();
  782. if (rpc_worker_group != NULL)
  783. rpc_worker_group->join_all();
  784. delete rpc_worker_group; rpc_worker_group = NULL;
  785. delete rpc_ssl_context; rpc_ssl_context = NULL;
  786. delete rpc_io_service; rpc_io_service = NULL;
  787. }
  788. void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
  789. {
  790. if (!err)
  791. func();
  792. }
  793. void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
  794. {
  795. assert(rpc_io_service != NULL);
  796. if (deadlineTimers.count(name) == 0)
  797. {
  798. deadlineTimers.insert(make_pair(name,
  799. boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
  800. }
  801. deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
  802. deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
  803. }
  804. class JSONRequest
  805. {
  806. public:
  807. Value id;
  808. string strMethod;
  809. Array params;
  810. JSONRequest() { id = Value::null; }
  811. void parse(const Value& valRequest);
  812. };
  813. void JSONRequest::parse(const Value& valRequest)
  814. {
  815. // Parse request
  816. if (valRequest.type() != obj_type)
  817. throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
  818. const Object& request = valRequest.get_obj();
  819. // Parse id now so errors from here on will have the id
  820. id = find_value(request, "id");
  821. // Parse method
  822. Value valMethod = find_value(request, "method");
  823. if (valMethod.type() == null_type)
  824. throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
  825. if (valMethod.type() != str_type)
  826. throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
  827. strMethod = valMethod.get_str();
  828. if (strMethod != "getwork" && strMethod != "getblocktemplate")
  829. LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod.c_str());
  830. // Parse params
  831. Value valParams = find_value(request, "params");
  832. if (valParams.type() == array_type)
  833. params = valParams.get_array();
  834. else if (valParams.type() == null_type)
  835. params = Array();
  836. else
  837. throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
  838. }
  839. static Object JSONRPCExecOne(const Value& req)
  840. {
  841. Object rpc_result;
  842. JSONRequest jreq;
  843. try {
  844. jreq.parse(req);
  845. Value result = tableRPC.execute(jreq.strMethod, jreq.params);
  846. rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id);
  847. }
  848. catch (Object& objError)
  849. {
  850. rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id);
  851. }
  852. catch (std::exception& e)
  853. {
  854. rpc_result = JSONRPCReplyObj(Value::null,
  855. JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
  856. }
  857. return rpc_result;
  858. }
  859. static string JSONRPCExecBatch(const Array& vReq)
  860. {
  861. Array ret;
  862. for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
  863. ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
  864. return write_string(Value(ret), false) + "\n";
  865. }
  866. void ServiceConnection(AcceptedConnection *conn)
  867. {
  868. bool fRun = true;
  869. while (fRun)
  870. {
  871. int nProto = 0;
  872. map<string, string> mapHeaders;
  873. string strRequest, strMethod, strURI;
  874. // Read HTTP request line
  875. if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
  876. break;
  877. // Read HTTP message headers and body
  878. ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);
  879. if (strURI != "/") {
  880. conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush;
  881. break;
  882. }
  883. // Check authorization
  884. if (mapHeaders.count("authorization") == 0)
  885. {
  886. conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
  887. break;
  888. }
  889. if (!HTTPAuthorized(mapHeaders))
  890. {
  891. LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string().c_str());
  892. /* Deter brute-forcing short passwords.
  893. If this results in a DoS the user really
  894. shouldn't have their RPC port exposed. */
  895. if (mapArgs["-rpcpassword"].size() < 20)
  896. MilliSleep(250);
  897. conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
  898. break;
  899. }
  900. if (mapHeaders["connection"] == "close")
  901. fRun = false;
  902. JSONRequest jreq;
  903. try
  904. {
  905. // Parse request
  906. Value valRequest;
  907. if (!read_string(strRequest, valRequest))
  908. throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
  909. string strReply;
  910. // singleton request
  911. if (valRequest.type() == obj_type) {
  912. jreq.parse(valRequest);
  913. Value result = tableRPC.execute(jreq.strMethod, jreq.params);
  914. // Send reply
  915. strReply = JSONRPCReply(result, Value::null, jreq.id);
  916. // array of requests
  917. } else if (valRequest.type() == array_type)
  918. strReply = JSONRPCExecBatch(valRequest.get_array());
  919. else
  920. throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
  921. conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
  922. }
  923. catch (Object& objError)
  924. {
  925. ErrorReply(conn->stream(), objError, jreq.id);
  926. break;
  927. }
  928. catch (std::exception& e)
  929. {
  930. ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
  931. break;
  932. }
  933. }
  934. }
  935. json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
  936. {
  937. // Find method
  938. const CRPCCommand *pcmd = tableRPC[strMethod];
  939. if (!pcmd)
  940. throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
  941. if (pcmd->reqWallet && !pwalletMain)
  942. throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
  943. // Observe safe mode
  944. string strWarning = GetWarnings("rpc");
  945. if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
  946. !pcmd->okSafeMode)
  947. throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
  948. try
  949. {
  950. // Execute
  951. Value result;
  952. {
  953. if (pcmd->threadSafe)
  954. result = pcmd->actor(params, false);
  955. else if (!pwalletMain) {
  956. LOCK(cs_main);
  957. result = pcmd->actor(params, false);
  958. } else {
  959. LOCK2(cs_main, pwalletMain->cs_wallet);
  960. result = pcmd->actor(params, false);
  961. }
  962. }
  963. return result;
  964. }
  965. catch (std::exception& e)
  966. {
  967. throw JSONRPCError(RPC_MISC_ERROR, e.what());
  968. }
  969. }
  970. Object CallRPC(const string& strMethod, const Array& params)
  971. {
  972. if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
  973. throw runtime_error(strprintf(
  974. _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
  975. "If the file does not exist, create it with owner-readable-only file permissions."),
  976. GetConfigFile().string().c_str()));
  977. // Connect to localhost
  978. bool fUseSSL = GetBoolArg("-rpcssl", false);
  979. asio::io_service io_service;
  980. ssl::context context(io_service, ssl::context::sslv23);
  981. context.set_options(ssl::context::no_sslv2);
  982. asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
  983. SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
  984. iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
  985. if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(Params().RPCPort()))))
  986. throw runtime_error("couldn't connect to server");
  987. // HTTP basic authentication
  988. string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
  989. map<string, string> mapRequestHeaders;
  990. mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
  991. // Send request
  992. string strRequest = JSONRPCRequest(strMethod, params, 1);
  993. string strPost = HTTPPost(strRequest, mapRequestHeaders);
  994. stream << strPost << std::flush;
  995. // Receive HTTP reply status
  996. int nProto = 0;
  997. int nStatus = ReadHTTPStatus(stream, nProto);
  998. // Receive HTTP reply message headers and body
  999. map<string, string> mapHeaders;
  1000. string strReply;
  1001. ReadHTTPMessage(stream, mapHeaders, strReply, nProto);
  1002. if (nStatus == HTTP_UNAUTHORIZED)
  1003. throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
  1004. else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
  1005. throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
  1006. else if (strReply.empty())
  1007. throw runtime_error("no response from server");
  1008. // Parse reply
  1009. Value valReply;
  1010. if (!read_string(strReply, valReply))
  1011. throw runtime_error("couldn't parse reply from server");
  1012. const Object& reply = valReply.get_obj();
  1013. if (reply.empty())
  1014. throw runtime_error("expected reply to have result, error and id properties");
  1015. return reply;
  1016. }
  1017. template<typename T>
  1018. void ConvertTo(Value& value, bool fAllowNull=false)
  1019. {
  1020. if (fAllowNull && value.type() == null_type)
  1021. return;
  1022. if (value.type() == str_type)
  1023. {
  1024. // reinterpret string as unquoted json value
  1025. Value value2;
  1026. string strJSON = value.get_str();
  1027. if (!read_string(strJSON, value2))
  1028. throw runtime_error(string("Error parsing JSON:")+strJSON);
  1029. ConvertTo<T>(value2, fAllowNull);
  1030. value = value2;
  1031. }
  1032. else
  1033. {
  1034. value = value.get_value<T>();
  1035. }
  1036. }
  1037. // Convert strings to command-specific RPC representation
  1038. Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
  1039. {
  1040. Array params;
  1041. BOOST_FOREACH(const std::string &param, strParams)
  1042. params.push_back(param);
  1043. int n = params.size();
  1044. //
  1045. // Special case non-string parameter types
  1046. //
  1047. if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
  1048. if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
  1049. if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
  1050. if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1051. if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1052. if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1053. if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
  1054. if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
  1055. if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1056. if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1057. if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1058. if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
  1059. if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1060. if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
  1061. if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1062. if (strMethod == "getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1063. if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
  1064. if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
  1065. if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
  1066. if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
  1067. if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1068. if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
  1069. if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1070. if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1071. if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
  1072. if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1073. if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
  1074. if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
  1075. if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1076. if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
  1077. if (strMethod == "createmultisig" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1078. if (strMethod == "createmultisig" && n > 1) ConvertTo<Array>(params[1]);
  1079. if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1080. if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1081. if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
  1082. if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
  1083. if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1084. if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
  1085. if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
  1086. if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
  1087. if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
  1088. if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
  1089. if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1090. if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
  1091. if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
  1092. if (strMethod == "lockunspent" && n > 1) ConvertTo<Array>(params[1]);
  1093. if (strMethod == "importprivkey" && n > 2) ConvertTo<bool>(params[2]);
  1094. if (strMethod == "verifychain" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1095. if (strMethod == "verifychain" && n > 1) ConvertTo<boost::int64_t>(params[1]);
  1096. if (strMethod == "keypoolrefill" && n > 0) ConvertTo<boost::int64_t>(params[0]);
  1097. return params;
  1098. }
  1099. int CommandLineRPC(int argc, char *argv[])
  1100. {
  1101. string strPrint;
  1102. int nRet = 0;
  1103. try
  1104. {
  1105. // Skip switches
  1106. while (argc > 1 && IsSwitchChar(argv[1][0]))
  1107. {
  1108. argc--;
  1109. argv++;
  1110. }
  1111. // Method
  1112. if (argc < 2)
  1113. throw runtime_error("too few parameters");
  1114. string strMethod = argv[1];
  1115. // Parameters default to strings
  1116. std::vector<std::string> strParams(&argv[2], &argv[argc]);
  1117. Array params = RPCConvertValues(strMethod, strParams);
  1118. // Execute
  1119. Object reply = CallRPC(strMethod, params);
  1120. // Parse reply
  1121. const Value& result = find_value(reply, "result");
  1122. const Value& error = find_value(reply, "error");
  1123. if (error.type() != null_type)
  1124. {
  1125. // Error
  1126. strPrint = "error: " + write_string(error, false);
  1127. int code = find_value(error.get_obj(), "code").get_int();
  1128. nRet = abs(code);
  1129. }
  1130. else
  1131. {
  1132. // Result
  1133. if (result.type() == null_type)
  1134. strPrint = "";
  1135. else if (result.type() == str_type)
  1136. strPrint = result.get_str();
  1137. else
  1138. strPrint = write_string(result, true);
  1139. }
  1140. }
  1141. catch (boost::thread_interrupted) {
  1142. throw;
  1143. }
  1144. catch (std::exception& e) {
  1145. strPrint = string("error: ") + e.what();
  1146. nRet = 87;
  1147. }
  1148. catch (...) {
  1149. PrintException(NULL, "CommandLineRPC()");
  1150. }
  1151. if (strPrint != "")
  1152. {
  1153. fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
  1154. }
  1155. return nRet;
  1156. }
  1157. #ifdef TEST
  1158. int main(int argc, char *argv[])
  1159. {
  1160. #ifdef _MSC_VER
  1161. // Turn off Microsoft heap dump noise
  1162. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  1163. _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
  1164. #endif
  1165. setbuf(stdin, NULL);
  1166. setbuf(stdout, NULL);
  1167. setbuf(stderr, NULL);
  1168. try
  1169. {
  1170. if (argc >= 2 && string(argv[1]) == "-server")
  1171. {
  1172. LogPrintf("server ready\n");
  1173. ThreadRPCServer(NULL);
  1174. }
  1175. else
  1176. {
  1177. return CommandLineRPC(argc, argv);
  1178. }
  1179. }
  1180. catch (boost::thread_interrupted) {
  1181. throw;
  1182. }
  1183. catch (std::exception& e) {
  1184. PrintException(&e, "main()");
  1185. } catch (...) {
  1186. PrintException(NULL, "main()");
  1187. }
  1188. return 0;
  1189. }
  1190. #endif
  1191. const CRPCTable tableRPC;