From 655422bbdf4f579351778c3a77e90a0e54e6856e Mon Sep 17 00:00:00 2001 From: Wang Xiaofeng Date: Sun, 25 Oct 2026 23:45:09 +0800 Subject: [PATCH 1/2] Escape resolved hostnames in HTML connection output --- src/brpc/builtin/connections_service.cpp | 10 ++++++---- test/brpc_builtin_service_unittest.cpp | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/brpc/builtin/connections_service.cpp b/src/brpc/builtin/connections_service.cpp index 22786352cb..aa3616a0a0 100644 --- a/src/brpc/builtin/connections_service.cpp +++ b/src/brpc/builtin/connections_service.cpp @@ -56,15 +56,17 @@ inline const char* SSLStateToYesNo(SSLState s, bool use_html) { } struct NameOfPoint { - explicit NameOfPoint(const butil::EndPoint& pt_) : pt(pt_) {} + NameOfPoint(const butil::EndPoint& pt_, bool use_html_) + : pt(pt_), use_html(use_html_) {} butil::EndPoint pt; + bool use_html; }; std::ostream& operator<<(std::ostream& os, const NameOfPoint& nop) { char buf[128]; if (FLAGS_show_hostname_instead_of_ip && butil::endpoint2hostname(nop.pt, buf, sizeof(buf)) == 0) { - return os << buf; + return os << (nop.use_html ? WebEscape(buf) : std::string(buf)); } else { return os << nop.pt; } @@ -174,7 +176,7 @@ void ConnectionsService::PrintConnections( } if (failed) { os << min_width("Broken", 26) << bar - << min_width(NameOfPoint(ptr->remote_side()), 19) << bar; + << min_width(NameOfPoint(ptr->remote_side(), use_html), 19) << bar; if (is_channel_conn) { os << min_width(ptr->local_side().port, 5) << bar << min_width(ptr->recent_error_count(), 10) << bar @@ -276,7 +278,7 @@ void ConnectionsService::PrintConnections( } else { strcpy(rtt_display, "-"); } - os << bar << min_width(NameOfPoint(ptr->remote_side()), 19) << bar; + os << bar << min_width(NameOfPoint(ptr->remote_side(), use_html), 19) << bar; if (is_channel_conn) { if (ptr->local_side().port > 0) { os << min_width(ptr->local_side().port, 5) << bar; diff --git a/test/brpc_builtin_service_unittest.cpp b/test/brpc_builtin_service_unittest.cpp index 958e06669c..83a65006e6 100644 --- a/test/brpc_builtin_service_unittest.cpp +++ b/test/brpc_builtin_service_unittest.cpp @@ -74,6 +74,7 @@ const bool ALLOW_UNUSED dummy_validate_reloadable_string_flag_for_ut = namespace brpc { DECLARE_bool(enable_rpcz); +DECLARE_bool(show_hostname_instead_of_ip); DECLARE_bool(rpcz_hex_log_id); DECLARE_int32(idle_timeout_second); } // namespace rpc @@ -259,7 +260,20 @@ class BuiltinServiceTest : public ::testing::Test{ service.default_method(&cntl, &req, &res, &done); EXPECT_FALSE(cntl.Failed()); EXPECT_EQ(expect_type, cntl.http_response().content_type()); - CheckContent(cntl, buf); + if (brpc::FLAGS_show_hostname_instead_of_ip) { + char hostname[256]; + butil::EndPoint peer; + ASSERT_EQ(0, str2endpoint(buf, &peer)); + if (butil::endpoint2hostname(peer, hostname, sizeof(hostname)) == 0) { + const std::string expected = use_html + ? brpc::WebEscape(hostname) : std::string(hostname); + CheckContent(cntl, expected.c_str()); + } else { + CheckContent(cntl, buf); + } + } else { + CheckContent(cntl, buf); + } CheckFieldInContent(cntl, "channel_connection_count: ", 0); close(cfd); @@ -693,6 +707,13 @@ TEST_F(BuiltinServiceTest, connections) { TestConnections(true); } +TEST_F(BuiltinServiceTest, connections_with_hostnames) { + GFLAGS_NAMESPACE::FlagSaver flag_saver; + brpc::FLAGS_show_hostname_instead_of_ip = true; + TestConnections(false); + TestConnections(true); +} + TEST_F(BuiltinServiceTest, flags) { TestFlags(false); TestFlags(true); From bba98abac3ac474cea47ad394604e03ba011bfa4 Mon Sep 17 00:00:00 2001 From: Wang Xiaofeng Date: Sun, 25 Oct 2026 23:56:40 +0800 Subject: [PATCH 2/2] Use an ephemeral port in connection output tests --- test/brpc_builtin_service_unittest.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/brpc_builtin_service_unittest.cpp b/test/brpc_builtin_service_unittest.cpp index 83a65006e6..02198c1107 100644 --- a/test/brpc_builtin_service_unittest.cpp +++ b/test/brpc_builtin_service_unittest.cpp @@ -247,9 +247,8 @@ class BuiltinServiceTest : public ::testing::Test{ brpc::Controller cntl; ClosureChecker done; SetUpController(&cntl, use_html); - butil::EndPoint ep; - ASSERT_EQ(0, str2endpoint("127.0.0.1:9798", &ep)); - ASSERT_EQ(0, _server.Start(ep, nullptr)); + ASSERT_EQ(0, _server.Start("127.0.0.1:0", nullptr)); + const butil::EndPoint ep = _server.listen_address(); int self_port = -1; const int cfd = tcp_connect(ep, &self_port); ASSERT_GT(cfd, 0);