aboutsummaryrefslogtreecommitdiff
path: root/src/httpserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/httpserver.cpp')
-rw-r--r--src/httpserver.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 600e57b7cc..e967d3a4a8 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -155,6 +155,8 @@ static std::vector<CSubNet> rpc_allow_subnets;
static WorkQueue<HTTPClosure>* workQueue = 0;
//! Handlers for (sub)paths
std::vector<HTTPPathHandler> pathHandlers;
+//! Bound listening sockets
+std::vector<evhttp_bound_socket *> boundSockets;
/** Check if a network address is allowed to access the HTTP server */
static bool ClientAllowed(const CNetAddr& netaddr)
@@ -264,6 +266,13 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
}
}
+/** 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);
+}
+
/** Event dispatcher thread */
static void ThreadHTTP(struct event_base* base, struct evhttp* http)
{
@@ -278,7 +287,6 @@ static void ThreadHTTP(struct event_base* base, struct evhttp* http)
static bool HTTPBindAddresses(struct evhttp* http)
{
int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
- int nBound = 0;
std::vector<std::pair<std::string, uint16_t> > endpoints;
// Determine what addresses to bind to
@@ -304,13 +312,14 @@ static bool HTTPBindAddresses(struct evhttp* http)
// 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);
- if (evhttp_bind_socket(http, i->first.empty() ? NULL : i->first.c_str(), i->second) == 0) {
- nBound += 1;
+ 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);
} else {
LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second);
}
}
- return nBound > 0;
+ return !boundSockets.empty();
}
/** Simple wrapper to set thread name and run work queue */
@@ -410,8 +419,14 @@ bool StartHTTPServer(boost::thread_group& threadGroup)
void InterruptHTTPServer()
{
LogPrint("http", "Interrupting HTTP server\n");
- if (eventBase)
- event_base_loopbreak(eventBase);
+ 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);
+ }
if (workQueue)
workQueue->Interrupt();
}