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-23 07:53:17 +01:00
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "httpserver.h"
# include "chainparamsbase.h"
# include "compat.h"
# include "util.h"
# include "netbase.h"
2016-01-15 01:55:17 +01:00
# include "rpc/protocol.h" // For HTTP status codes
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-23 07:53:17 +01:00
# include "sync.h"
# include "ui_interface.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <signal.h>
# include <event2/event.h>
# include <event2/http.h>
# include <event2/thread.h>
# include <event2/buffer.h>
# include <event2/util.h>
# include <event2/keyvalq_struct.h>
# ifdef EVENT__HAVE_NETINET_IN_H
# include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
# include <arpa/inet.h>
# endif
# endif
# include <boost/algorithm/string/case_conv.hpp> // for to_lower()
# include <boost/foreach.hpp>
# include <boost/scoped_ptr.hpp>
2015-10-20 11:35:10 +02:00
/** Maximum size of http request (request line + headers) */
static const size_t MAX_HEADERS_SIZE = 8192 ;
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-23 07:53:17 +01:00
/** HTTP request work item */
class HTTPWorkItem : public HTTPClosure
{
public :
HTTPWorkItem ( HTTPRequest * req , const std : : string & path , const HTTPRequestHandler & func ) :
req ( req ) , path ( path ) , func ( func )
{
}
void operator ( ) ( )
{
func ( req . get ( ) , path ) ;
}
boost : : scoped_ptr < HTTPRequest > req ;
private :
std : : string path ;
HTTPRequestHandler func ;
} ;
/** Simple work queue for distributing work over multiple threads.
* Work items are simply callable objects .
*/
template < typename WorkItem >
class WorkQueue
{
private :
/** Mutex protects entire object */
CWaitableCriticalSection cs ;
CConditionVariable cond ;
/* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */
std : : deque < WorkItem * > queue ;
bool running ;
size_t maxDepth ;
2015-09-25 13:49:08 +02:00
int numThreads ;
/** RAII object to keep track of number of running worker threads */
class ThreadCounter
{
public :
WorkQueue & wq ;
ThreadCounter ( WorkQueue & w ) : wq ( w )
{
boost : : lock_guard < boost : : mutex > lock ( wq . cs ) ;
wq . numThreads + = 1 ;
}
~ ThreadCounter ( )
{
boost : : lock_guard < boost : : mutex > lock ( wq . cs ) ;
wq . numThreads - = 1 ;
wq . cond . notify_all ( ) ;
}
} ;
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-23 07:53:17 +01:00
public :
WorkQueue ( size_t maxDepth ) : running ( true ) ,
2015-09-25 13:49:08 +02:00
maxDepth ( maxDepth ) ,
numThreads ( 0 )
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-23 07:53:17 +01:00
{
}
2015-09-25 13:49:08 +02:00
/*( Precondition: worker threads have all stopped
* ( call WaitExit )
*/
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-23 07:53:17 +01:00
~ WorkQueue ( )
{
while ( ! queue . empty ( ) ) {
delete queue . front ( ) ;
queue . pop_front ( ) ;
}
}
/** Enqueue a work item */
bool Enqueue ( WorkItem * item )
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
if ( queue . size ( ) > = maxDepth ) {
return false ;
}
queue . push_back ( item ) ;
cond . notify_one ( ) ;
return true ;
}
/** Thread function */
void Run ( )
{
2015-09-25 13:49:08 +02:00
ThreadCounter count ( * this ) ;
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-23 07:53:17 +01:00
while ( running ) {
WorkItem * i = 0 ;
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
while ( running & & queue . empty ( ) )
cond . wait ( lock ) ;
if ( ! running )
break ;
i = queue . front ( ) ;
queue . pop_front ( ) ;
}
( * i ) ( ) ;
delete i ;
}
}
/** Interrupt and exit loops */
void Interrupt ( )
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
running = false ;
cond . notify_all ( ) ;
}
2015-09-25 13:49:08 +02:00
/** Wait for worker threads to exit */
void WaitExit ( )
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
while ( numThreads > 0 )
cond . wait ( lock ) ;
}
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-23 07:53:17 +01:00
/** Return current depth of queue */
size_t Depth ( )
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
return queue . size ( ) ;
}
} ;
struct HTTPPathHandler
{
HTTPPathHandler ( ) { }
HTTPPathHandler ( std : : string prefix , bool exactMatch , HTTPRequestHandler handler ) :
prefix ( prefix ) , exactMatch ( exactMatch ) , handler ( handler )
{
}
std : : string prefix ;
bool exactMatch ;
HTTPRequestHandler handler ;
} ;
/** HTTP module state */
//! libevent event loop
static struct event_base * eventBase = 0 ;
//! HTTP server
struct evhttp * eventHTTP = 0 ;
//! List of subnets to allow RPC connections from
static std : : vector < CSubNet > rpc_allow_subnets ;
//! Work queue for handling longer requests off the event loop thread
static WorkQueue < HTTPClosure > * workQueue = 0 ;
//! Handlers for (sub)paths
std : : vector < HTTPPathHandler > pathHandlers ;
2015-09-24 17:29:22 +02:00
//! Bound listening sockets
std : : vector < evhttp_bound_socket * > boundSockets ;
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-23 07:53:17 +01:00
/** Check if a network address is allowed to access the HTTP server */
static bool ClientAllowed ( const CNetAddr & netaddr )
{
if ( ! netaddr . IsValid ( ) )
return false ;
BOOST_FOREACH ( const CSubNet & subnet , rpc_allow_subnets )
if ( subnet . Match ( netaddr ) )
return true ;
return false ;
}
/** Initialize ACL list for HTTP server */
static bool InitHTTPAllowList ( )
{
rpc_allow_subnets . clear ( ) ;
rpc_allow_subnets . push_back ( CSubNet ( " 127.0.0.0/8 " ) ) ; // always allow IPv4 local subnet
rpc_allow_subnets . push_back ( CSubNet ( " ::1 " ) ) ; // always allow IPv6 localhost
if ( mapMultiArgs . count ( " -rpcallowip " ) ) {
const std : : vector < std : : string > & vAllow = mapMultiArgs [ " -rpcallowip " ] ;
BOOST_FOREACH ( std : : string strAllow , vAllow ) {
CSubNet subnet ( strAllow ) ;
if ( ! subnet . IsValid ( ) ) {
uiInterface . ThreadSafeMessageBox (
strprintf ( " Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). " , strAllow ) ,
" " , CClientUIInterface : : MSG_ERROR ) ;
return false ;
}
rpc_allow_subnets . push_back ( subnet ) ;
}
}
std : : string strAllowed ;
BOOST_FOREACH ( const CSubNet & subnet , rpc_allow_subnets )
strAllowed + = subnet . ToString ( ) + " " ;
LogPrint ( " http " , " Allowing HTTP connections from: %s \n " , strAllowed ) ;
return true ;
}
/** HTTP request method as string - use for logging only */
static std : : string RequestMethodString ( HTTPRequest : : RequestMethod m )
{
switch ( m ) {
case HTTPRequest : : GET :
return " GET " ;
break ;
case HTTPRequest : : POST :
return " POST " ;
break ;
case HTTPRequest : : HEAD :
return " HEAD " ;
break ;
case HTTPRequest : : PUT :
return " PUT " ;
break ;
default :
return " unknown " ;
}
}
/** HTTP request callback */
static void http_request_cb ( struct evhttp_request * req , void * arg )
{
std : : auto_ptr < HTTPRequest > hreq ( new HTTPRequest ( req ) ) ;
LogPrint ( " http " , " Received a %s request for %s from %s \n " ,
RequestMethodString ( hreq - > GetRequestMethod ( ) ) , hreq - > GetURI ( ) , hreq - > GetPeer ( ) . ToString ( ) ) ;
// Early address-based allow check
if ( ! ClientAllowed ( hreq - > GetPeer ( ) ) ) {
hreq - > WriteReply ( HTTP_FORBIDDEN ) ;
return ;
}
// Early reject unknown HTTP methods
if ( hreq - > GetRequestMethod ( ) = = HTTPRequest : : UNKNOWN ) {
hreq - > WriteReply ( HTTP_BADMETHOD ) ;
return ;
}
// Find registered handler for prefix
std : : string strURI = hreq - > GetURI ( ) ;
std : : string path ;
std : : vector < HTTPPathHandler > : : const_iterator i = pathHandlers . begin ( ) ;
std : : vector < HTTPPathHandler > : : const_iterator iend = pathHandlers . end ( ) ;
for ( ; i ! = iend ; + + i ) {
bool match = false ;
if ( i - > exactMatch )
match = ( strURI = = i - > prefix ) ;
else
match = ( strURI . substr ( 0 , i - > prefix . size ( ) ) = = i - > prefix ) ;
if ( match ) {
path = strURI . substr ( i - > prefix . size ( ) ) ;
break ;
}
}
// Dispatch to worker thread
if ( i ! = iend ) {
std : : auto_ptr < HTTPWorkItem > item ( new HTTPWorkItem ( hreq . release ( ) , path , i - > handler ) ) ;
assert ( workQueue ) ;
if ( workQueue - > Enqueue ( item . get ( ) ) )
item . release ( ) ; /* if true, queue took ownership */
else
item - > req - > WriteReply ( HTTP_INTERNAL , " Work queue depth exceeded " ) ;
} else {
hreq - > WriteReply ( HTTP_NOTFOUND ) ;
}
}
2015-09-24 17:29:22 +02:00
/** Callback to reject HTTP requests after shutdown. */
static void http_reject_request_cb ( struct evhttp_request * req , void * )
{
LogPrint ( " http " , " Rejecting request while shutting down \n " ) ;
evhttp_send_error ( req , HTTP_SERVUNAVAIL , NULL ) ;
}
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-23 07:53:17 +01:00
/** Event dispatcher thread */
static void ThreadHTTP ( struct event_base * base , struct evhttp * http )
{
RenameThread ( " bitcoin-http " ) ;
LogPrint ( " http " , " Entering http event loop \n " ) ;
event_base_dispatch ( base ) ;
// Event loop will be interrupted by InterruptHTTPServer()
LogPrint ( " http " , " Exited http event loop \n " ) ;
}
/** Bind HTTP server to specified addresses */
static bool HTTPBindAddresses ( struct evhttp * http )
{
int defaultPort = GetArg ( " -rpcport " , BaseParams ( ) . RPCPort ( ) ) ;
std : : vector < std : : pair < std : : string , uint16_t > > endpoints ;
// Determine what addresses to bind to
if ( ! mapArgs . count ( " -rpcallowip " ) ) { // Default to loopback if not allowing external IPs
endpoints . push_back ( std : : make_pair ( " ::1 " , defaultPort ) ) ;
endpoints . push_back ( std : : make_pair ( " 127.0.0.1 " , defaultPort ) ) ;
if ( mapArgs . count ( " -rpcbind " ) ) {
LogPrintf ( " WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect \n " ) ;
}
} else if ( mapArgs . count ( " -rpcbind " ) ) { // Specific bind address
const std : : vector < std : : string > & vbind = mapMultiArgs [ " -rpcbind " ] ;
for ( std : : vector < std : : string > : : const_iterator i = vbind . begin ( ) ; i ! = vbind . end ( ) ; + + i ) {
int port = defaultPort ;
std : : string host ;
SplitHostPort ( * i , port , host ) ;
endpoints . push_back ( std : : make_pair ( host , port ) ) ;
}
} else { // No specific bind address specified, bind to any
endpoints . push_back ( std : : make_pair ( " :: " , defaultPort ) ) ;
endpoints . push_back ( std : : make_pair ( " 0.0.0.0 " , defaultPort ) ) ;
}
// Bind addresses
for ( std : : vector < std : : pair < std : : string , uint16_t > > : : iterator i = endpoints . begin ( ) ; i ! = endpoints . end ( ) ; + + i ) {
LogPrint ( " http " , " Binding RPC on address %s port %i \n " , i - > first , i - > second ) ;
2015-09-24 17:29:22 +02:00
evhttp_bound_socket * bind_handle = evhttp_bind_socket_with_handle ( http , i - > first . empty ( ) ? NULL : i - > first . c_str ( ) , i - > second ) ;
if ( bind_handle ) {
boundSockets . push_back ( bind_handle ) ;
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-23 07:53:17 +01:00
} else {
LogPrintf ( " Binding RPC on address %s port %i failed. \n " , i - > first , i - > second ) ;
}
}
2015-09-24 17:29:22 +02:00
return ! boundSockets . empty ( ) ;
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-23 07:53:17 +01:00
}
/** Simple wrapper to set thread name and run work queue */
static void HTTPWorkQueueRun ( WorkQueue < HTTPClosure > * queue )
{
RenameThread ( " bitcoin-httpworker " ) ;
queue - > Run ( ) ;
}
2015-09-18 14:58:08 +02:00
/** libevent event log callback */
static void libevent_log_cb ( int severity , const char * msg )
{
2015-11-14 14:54:21 +01:00
# ifndef EVENT_LOG_WARN
// EVENT_LOG_WARN was added in 2.0.19; but before then _EVENT_LOG_WARN existed.
# define EVENT_LOG_WARN _EVENT_LOG_WARN
# endif
2015-09-18 14:58:08 +02:00
if ( severity > = EVENT_LOG_WARN ) // Log warn messages and higher without debug category
LogPrintf ( " libevent: %s \n " , msg ) ;
else
LogPrint ( " libevent " , " libevent: %s \n " , msg ) ;
}
2015-08-28 16:55:16 +02:00
bool InitHTTPServer ( )
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-23 07:53:17 +01:00
{
struct evhttp * http = 0 ;
struct event_base * base = 0 ;
if ( ! InitHTTPAllowList ( ) )
return false ;
if ( GetBoolArg ( " -rpcssl " , false ) ) {
uiInterface . ThreadSafeMessageBox (
" SSL mode for RPC (-rpcssl) is no longer supported. " ,
" " , CClientUIInterface : : MSG_ERROR ) ;
return false ;
}
2015-09-18 14:58:08 +02:00
// Redirect libevent's logging to our own log
event_set_log_callback ( & libevent_log_cb ) ;
# if LIBEVENT_VERSION_NUMBER >= 0x02010100
// If -debug=libevent, set full libevent debugging.
// Otherwise, disable all libevent debugging.
if ( LogAcceptCategory ( " libevent " ) )
event_enable_debug_logging ( EVENT_DBG_ALL ) ;
else
event_enable_debug_logging ( EVENT_DBG_NONE ) ;
# 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-23 07:53:17 +01:00
# ifdef WIN32
evthread_use_windows_threads ( ) ;
# else
evthread_use_pthreads ( ) ;
# endif
base = event_base_new ( ) ; // XXX RAII
if ( ! base ) {
LogPrintf ( " Couldn't create an event_base: exiting \n " ) ;
return false ;
}
/* Create a new evhttp object to handle requests. */
http = evhttp_new ( base ) ; // XXX RAII
if ( ! http ) {
LogPrintf ( " couldn't create evhttp. Exiting. \n " ) ;
event_base_free ( base ) ;
return false ;
}
2015-09-18 15:45:38 +02:00
evhttp_set_timeout ( http , GetArg ( " -rpcservertimeout " , DEFAULT_HTTP_SERVER_TIMEOUT ) ) ;
2015-10-20 11:35:10 +02:00
evhttp_set_max_headers_size ( http , MAX_HEADERS_SIZE ) ;
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-23 07:53:17 +01:00
evhttp_set_max_body_size ( http , MAX_SIZE ) ;
evhttp_set_gencb ( http , http_request_cb , NULL ) ;
if ( ! HTTPBindAddresses ( http ) ) {
LogPrintf ( " Unable to bind any endpoint for RPC server \n " ) ;
evhttp_free ( http ) ;
event_base_free ( base ) ;
return false ;
}
2015-08-28 16:55:16 +02:00
LogPrint ( " http " , " Initialized HTTP server \n " ) ;
2015-08-28 17:14:51 +02:00
int workQueueDepth = std : : max ( ( long ) GetArg ( " -rpcworkqueue " , DEFAULT_HTTP_WORKQUEUE ) , 1L ) ;
2015-08-28 16:55:16 +02:00
LogPrintf ( " HTTP: creating work queue of depth %d \n " , workQueueDepth ) ;
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-23 07:53:17 +01:00
workQueue = new WorkQueue < HTTPClosure > ( workQueueDepth ) ;
2015-08-28 16:55:16 +02:00
eventBase = base ;
eventHTTP = http ;
return true ;
}
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-23 07:53:17 +01:00
2015-11-11 17:34:10 +01:00
boost : : thread threadHTTP ;
bool StartHTTPServer ( )
2015-08-28 16:55:16 +02:00
{
LogPrint ( " http " , " Starting HTTP server \n " ) ;
int rpcThreads = std : : max ( ( long ) GetArg ( " -rpcthreads " , DEFAULT_HTTP_THREADS ) , 1L ) ;
LogPrintf ( " HTTP: starting %d worker threads \n " , rpcThreads ) ;
2015-11-11 17:34:10 +01:00
threadHTTP = boost : : thread ( boost : : bind ( & ThreadHTTP , eventBase , eventHTTP ) ) ;
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-23 07:53:17 +01:00
for ( int i = 0 ; i < rpcThreads ; i + + )
2015-11-11 17:34:10 +01:00
boost : : thread ( boost : : bind ( & HTTPWorkQueueRun , workQueue ) ) ;
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-23 07:53:17 +01:00
return true ;
}
void InterruptHTTPServer ( )
{
LogPrint ( " http " , " Interrupting HTTP server \n " ) ;
2015-09-24 17:29:22 +02:00
if ( eventHTTP ) {
// Unlisten sockets
BOOST_FOREACH ( evhttp_bound_socket * socket , boundSockets ) {
evhttp_del_accept_socket ( eventHTTP , socket ) ;
}
// Reject requests on current connections
evhttp_set_gencb ( eventHTTP , http_reject_request_cb , NULL ) ;
}
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-23 07:53:17 +01:00
if ( workQueue )
workQueue - > Interrupt ( ) ;
}
void StopHTTPServer ( )
{
LogPrint ( " http " , " Stopping HTTP server \n " ) ;
2015-09-25 13:49:08 +02:00
if ( workQueue ) {
LogPrint ( " http " , " Waiting for HTTP worker threads to exit \n " ) ;
workQueue - > WaitExit ( ) ;
delete workQueue ;
}
2015-11-11 17:34:10 +01:00
if ( eventBase ) {
LogPrint ( " http " , " Waiting for HTTP event thread to exit \n " ) ;
// Give event loop a few seconds to exit (to send back last RPC responses), then break it
// Before this was solved with event_base_loopexit, but that didn't work as expected in
// at least libevent 2.0.21 and always introduced a delay. In libevent
// master that appears to be solved, so in the future that solution
// could be used again (if desirable).
// (see discussion in https://github.com/bitcoin/bitcoin/pull/6990)
2015-11-20 10:14:21 +01:00
# if BOOST_VERSION >= 105000
2015-11-11 17:34:10 +01:00
if ( ! threadHTTP . try_join_for ( boost : : chrono : : milliseconds ( 2000 ) ) ) {
2015-11-20 10:14:21 +01:00
# else
if ( ! threadHTTP . timed_join ( boost : : posix_time : : milliseconds ( 2000 ) ) ) {
# endif
2015-11-11 17:34:10 +01:00
LogPrintf ( " HTTP event loop did not exit within allotted time, sending loopbreak \n " ) ;
event_base_loopbreak ( eventBase ) ;
threadHTTP . join ( ) ;
}
}
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-23 07:53:17 +01:00
if ( eventHTTP ) {
evhttp_free ( eventHTTP ) ;
eventHTTP = 0 ;
}
if ( eventBase ) {
event_base_free ( eventBase ) ;
eventBase = 0 ;
}
2015-11-11 17:34:10 +01:00
LogPrint ( " http " , " Stopped HTTP server \n " ) ;
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-23 07:53:17 +01:00
}
struct event_base * EventBase ( )
{
return eventBase ;
}
static void httpevent_callback_fn ( evutil_socket_t , short , void * data )
{
2015-08-28 16:46:20 +02:00
// Static handler: simply call inner handler
HTTPEvent * self = ( ( HTTPEvent * ) data ) ;
self - > handler ( ) ;
if ( self - > deleteWhenTriggered )
delete self ;
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-23 07:53:17 +01:00
}
2015-08-28 16:46:20 +02:00
HTTPEvent : : HTTPEvent ( struct event_base * base , bool deleteWhenTriggered , const boost : : function < void ( void ) > & handler ) :
deleteWhenTriggered ( deleteWhenTriggered ) , handler ( handler )
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-23 07:53:17 +01:00
{
ev = event_new ( base , - 1 , 0 , httpevent_callback_fn , this ) ;
assert ( ev ) ;
}
HTTPEvent : : ~ HTTPEvent ( )
{
event_free ( ev ) ;
}
void HTTPEvent : : trigger ( struct timeval * tv )
{
if ( tv = = NULL )
event_active ( ev , 0 , 0 ) ; // immediately trigger event in main thread
else
evtimer_add ( ev , tv ) ; // trigger after timeval passed
}
HTTPRequest : : HTTPRequest ( struct evhttp_request * req ) : req ( req ) ,
replySent ( false )
{
}
HTTPRequest : : ~ HTTPRequest ( )
{
if ( ! replySent ) {
// Keep track of whether reply was sent to avoid request leaks
LogPrintf ( " %s: Unhandled request \n " , __func__ ) ;
WriteReply ( HTTP_INTERNAL , " Unhandled request " ) ;
}
// evhttpd cleans up the request, as long as a reply was sent.
}
std : : pair < bool , std : : string > HTTPRequest : : GetHeader ( const std : : string & hdr )
{
const struct evkeyvalq * headers = evhttp_request_get_input_headers ( req ) ;
assert ( headers ) ;
const char * val = evhttp_find_header ( headers , hdr . c_str ( ) ) ;
if ( val )
return std : : make_pair ( true , val ) ;
else
return std : : make_pair ( false , " " ) ;
}
std : : string HTTPRequest : : ReadBody ( )
{
struct evbuffer * buf = evhttp_request_get_input_buffer ( req ) ;
if ( ! buf )
return " " ;
size_t size = evbuffer_get_length ( buf ) ;
/** Trivial implementation: if this is ever a performance bottleneck,
* internal copying can be avoided in multi - segment buffers by using
* evbuffer_peek and an awkward loop . Though in that case , it ' d be even
* better to not copy into an intermediate string but use a stream
* abstraction to consume the evbuffer on the fly in the parsing algorithm .
*/
const char * data = ( const char * ) evbuffer_pullup ( buf , size ) ;
if ( ! data ) // returns NULL in case of empty buffer
return " " ;
std : : string rv ( data , size ) ;
evbuffer_drain ( buf , size ) ;
return rv ;
}
void HTTPRequest : : WriteHeader ( const std : : string & hdr , const std : : string & value )
{
struct evkeyvalq * headers = evhttp_request_get_output_headers ( req ) ;
assert ( headers ) ;
evhttp_add_header ( headers , hdr . c_str ( ) , value . c_str ( ) ) ;
}
/** Closure sent to main thread to request a reply to be sent to
* a HTTP request .
* Replies must be sent in the main loop in the main http thread ,
* this cannot be done from worker threads .
*/
void HTTPRequest : : WriteReply ( int nStatus , const std : : string & strReply )
{
assert ( ! replySent & & req ) ;
// Send event to main http thread to send reply message
struct evbuffer * evb = evhttp_request_get_output_buffer ( req ) ;
assert ( evb ) ;
evbuffer_add ( evb , strReply . data ( ) , strReply . size ( ) ) ;
HTTPEvent * ev = new HTTPEvent ( eventBase , true ,
2015-08-28 16:46:20 +02:00
boost : : bind ( evhttp_send_reply , req , nStatus , ( const char * ) NULL , ( struct evbuffer * ) NULL ) ) ;
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-23 07:53:17 +01:00
ev - > trigger ( 0 ) ;
replySent = true ;
req = 0 ; // transferred back to main thread
}
CService HTTPRequest : : GetPeer ( )
{
evhttp_connection * con = evhttp_request_get_connection ( req ) ;
CService peer ;
if ( con ) {
// evhttp retains ownership over returned address string
const char * address = " " ;
uint16_t port = 0 ;
evhttp_connection_get_peer ( con , ( char * * ) & address , & port ) ;
peer = CService ( address , port ) ;
}
return peer ;
}
std : : string HTTPRequest : : GetURI ( )
{
return evhttp_request_get_uri ( req ) ;
}
HTTPRequest : : RequestMethod HTTPRequest : : GetRequestMethod ( )
{
switch ( evhttp_request_get_command ( req ) ) {
case EVHTTP_REQ_GET :
return GET ;
break ;
case EVHTTP_REQ_POST :
return POST ;
break ;
case EVHTTP_REQ_HEAD :
return HEAD ;
break ;
case EVHTTP_REQ_PUT :
return PUT ;
break ;
default :
return UNKNOWN ;
break ;
}
}
void RegisterHTTPHandler ( const std : : string & prefix , bool exactMatch , const HTTPRequestHandler & handler )
{
2015-09-04 19:22:48 +02:00
LogPrint ( " http " , " Registering HTTP handler for %s (exactmatch %d) \n " , prefix , exactMatch ) ;
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-23 07:53:17 +01:00
pathHandlers . push_back ( HTTPPathHandler ( prefix , exactMatch , handler ) ) ;
}
void UnregisterHTTPHandler ( const std : : string & prefix , bool exactMatch )
{
std : : vector < HTTPPathHandler > : : iterator i = pathHandlers . begin ( ) ;
std : : vector < HTTPPathHandler > : : iterator iend = pathHandlers . end ( ) ;
for ( ; i ! = iend ; + + i )
if ( i - > prefix = = prefix & & i - > exactMatch = = exactMatch )
break ;
if ( i ! = iend )
{
2015-09-04 19:22:48 +02:00
LogPrint ( " http " , " Unregistering HTTP handler for %s (exactmatch %d) \n " , prefix , exactMatch ) ;
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-23 07:53:17 +01:00
pathHandlers . erase ( i ) ;
}
}