refactor: split HTTPBindAddresses into config parse and libevent setup
What changed, and why it matters
This commit is a simple code cleanup: it takes one function that did two jobs—reading RPC bind settings and actually opening network sockets—and splits it into two smaller functions. The behavior, settings, and warnings shown to users are unchanged. There is no security fix or vulnerability here.
No security action needed. Review as normal refactoring if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors HTTPBindAddresses in src/httpserver.cpp. The original function parsed -rpcbind/-rpcport arguments into a vector of (host, port) pairs and then immediately bound them via libevent. The patch extracts the parsing/validation half into a new GetBindAddresses() helper and moves the libevent binding half into the http_libevent namespace as HTTPBindAddresses. Logic, error messages, warning behavior, and TCP_NODELAY handling are preserved verbatim. This is preparatory work for a future alternative HTTP server implementation.
Changed components
src/httpserver.cppInspect captured patch +29 / −25
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index 9587a99b..e912e854 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -322,8 +322,7 @@ static void ThreadHTTP(struct event_base* base)
LogDebug(BCLog::HTTP, "Exited http event loop\n");
}
-/** Bind HTTP server to specified addresses */
-static bool HTTPBindAddresses(struct evhttp* http)
+static std::vector<std::pair<std::string, uint16_t>> GetBindAddresses()
{
uint16_t http_port{static_cast<uint16_t>(gArgs.GetIntArg("-rpcport", BaseParams().RPCPort()))};
std::vector<std::pair<std::string, uint16_t>> endpoints;
@@ -348,33 +347,12 @@ static bool HTTPBindAddresses(struct evhttp* http)
std::string host;
if (!SplitHostPort(strRPCBind, port, host)) {
LogError("%s\n", InvalidPortErrMsg("-rpcbind", strRPCBind).original);
- return false;
+ return {}; // empty
}
endpoints.emplace_back(host, port);
}
}
-
- // Bind addresses
- for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) {
- LogInfo("Binding RPC on address %s port %i", i->first, i->second);
- evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? nullptr : i->first.c_str(), i->second);
- if (bind_handle) {
- const std::optional<CNetAddr> addr{LookupHost(i->first, false)};
- if (i->first.empty() || (addr.has_value() && addr->IsBindAny())) {
- LogWarning("The RPC server is not safe to expose to untrusted networks such as the public internet");
- }
- // Set the no-delay option (disable Nagle's algorithm) on the TCP socket.
- evutil_socket_t fd = evhttp_bound_socket_get_fd(bind_handle);
- int one = 1;
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&one), sizeof(one)) == SOCKET_ERROR) {
- LogInfo("WARNING: Unable to set TCP_NODELAY on RPC server socket, continuing anyway\n");
- }
- boundSockets.push_back(bind_handle);
- } else {
- LogWarning("Binding RPC on address %s port %i failed.", i->first, i->second);
- }
- }
- return !boundSockets.empty();
+ return endpoints;
}
/** libevent event log callback */
@@ -397,6 +375,32 @@ static void libevent_log_cb(int severity, const char *msg)
}
namespace http_libevent {
+/** Bind HTTP server to specified addresses */
+static bool HTTPBindAddresses(struct evhttp* http)
+{
+ std::vector<std::pair<std::string, uint16_t>> endpoints{GetBindAddresses()};
+ for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) {
+ LogInfo("Binding RPC on address %s port %i", i->first, i->second);
+ evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? nullptr : i->first.c_str(), i->second);
+ if (bind_handle) {
+ const std::optional<CNetAddr> addr{LookupHost(i->first, false)};
+ if (i->first.empty() || (addr.has_value() && addr->IsBindAny())) {
+ LogWarning("The RPC server is not safe to expose to untrusted networks such as the public internet");
+ }
+ // Set the no-delay option (disable Nagle's algorithm) on the TCP socket.
+ evutil_socket_t fd = evhttp_bound_socket_get_fd(bind_handle);
+ int one = 1;
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&one), sizeof(one)) == SOCKET_ERROR) {
+ LogInfo("WARNING: Unable to set TCP_NODELAY on RPC server socket, continuing anyway");
+ }
+ boundSockets.push_back(bind_handle);
+ } else {
+ LogWarning("Binding RPC on address %s port %i failed.", i->first, i->second);
+ }
+ }
+ return !boundSockets.empty();
+}
+
bool InitHTTPServer(const util::SignalInterrupt& interrupt)
{
if (!InitHTTPAllowList())
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.