diff --git a/BUILD b/BUILD index 5701f31234a..ccc944df6b8 100644 --- a/BUILD +++ b/BUILD @@ -1739,6 +1739,7 @@ grpc_cc_library( "gpr_base", "grpc_sockaddr", "resolved_address", + "uri_parser", ], ) diff --git a/src/core/lib/address_utils/sockaddr_utils.cc b/src/core/lib/address_utils/sockaddr_utils.cc index 4b73ab9df11..a8aaa222ba6 100644 --- a/src/core/lib/address_utils/sockaddr_utils.cc +++ b/src/core/lib/address_utils/sockaddr_utils.cc @@ -29,6 +29,7 @@ #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/str_replace.h" #include #include @@ -37,6 +38,7 @@ #include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" +#include "src/core/lib/uri/uri_parser.h" #ifdef GRPC_HAVE_UNIX_SOCKET #include @@ -52,14 +54,20 @@ static absl::StatusOr grpc_sockaddr_to_uri_unix_if_possible( absl::StrCat("Socket family is not AF_UNIX: ", addr->sa_family)); } const auto* unix_addr = reinterpret_cast(addr); + std::string scheme, path; if (unix_addr->sun_path[0] == '\0' && unix_addr->sun_path[1] != '\0') { - return absl::StrCat( - "unix-abstract:", - absl::string_view( - unix_addr->sun_path + 1, - resolved_addr->len - sizeof(unix_addr->sun_family) - 1)); + scheme = "unix-abstract"; + path = std::string(unix_addr->sun_path + 1, + resolved_addr->len - sizeof(unix_addr->sun_family) - 1); + } else { + scheme = "unix"; + path = unix_addr->sun_path; } - return absl::StrCat("unix:", unix_addr->sun_path); + absl::StatusOr uri = grpc_core::URI::Create( + std::move(scheme), /*authority=*/"", std::move(path), + /*query_parameter_pairs=*/{}, /*fragment=*/""); + if (!uri.ok()) return uri.status(); + return uri->ToString(); } #else static absl::StatusOr grpc_sockaddr_to_uri_unix_if_possible( @@ -263,6 +271,8 @@ absl::StatusOr grpc_sockaddr_to_uri( if (scheme == nullptr || strcmp("unix", scheme) == 0) { return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr); } + // TODO(anramach): Encode the string using URI::Create() and URI::ToString() + // before returning. auto path = grpc_sockaddr_to_string(resolved_addr, false /* normalize */); if (!path.ok()) return path; return absl::StrCat(scheme, ":", path.value()); diff --git a/test/core/address_utils/sockaddr_utils_test.cc b/test/core/address_utils/sockaddr_utils_test.cc index be21dab58c0..9053ead6ac0 100644 --- a/test/core/address_utils/sockaddr_utils_test.cc +++ b/test/core/address_utils/sockaddr_utils_test.cc @@ -256,6 +256,27 @@ TEST(SockAddrUtilsTest, SockAddrToString) { #endif } +#ifdef GRPC_HAVE_UNIX_SOCKET + +TEST(SockAddrUtilsTest, UnixSockAddrToUri) { + grpc_resolved_address addr; + ASSERT_TRUE(GRPC_ERROR_NONE == + grpc_core::UnixSockaddrPopulate("sample-path", &addr)); + EXPECT_EQ(grpc_sockaddr_to_uri(&addr).value(), "unix:sample-path"); + + ASSERT_TRUE(GRPC_ERROR_NONE == + grpc_core::UnixAbstractSockaddrPopulate("no-nulls", &addr)); + EXPECT_EQ(grpc_sockaddr_to_uri(&addr).value(), "unix-abstract:no-nulls"); + + ASSERT_TRUE(GRPC_ERROR_NONE == + grpc_core::UnixAbstractSockaddrPopulate( + std::string("path_\0with_null", 15), &addr)); + EXPECT_EQ(grpc_sockaddr_to_uri(&addr).value(), + "unix-abstract:path_%00with_null"); +} + +#endif /* GRPC_HAVE_UNIX_SOCKET */ + TEST(SockAddrUtilsTest, SockAddrSetGetPort) { grpc_resolved_address input4 = MakeAddr4(kIPv4, sizeof(kIPv4)); ASSERT_EQ(grpc_sockaddr_get_port(&input4), 12345);