 |
PRCYCoin
2.0.0.7rc1
P2P Digital Currency
|
Go to the documentation of this file.
20 #include <event2/event.h>
21 #include <event2/http.h>
22 #include <event2/buffer.h>
23 #include <event2/keyvalq_struct.h>
26 #define _(x) std::string(x)
29 static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
36 strUsage +=
HelpMessageOpt(
"-conf=<file>",
strprintf(
_(
"Specify configuration file (default: %s)"),
"prcycoin.conf"));
37 strUsage +=
HelpMessageOpt(
"-datadir=<dir>",
_(
"Specify data directory"));
39 strUsage +=
HelpMessageOpt(
"-regtest",
_(
"Enter regression test mode, which uses a special chain in which blocks can be "
40 "solved instantly. This is intended for regression testing tools and app development."));
41 strUsage +=
HelpMessageOpt(
"-rpcconnect=<ip>",
strprintf(
_(
"Send commands to node running on <ip> (default: %s)"),
"127.0.0.1"));
42 strUsage +=
HelpMessageOpt(
"-rpcport=<port>",
strprintf(
_(
"Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 59683, 59685));
43 strUsage +=
HelpMessageOpt(
"-rpcwait",
_(
"Wait for RPC server to start"));
44 strUsage +=
HelpMessageOpt(
"-rpcuser=<user>",
_(
"Username for JSON-RPC connections"));
45 strUsage +=
HelpMessageOpt(
"-rpcpassword=<pw>",
_(
"Password for JSON-RPC connections"));
46 strUsage +=
HelpMessageOpt(
"-rpcclienttimeout=<n>",
strprintf(
_(
"Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
68 static bool AppInitRPC(
int argc,
char* argv[])
75 std::string strUsage =
_(
"PRCY RPC client version") +
" " +
FormatFullVersion() +
"\n";
76 if (!
mapArgs.count(
"-version")) {
77 strUsage +=
"\n" +
_(
"Usage:") +
"\n" +
78 " prcycoin-cli [options] <command> [params] " +
_(
"Send command to PRCY") +
"\n" +
79 " prcycoin-cli [options] help " +
_(
"List commands") +
"\n" +
80 " prcycoin-cli [options] help <command> " +
_(
"Get help for a command") +
"\n";
85 fprintf(stdout,
"%s", strUsage.c_str());
89 fprintf(stderr,
"Error: Specified data directory \"%s\" does not exist.\n",
mapArgs[
"-datadir"].c_str());
94 }
catch (
const std::exception& e) {
95 fprintf(stderr,
"Error reading configuration file: %s\n", e.what());
100 fprintf(stderr,
"Error: Invalid combination of -regtest and -testnet.\n");
105 fprintf(stderr,
"Error: SSL mode for RPC (-rpcssl) is no longer supported.\n");
118 static void http_request_done(
struct evhttp_request *req,
void *ctx)
130 reply->
status = evhttp_request_get_response_code(req);
132 struct evbuffer *buf = evhttp_request_get_input_buffer(req);
135 size_t size = evbuffer_get_length(buf);
136 const char *data = (
const char*)evbuffer_pullup(buf, size);
138 reply->
body = std::string(data, size);
139 evbuffer_drain(buf, size);
145 std::string host =
GetArg(
"-rpcconnect",
"127.0.0.1");
149 struct event_base *base = event_base_new();
151 throw std::runtime_error(
"cannot create event_base");
154 struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port);
156 throw std::runtime_error(
"create connection failed");
157 evhttp_connection_set_timeout(evcon,
GetArg(
"-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT));
160 struct evhttp_request *req = evhttp_request_new(http_request_done, (
void*)&response);
162 throw std::runtime_error(
"create http request failed");
165 std::string strRPCUserColonPass;
166 if (
mapArgs[
"-rpcpassword"] ==
"") {
170 _(
"Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"),
175 strRPCUserColonPass =
mapArgs[
"-rpcuser"] +
":" +
mapArgs[
"-rpcpassword"];
178 struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req);
179 assert(output_headers);
180 evhttp_add_header(output_headers,
"Host", host.c_str());
181 evhttp_add_header(output_headers,
"Connection",
"close");
182 evhttp_add_header(output_headers,
"Content-Type",
"application/json");
183 evhttp_add_header(output_headers,
"Authorization", (std::string(
"Basic ") +
EncodeBase64(strRPCUserColonPass)).c_str());
187 struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req);
188 assert(output_buffer);
189 evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
191 int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST,
"/");
193 evhttp_connection_free(evcon);
194 event_base_free(base);
198 event_base_dispatch(base);
199 evhttp_connection_free(evcon);
200 event_base_free(base);
202 if (response.status == 0)
205 throw std::runtime_error(
"incorrect rpcuser or rpcpassword (authorization failed)");
207 throw std::runtime_error(
strprintf(
"server returned HTTP error %d", response.status));
208 else if (response.body.empty())
209 throw std::runtime_error(
"no response from server");
213 if (!valReply.
read(response.body))
214 throw std::runtime_error(
"couldn't parse reply from server");
217 throw std::runtime_error(
"expected reply to have result, error and id properties");
224 std::string strPrint;
235 throw std::runtime_error(
"too few parameters");
236 std::string strMethod = argv[1];
239 std::vector<std::string> strParams(&argv[2], &argv[argc]);
243 const bool fWait =
GetBoolArg(
"-rpcwait",
false);
252 if (!
error.isNull()) {
254 int code =
error[
"code"].get_int();
257 strPrint =
"error: " +
error.write();
263 else if (result.
isStr())
266 strPrint = result.
write(2);
277 }
catch (
const boost::thread_interrupted&) {
279 }
catch (
const std::exception& e) {
280 strPrint = std::string(
"error: ") + e.what();
287 if (strPrint !=
"") {
288 fprintf((nRet == 0 ? stdout : stderr),
"%s\n", strPrint.c_str());
293 int main(
int argc,
char* argv[])
297 fprintf(stderr,
"Error: Initializing networking failed\n");
302 if (!AppInitRPC(argc, argv))
304 }
catch (
const std::exception& e) {
312 int ret = EXIT_FAILURE;
315 }
catch (
const std::exception& e) {
Reply structure for request_done to fill in.
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
void ReadConfigFile(std::map< std::string, std::string > &mapSettingsRet, std::map< std::string, std::vector< std::string > > &mapMultiSettingsRet)
bool SelectBaseParamsFromCommandLine()
Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate.
std::map< std::string, std::string > mapArgs
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
int CommandLineRPC(int argc, char *argv[])
bool read(const char *raw, size_t len)
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert strings to command-specific RPC representation.
CConnectionFailed(const std::string &msg)
bool IsSwitchChar(char c)
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
void const uint64_t uint64_t * r
const std::string & get_str() const
const UniValue & get_obj() const
std::string HelpMessageCli()
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
@ RPC_IN_WARMUP
Transaction already in chain.
std::string EncodeBase64(const unsigned char *pch, size_t len)
std::string JSONRPCRequest(const std::string &strMethod, const UniValue ¶ms, const UniValue &id)
JSON-RPC protocol.
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
void ParseParameters(int argc, const char *const argv[])
const fs::path & GetDataDir(bool fNetSpecific)
void MilliSleep(int64_t n)
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
const UniValue & find_value(const UniValue &obj, const std::string &name)
std::string FormatFullVersion()
UniValue CallRPC(const std::string &strMethod, const UniValue ¶ms)
std::map< std::string, std::vector< std::string > > mapMultiArgs
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
int main(int argc, char *argv[])
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool error(const char *fmt, const Args &... args)
@ HTTP_INTERNAL_SERVER_ERROR