2013-10-11 14:09:59 -07:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2014-12-16 17:47:57 -08:00
// Copyright (c) 2009-2013 The Bitcoin Core developers
2023-01-23 10:31:54 -08:00
// Copyright (c) 2016-2023 The Zcash developers
2014-12-12 20:09:33 -08:00
// Distributed under the MIT software license, see the accompanying
2019-07-18 07:16:09 -07:00
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
2013-10-11 14:09:59 -07:00
2014-09-14 03:43:56 -07:00
# include "chainparamsbase.h"
2014-10-28 18:33:23 -07:00
# include "clientversion.h"
2017-03-01 07:54:22 -08:00
# include "fs.h"
2016-01-14 16:55:17 -08:00
# include "rpc/client.h"
# include "rpc/protocol.h"
2018-10-22 15:51:11 -07:00
# include "util/system.h"
# include "util/strencodings.h"
2013-10-11 14:09:59 -07:00
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
# include <stdio.h>
# include <event2/buffer.h>
# include <event2/keyvalq_struct.h>
2016-12-20 03:46:11 -08:00
# include "support/events.h"
2013-04-12 22:13:08 -07:00
2015-09-04 07:11:34 -07:00
# include <univalue.h>
2015-05-18 05:02:18 -07:00
2020-12-30 07:02:57 -08:00
# ifdef WIN32
# include <windows.h>
# else
# include <termios.h>
# include <unistd.h>
2021-01-01 11:49:13 -08:00
# include <cerrno>
2020-12-30 07:02:57 -08:00
# endif
2018-08-13 13:13:29 -07:00
const std : : function < std : : string ( const char * ) > G_TRANSLATION_FUN = nullptr ;
2015-06-27 12:21:41 -07:00
static const char DEFAULT_RPCCONNECT [ ] = " 127.0.0.1 " ;
2015-09-18 06:45:38 -07:00
static const int DEFAULT_HTTP_CLIENT_TIMEOUT = 900 ;
2016-11-02 11:59:09 -07:00
static const int CONTINUE_EXECUTION = - 1 ;
2015-09-18 06:45:38 -07:00
2014-05-26 02:38:44 -07:00
std : : string HelpMessageCli ( )
{
2016-11-25 00:17:57 -08:00
std : : string strUsage ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageGroup ( _ ( " Options: " ) ) ;
strUsage + = HelpMessageOpt ( " -? " , _ ( " This help message " ) ) ;
2018-02-05 14:46:06 -08:00
strUsage + = HelpMessageOpt ( " -conf=<file> " , strprintf ( _ ( " Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s) " ) , BITCOIN_CONF_FILENAME ) ) ;
2022-03-11 10:35:52 -08:00
strUsage + = HelpMessageOpt ( " -datadir=<dir> " , _ ( " Specify data directory (this path cannot use '~') " ) ) ;
2020-12-30 07:02:57 -08:00
strUsage + = HelpMessageOpt ( " -stdin " , _ ( " Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). If first extra argument is `walletpassphrase` then the first line(password) will not be echoed. " ) ) ;
2015-05-25 00:00:17 -07:00
AppendParamsHelpMessages ( strUsage ) ;
2015-06-27 12:21:41 -07:00
strUsage + = HelpMessageOpt ( " -rpcconnect=<ip> " , strprintf ( _ ( " Send commands to node running on <ip> (default: %s) " ) , DEFAULT_RPCCONNECT ) ) ;
2016-06-15 19:14:27 -07:00
strUsage + = HelpMessageOpt ( " -rpcport=<port> " , strprintf ( _ ( " Connect to JSON-RPC on <port> (default: %u or testnet: %u) " ) , 8232 , 18232 ) ) ;
2015-02-04 00:11:49 -08:00
strUsage + = HelpMessageOpt ( " -rpcwait " , _ ( " Wait for RPC server to start " ) ) ;
strUsage + = HelpMessageOpt ( " -rpcuser=<user> " , _ ( " Username for JSON-RPC connections " ) ) ;
strUsage + = HelpMessageOpt ( " -rpcpassword=<pw> " , _ ( " Password for JSON-RPC connections " ) ) ;
2017-03-02 04:42:37 -08:00
strUsage + = HelpMessageOpt ( " -rpcclienttimeout=<n> " , strprintf ( _ ( " Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d) " ) , DEFAULT_HTTP_CLIENT_TIMEOUT ) ) ;
2014-05-26 02:38:44 -07:00
return strUsage ;
}
2013-10-11 14:09:59 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// Start
//
2014-10-29 10:08:31 -07:00
//
// Exception thrown on connection error. This error is used to determine
// when to wait if -rpcwait is given.
//
class CConnectionFailed : public std : : runtime_error
{
public :
explicit inline CConnectionFailed ( const std : : string & msg ) :
std : : runtime_error ( msg )
{ }
} ;
2016-11-02 11:59:09 -07:00
//
// This function returns either one of EXIT_ codes when it's expected to stop the process or
// CONTINUE_EXECUTION when it's expected to continue further.
//
static int AppInitRPC ( int argc , char * argv [ ] )
2013-10-11 14:09:59 -07:00
{
2018-04-12 17:11:46 -07:00
static_assert ( CONTINUE_EXECUTION ! = EXIT_FAILURE ,
" CONTINUE_EXECUTION should be different from EXIT_FAILURE " ) ;
static_assert ( CONTINUE_EXECUTION ! = EXIT_SUCCESS ,
" CONTINUE_EXECUTION should be different from EXIT_SUCCESS " ) ;
2013-10-11 14:09:59 -07:00
//
// Parameters
//
ParseParameters ( argc , argv ) ;
2015-10-18 03:02:36 -07:00
if ( argc < 2 | | mapArgs . count ( " -? " ) | | mapArgs . count ( " -h " ) | | mapArgs . count ( " -help " ) | | mapArgs . count ( " -version " ) ) {
2017-03-25 18:08:29 -07:00
std : : string strUsage = _ ( " Zcash RPC client version " ) + " " + FormatFullVersion ( ) + " \n " + PrivacyInfo ( ) ;
2014-11-22 10:56:25 -08:00
if ( ! mapArgs . count ( " -version " ) ) {
strUsage + = " \n " + _ ( " Usage: " ) + " \n " +
2016-05-17 22:23:47 -07:00
" zcash-cli [options] <command> [params] " + _ ( " Send command to Zcash " ) + " \n " +
" zcash-cli [options] help " + _ ( " List commands " ) + " \n " +
" zcash-cli [options] help <command> " + _ ( " Get help for a command " ) + " \n " ;
2014-11-22 10:56:25 -08:00
strUsage + = " \n " + HelpMessageCli ( ) ;
2017-01-09 23:17:48 -08:00
} else {
strUsage + = LicenseInfo ( ) ;
2014-11-22 10:56:25 -08:00
}
fprintf ( stdout , " %s " , strUsage . c_str ( ) ) ;
2016-11-02 11:59:09 -07:00
if ( argc < 2 ) {
fprintf ( stderr , " Error: too few parameters \n " ) ;
return EXIT_FAILURE ;
}
return EXIT_SUCCESS ;
2014-11-22 10:56:25 -08:00
}
2017-03-01 08:05:50 -08:00
if ( ! fs : : is_directory ( GetDataDir ( false ) ) ) {
2013-10-11 14:09:59 -07:00
fprintf ( stderr , " Error: Specified data directory \" %s \" does not exist. \n " , mapArgs [ " -datadir " ] . c_str ( ) ) ;
2016-11-02 11:59:09 -07:00
return EXIT_FAILURE ;
2013-10-11 14:09:59 -07:00
}
2014-04-07 01:10:01 -07:00
try {
2016-09-28 01:10:15 -07:00
ReadConfigFile ( GetArg ( " -conf " , BITCOIN_CONF_FILENAME ) , mapArgs , mapMultiArgs ) ;
2014-12-07 04:29:06 -08:00
} catch ( const std : : exception & e ) {
2014-04-07 01:10:01 -07:00
fprintf ( stderr , " Error reading configuration file: %s \n " , e . what ( ) ) ;
2016-11-02 11:59:09 -07:00
return EXIT_FAILURE ;
2014-04-07 01:10:01 -07:00
}
2014-06-19 06:10:04 -07:00
// Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
2015-05-25 00:00:17 -07:00
try {
SelectBaseParams ( ChainNameFromCommandLine ( ) ) ;
} catch ( std : : exception & e ) {
fprintf ( stderr , " Error: %s \n " , e . what ( ) ) ;
2016-11-02 11:59:09 -07:00
return EXIT_FAILURE ;
2013-11-28 08:28:27 -08:00
}
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( GetBoolArg ( " -rpcssl " , false ) )
{
fprintf ( stderr , " Error: SSL mode for RPC (-rpcssl) is no longer supported. \n " ) ;
2016-11-02 11:59:09 -07:00
return EXIT_FAILURE ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
}
2016-11-02 11:59:09 -07:00
return CONTINUE_EXECUTION ;
2013-10-11 14:09:59 -07:00
}
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
/** Reply structure for request_done to fill in */
struct HTTPReply
2014-05-26 02:38:44 -07:00
{
2016-09-14 06:08:34 -07:00
HTTPReply ( ) : status ( 0 ) , error ( - 1 ) { }
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
int status ;
2016-09-14 06:08:34 -07:00
int error ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
std : : string body ;
} ;
2016-09-14 06:08:34 -07:00
const char * http_errorstring ( int code )
{
switch ( code ) {
# if LIBEVENT_VERSION_NUMBER >= 0x02010300
case EVREQ_HTTP_TIMEOUT :
return " timeout reached " ;
case EVREQ_HTTP_EOF :
return " EOF reached " ;
case EVREQ_HTTP_INVALID_HEADER :
return " error while reading header, or invalid header " ;
case EVREQ_HTTP_BUFFER_ERROR :
return " error encountered while reading or writing " ;
case EVREQ_HTTP_REQUEST_CANCEL :
return " request was canceled " ;
case EVREQ_HTTP_DATA_TOO_LONG :
return " response body is larger than allowed " ;
# endif
default :
return " unknown " ;
}
}
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
static void http_request_done ( struct evhttp_request * req , void * ctx )
{
HTTPReply * reply = static_cast < HTTPReply * > ( ctx ) ;
if ( req = = NULL ) {
2016-09-14 06:08:34 -07:00
/* If req is NULL, it means an error occurred while connecting: the
* error code will have been passed to http_error_cb .
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
*/
reply - > status = 0 ;
return ;
}
2014-05-26 02:38:44 -07:00
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
reply - > status = evhttp_request_get_response_code ( req ) ;
struct evbuffer * buf = evhttp_request_get_input_buffer ( req ) ;
if ( buf )
{
size_t size = evbuffer_get_length ( buf ) ;
const char * data = ( const char * ) evbuffer_pullup ( buf , size ) ;
if ( data )
reply - > body = std : : string ( data , size ) ;
evbuffer_drain ( buf , size ) ;
}
}
2016-09-14 06:08:34 -07:00
# if LIBEVENT_VERSION_NUMBER >= 0x02010300
static void http_error_cb ( enum evhttp_request_error err , void * ctx )
{
HTTPReply * reply = static_cast < HTTPReply * > ( ctx ) ;
reply - > error = err ;
}
# endif
2016-11-25 00:17:57 -08:00
UniValue CallRPC ( const std : : string & strMethod , const UniValue & params )
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
{
2015-06-27 12:21:41 -07:00
std : : string host = GetArg ( " -rpcconnect " , DEFAULT_RPCCONNECT ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
int port = GetArg ( " -rpcport " , BaseParams ( ) . RPCPort ( ) ) ;
2016-12-20 03:46:11 -08:00
// Obtain event base
raii_event_base base = obtain_event_base ( ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
// Synchronously look up hostname
2016-12-20 03:46:11 -08:00
raii_evhttp_connection evcon = obtain_evhttp_connection_base ( base . get ( ) , host , port ) ;
evhttp_connection_set_timeout ( evcon . get ( ) , GetArg ( " -rpcclienttimeout " , DEFAULT_HTTP_CLIENT_TIMEOUT ) ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
HTTPReply response ;
2016-12-20 03:46:11 -08:00
raii_evhttp_request req = obtain_evhttp_request ( http_request_done , ( void * ) & response ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( req = = NULL )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " create http request failed " ) ;
2016-09-14 06:08:34 -07:00
# if LIBEVENT_VERSION_NUMBER >= 0x02010300
2016-12-20 03:46:11 -08:00
evhttp_request_set_error_cb ( req . get ( ) , http_error_cb ) ;
2016-09-14 06:08:34 -07:00
# endif
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
// Get credentials
2015-07-07 05:53:48 -07:00
std : : string strRPCUserColonPass ;
if ( mapArgs [ " -rpcpassword " ] = = " " ) {
// Try fall back to cookie-based authentication if no password is provided
if ( ! GetAuthCookie ( & strRPCUserColonPass ) ) {
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( strprintf (
2017-03-24 21:39:56 -07:00
_ ( " Could not locate RPC credentials. No authentication cookie could be found, \n "
" and no rpcpassword is set in the configuration file (%s). " ) ,
2016-09-28 01:10:15 -07:00
GetConfigFile ( GetArg ( " -conf " , BITCOIN_CONF_FILENAME ) ) . string ( ) . c_str ( ) ) ) ;
2015-07-07 05:53:48 -07:00
}
} else {
strRPCUserColonPass = mapArgs [ " -rpcuser " ] + " : " + mapArgs [ " -rpcpassword " ] ;
}
2016-12-20 03:46:11 -08:00
struct evkeyvalq * output_headers = evhttp_request_get_output_headers ( req . get ( ) ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
assert ( output_headers ) ;
evhttp_add_header ( output_headers , " Host " , host . c_str ( ) ) ;
evhttp_add_header ( output_headers , " Connection " , " close " ) ;
evhttp_add_header ( output_headers , " Authorization " , ( std : : string ( " Basic " ) + EncodeBase64 ( strRPCUserColonPass ) ) . c_str ( ) ) ;
// Attach request data
std : : string strRequest = JSONRPCRequest ( strMethod , params , 1 ) ;
2016-12-20 03:46:11 -08:00
struct evbuffer * output_buffer = evhttp_request_get_output_buffer ( req . get ( ) ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
assert ( output_buffer ) ;
evbuffer_add ( output_buffer , strRequest . data ( ) , strRequest . size ( ) ) ;
2016-12-20 03:46:11 -08:00
int r = evhttp_make_request ( evcon . get ( ) , req . get ( ) , EVHTTP_REQ_POST , " / " ) ;
req . release ( ) ; // ownership moved to evcon in above call
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( r ! = 0 ) {
throw CConnectionFailed ( " send http request failed " ) ;
}
2014-05-26 02:38:44 -07:00
2016-12-20 03:46:11 -08:00
event_base_dispatch ( base . get ( ) ) ;
2014-05-26 02:38:44 -07:00
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( response . status = = 0 )
2016-12-01 23:51:36 -08:00
throw CConnectionFailed ( strprintf ( " couldn't connect to server: %s (code %d) \ n ( make sure server is running and you are connecting to the correct RPC port ) " , http_errorstring(response.error), response.error)) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
else if ( response . status = = HTTP_UNAUTHORIZED )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " incorrect rpcuser or rpcpassword (authorization failed) " ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
else if ( response . status > = 400 & & response . status ! = HTTP_BAD_REQUEST & & response . status ! = HTTP_NOT_FOUND & & response . status ! = HTTP_INTERNAL_SERVER_ERROR )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( strprintf ( " server returned HTTP error %d " , response . status ) ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
else if ( response . body . empty ( ) )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " no response from server " ) ;
2014-05-26 02:38:44 -07:00
// Parse reply
2015-05-13 12:29:19 -07:00
UniValue valReply ( UniValue : : VSTR ) ;
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-22 22:53:17 -08:00
if ( ! valReply . read ( response . body ) )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " couldn't parse reply from server " ) ;
2015-05-18 05:02:18 -07:00
const UniValue & reply = valReply . get_obj ( ) ;
2014-05-26 02:38:44 -07:00
if ( reply . empty ( ) )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " expected reply to have result, error and id properties " ) ;
2014-05-26 02:38:44 -07:00
return reply ;
}
2021-01-01 11:49:13 -08:00
bool SetStdinEcho ( bool enable = true )
2020-12-30 07:02:57 -08:00
{
# ifdef WIN32
HANDLE hStdin = GetStdHandle ( STD_INPUT_HANDLE ) ;
2021-01-01 11:49:13 -08:00
if ( hStdin = = INVALID_HANDLE_VALUE | | hStdin = = NULL ) return false ;
2020-12-30 07:02:57 -08:00
DWORD mode ;
2021-01-01 11:49:13 -08:00
// if it's not a terminal then stdin won't be echoed, so that's not an error
DWORD dwStdinType = GetFileType ( hStdin ) & ~ FILE_TYPE_REMOTE ;
bool could_be_terminal = dwStdinType = = FILE_TYPE_CHAR | |
( dwStdinType = = FILE_TYPE_UNKNOWN & & GetLastError ( ) = = NO_ERROR ) ;
if ( ! could_be_terminal | | GetConsoleMode ( hStdin , & mode ) = = 0 ) return true ;
2020-12-30 07:02:57 -08:00
if ( ! enable )
mode & = ~ ENABLE_ECHO_INPUT ;
else
mode | = ENABLE_ECHO_INPUT ;
2021-01-01 11:49:13 -08:00
if ( SetConsoleMode ( hStdin , mode ) = = 0 ) return false ;
2020-12-30 07:02:57 -08:00
# else
struct termios tty ;
2021-01-01 11:49:13 -08:00
if ( tcgetattr ( STDIN_FILENO , & tty ) ! = 0 ) {
// if it's not a terminal then stdin won't be echoed, so that's not an error
return errno = = ENOTTY ;
}
2020-12-30 07:02:57 -08:00
if ( ! enable )
tty . c_lflag & = ~ ECHO ;
else
tty . c_lflag | = ECHO ;
2021-01-01 11:49:13 -08:00
if ( tcsetattr ( STDIN_FILENO , TCSANOW , & tty ) ! = 0 ) return false ;
2020-12-30 07:02:57 -08:00
# endif
2021-01-01 11:49:13 -08:00
return true ;
2020-12-30 07:02:57 -08:00
}
2014-05-26 02:38:44 -07:00
int CommandLineRPC ( int argc , char * argv [ ] )
{
2016-11-25 00:17:57 -08:00
std : : string strPrint ;
2014-05-26 02:38:44 -07:00
int nRet = 0 ;
2014-06-25 18:09:36 -07:00
try {
2014-05-26 02:38:44 -07:00
// Skip switches
2014-06-25 18:09:36 -07:00
while ( argc > 1 & & IsSwitchChar ( argv [ 1 ] [ 0 ] ) ) {
2014-05-26 02:38:44 -07:00
argc - - ;
argv + + ;
}
2016-02-17 06:03:38 -08:00
std : : vector < std : : string > args = std : : vector < std : : string > ( & argv [ 1 ] , & argv [ argc ] ) ;
if ( GetBoolArg ( " -stdin " , false ) ) {
2020-12-30 07:02:57 -08:00
bool hide = false ;
2021-01-01 11:49:13 -08:00
if ( args . size ( ) > 0 & & args [ 0 ] = = " walletpassphrase " ) {
if ( ! SetStdinEcho ( false ) )
throw std : : runtime_error ( " unable to set terminal to non-echoing " ) ;
2020-12-30 07:02:57 -08:00
hide = true ;
}
2016-02-17 06:03:38 -08:00
// Read one arg per line from stdin and append
std : : string line ;
2020-12-30 07:02:57 -08:00
while ( std : : getline ( std : : cin , line ) ) {
2016-02-17 06:03:38 -08:00
args . push_back ( line ) ;
2020-12-30 07:02:57 -08:00
if ( hide ) {
2021-01-01 11:49:13 -08:00
if ( ! SetStdinEcho ( true ) )
throw std : : runtime_error ( " unable to set terminal back to echoing " ) ;
2020-12-30 07:02:57 -08:00
hide = false ;
}
}
2016-02-17 06:03:38 -08:00
}
if ( args . size ( ) < 1 )
2016-11-25 00:17:57 -08:00
throw std : : runtime_error ( " too few parameters (need at least command) " ) ;
2016-02-17 06:03:38 -08:00
std : : string strMethod = args [ 0 ] ;
UniValue params = RPCConvertValues ( strMethod , std : : vector < std : : string > ( args . begin ( ) + 1 , args . end ( ) ) ) ;
2014-05-26 02:38:44 -07:00
2014-10-29 10:08:31 -07:00
// Execute and handle connection failures with -rpcwait
const bool fWait = GetBoolArg ( " -rpcwait " , false ) ;
do {
try {
2015-05-13 12:29:19 -07:00
const UniValue reply = CallRPC ( strMethod , params ) ;
2014-10-29 10:08:31 -07:00
// Parse reply
2015-05-18 05:02:18 -07:00
const UniValue & result = find_value ( reply , " result " ) ;
const UniValue & error = find_value ( reply , " error " ) ;
2014-10-29 10:08:31 -07:00
2014-08-20 12:15:16 -07:00
if ( ! error . isNull ( ) ) {
2014-10-29 10:08:31 -07:00
// Error
2014-08-20 12:15:16 -07:00
int code = error [ " code " ] . get_int ( ) ;
2015-05-18 05:02:18 -07:00
if ( fWait & & code = = RPC_IN_WARMUP )
throw CConnectionFailed ( " server in warmup " ) ;
strPrint = " error: " + error . write ( ) ;
2014-10-29 10:08:31 -07:00
nRet = abs ( code ) ;
2015-07-07 03:15:44 -07:00
if ( error . isObject ( ) )
{
UniValue errCode = find_value ( error , " code " ) ;
UniValue errMsg = find_value ( error , " message " ) ;
strPrint = errCode . isNull ( ) ? " " : " error code: " + errCode . getValStr ( ) + " \n " ;
if ( errMsg . isStr ( ) )
strPrint + = " error message: \n " + errMsg . get_str ( ) ;
}
2014-10-29 10:08:31 -07:00
} else {
// Result
2014-08-20 12:15:16 -07:00
if ( result . isNull ( ) )
2014-10-29 10:08:31 -07:00
strPrint = " " ;
2014-08-20 12:15:16 -07:00
else if ( result . isStr ( ) )
2014-10-29 10:08:31 -07:00
strPrint = result . get_str ( ) ;
else
2014-08-20 12:15:16 -07:00
strPrint = result . write ( 2 ) ;
2014-10-29 10:08:31 -07:00
}
// Connection succeeded, no need to retry.
break ;
}
2014-12-07 04:29:06 -08:00
catch ( const CConnectionFailed & ) {
2014-10-29 10:08:31 -07:00
if ( fWait )
MilliSleep ( 1000 ) ;
else
throw ;
}
} while ( fWait ) ;
2014-05-26 02:38:44 -07:00
}
2014-12-07 04:29:06 -08:00
catch ( const std : : exception & e ) {
2016-11-25 00:17:57 -08:00
strPrint = std : : string ( " error: " ) + e . what ( ) ;
2014-05-26 02:38:44 -07:00
nRet = EXIT_FAILURE ;
}
catch ( . . . ) {
PrintExceptionContinue ( NULL , " CommandLineRPC() " ) ;
throw ;
}
2014-06-25 18:09:36 -07:00
if ( strPrint ! = " " ) {
2014-05-26 02:38:44 -07:00
fprintf ( ( nRet = = 0 ? stdout : stderr ) , " %s \n " , strPrint . c_str ( ) ) ;
}
return nRet ;
}
2013-10-11 14:09:59 -07:00
int main ( int argc , char * argv [ ] )
{
2014-05-13 03:15:00 -07:00
SetupEnvironment ( ) ;
2015-09-02 07:18:16 -07:00
if ( ! SetupNetworking ( ) ) {
fprintf ( stderr , " Error: Initializing networking failed \n " ) ;
2016-05-02 09:48:04 -07:00
return EXIT_FAILURE ;
2015-09-02 07:18:16 -07:00
}
2014-05-13 03:15:00 -07:00
2014-06-25 18:09:36 -07:00
try {
2016-11-02 11:59:09 -07:00
int ret = AppInitRPC ( argc , argv ) ;
if ( ret ! = CONTINUE_EXECUTION )
return ret ;
2013-10-11 14:09:59 -07:00
}
2014-12-07 04:29:06 -08:00
catch ( const std : : exception & e ) {
2013-10-11 14:09:59 -07:00
PrintExceptionContinue ( & e , " AppInitRPC() " ) ;
2014-06-12 19:26:46 -07:00
return EXIT_FAILURE ;
2013-10-11 14:09:59 -07:00
} catch ( . . . ) {
PrintExceptionContinue ( NULL , " AppInitRPC() " ) ;
2014-06-12 19:26:46 -07:00
return EXIT_FAILURE ;
2013-10-11 14:09:59 -07:00
}
2014-06-12 19:26:46 -07:00
int ret = EXIT_FAILURE ;
2014-06-25 18:09:36 -07:00
try {
2014-02-24 05:08:56 -08:00
ret = CommandLineRPC ( argc , argv ) ;
2013-10-11 14:09:59 -07:00
}
2014-12-07 04:29:06 -08:00
catch ( const std : : exception & e ) {
2013-10-11 14:09:59 -07:00
PrintExceptionContinue ( & e , " CommandLineRPC() " ) ;
} catch ( . . . ) {
PrintExceptionContinue ( NULL , " CommandLineRPC() " ) ;
}
2014-02-24 05:08:56 -08:00
return ret ;
2013-10-11 14:09:59 -07:00
}