#include "web/Resolver.hpp" #include "util/Assert.hpp" #include #include #include #include #include #include #include namespace asio = boost::asio; namespace web { namespace { // Check if the hostname is an IP address or a subnet. bool isAddress(std::string_view hostname) { boost::system::error_code ec; asio::ip::make_address(hostname, ec); if (ec == boost::system::errc::success) { return true; } asio::ip::make_network_v4(hostname, ec); if (ec == boost::system::errc::success) { return true; } asio::ip::make_network_v6(hostname, ec); return ec == boost::system::errc::success; } std::string toString(auto const& endpoint) { std::stringstream ss; ss << endpoint; return ss.str(); } } // namespace std::vector Resolver::resolve(std::string_view hostname, std::string_view service) { ASSERT(not service.empty(), "Service is unspecified. Use `resolve(hostname)` instead."); if (isAddress(hostname)) return {std::string(hostname) + ':' + std::string(service)}; std::vector endpoints; for (auto const& endpoint : doResolve(hostname, service)) endpoints.push_back(toString(endpoint)); return endpoints; } std::vector Resolver::resolve(std::string_view hostname) { if (isAddress(hostname)) return {std::string(hostname)}; std::vector endpoints; for (auto const& endpoint : doResolve(hostname, "")) endpoints.push_back(endpoint.address().to_string()); return endpoints; } std::vector Resolver::doResolve(std::string_view hostname, std::string_view service) { std::vector endpoints; for (auto&& endpoint : resolver_.resolve(hostname, service)) endpoints.push_back(std::move(endpoint)); return endpoints; } } // namespace web