Merge #11683: tests: Remove unused mininode functions {ser,deser}_int_vector(......
[bitcoinplatinum.git] / src / rpc / protocol.cpp
blob4cb28c21042fe48515a66a0440e24403f9d05a4d
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include <rpc/protocol.h>
8 #include <random.h>
9 #include <tinyformat.h>
10 #include <util.h>
11 #include <utilstrencodings.h>
12 #include <utiltime.h>
13 #include <version.h>
15 #include <stdint.h>
16 #include <fstream>
18 /**
19 * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
20 * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
21 * unspecified (HTTP errors and contents of 'error').
23 * 1.0 spec: http://json-rpc.org/wiki/specification
24 * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
27 UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id)
29 UniValue request(UniValue::VOBJ);
30 request.push_back(Pair("method", strMethod));
31 request.push_back(Pair("params", params));
32 request.push_back(Pair("id", id));
33 return request;
36 UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
38 UniValue reply(UniValue::VOBJ);
39 if (!error.isNull())
40 reply.push_back(Pair("result", NullUniValue));
41 else
42 reply.push_back(Pair("result", result));
43 reply.push_back(Pair("error", error));
44 reply.push_back(Pair("id", id));
45 return reply;
48 std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
50 UniValue reply = JSONRPCReplyObj(result, error, id);
51 return reply.write() + "\n";
54 UniValue JSONRPCError(int code, const std::string& message)
56 UniValue error(UniValue::VOBJ);
57 error.push_back(Pair("code", code));
58 error.push_back(Pair("message", message));
59 return error;
62 /** Username used when cookie authentication is in use (arbitrary, only for
63 * recognizability in debugging/logging purposes)
65 static const std::string COOKIEAUTH_USER = "__cookie__";
66 /** Default name for auth cookie file */
67 static const std::string COOKIEAUTH_FILE = ".cookie";
69 /** Get name of RPC authentication cookie file */
70 static fs::path GetAuthCookieFile(bool temp=false)
72 std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE);
73 if (temp) {
74 arg += ".tmp";
76 fs::path path(arg);
77 if (!path.is_complete()) path = GetDataDir() / path;
78 return path;
81 bool GenerateAuthCookie(std::string *cookie_out)
83 const size_t COOKIE_SIZE = 32;
84 unsigned char rand_pwd[COOKIE_SIZE];
85 GetRandBytes(rand_pwd, COOKIE_SIZE);
86 std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE);
88 /** the umask determines what permissions are used to create this file -
89 * these are set to 077 in init.cpp unless overridden with -sysperms.
91 std::ofstream file;
92 fs::path filepath_tmp = GetAuthCookieFile(true);
93 file.open(filepath_tmp.string().c_str());
94 if (!file.is_open()) {
95 LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string());
96 return false;
98 file << cookie;
99 file.close();
101 fs::path filepath = GetAuthCookieFile(false);
102 if (!RenameOver(filepath_tmp, filepath)) {
103 LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string());
104 return false;
106 LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
108 if (cookie_out)
109 *cookie_out = cookie;
110 return true;
113 bool GetAuthCookie(std::string *cookie_out)
115 std::ifstream file;
116 std::string cookie;
117 fs::path filepath = GetAuthCookieFile();
118 file.open(filepath.string().c_str());
119 if (!file.is_open())
120 return false;
121 std::getline(file, cookie);
122 file.close();
124 if (cookie_out)
125 *cookie_out = cookie;
126 return true;
129 void DeleteAuthCookie()
131 try {
132 fs::remove(GetAuthCookieFile());
133 } catch (const fs::filesystem_error& e) {
134 LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what());
138 std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue &in, size_t num)
140 if (!in.isArray()) {
141 throw std::runtime_error("Batch must be an array");
143 std::vector<UniValue> batch(num);
144 for (size_t i=0; i<in.size(); ++i) {
145 const UniValue &rec = in[i];
146 if (!rec.isObject()) {
147 throw std::runtime_error("Batch member must be object");
149 size_t id = rec["id"].get_int();
150 if (id >= num) {
151 throw std::runtime_error("Batch member id larger than size");
153 batch[id] = rec;
155 return batch;