using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http.Features; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; namespace Ocelot.Provider.Nacos.NacosClient; internal static class UriTool { public static IEnumerable GetUri(IFeatureCollection features, string ip, int port, string preferredNetworks) { var splitChars = new char[] { ',', ';' }; var appPort = port <= 0 ? 80 : port; // 1. config if (!string.IsNullOrWhiteSpace(ip)) { // it seems that nacos don't return the scheme // so here use http only. return new List { new Uri($"http://{ip}:{appPort}") }; } // 1.1. Ip is null && Port has value if (string.IsNullOrWhiteSpace(ip) && appPort != 80) { return new List { new Uri($"http://{GetCurrentIp(preferredNetworks)}:{appPort}") }; } var address = string.Empty; // 2. IServerAddressesFeature if (features != null) { var addresses = features.Get(); var addressCollection = addresses?.Addresses; if (addressCollection != null && addressCollection.Any()) { var uris = new List(); foreach (var item in addressCollection) { var url = ReplaceAddress(item, preferredNetworks); uris.Add(new Uri(url)); } return uris; } } // 3. ASPNETCORE_URLS address = Environment.GetEnvironmentVariable("ASPNETCORE_URLS"); if (!string.IsNullOrWhiteSpace(address)) { var url = ReplaceAddress(address, preferredNetworks); return url.Split(splitChars).Select(x => new Uri(x)); } // 4. --urls var cmdArgs = Environment.GetCommandLineArgs(); if (cmdArgs != null && cmdArgs.Any()) { var cmd = cmdArgs.FirstOrDefault(x => x.StartsWith("--urls", StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrWhiteSpace(cmd)) { address = cmd.Split('=')[1]; var url = ReplaceAddress(address, preferredNetworks); return url.Split(splitChars).Select(x => new Uri(x)); } } // 5. current ip address third address = $"http://{GetCurrentIp(preferredNetworks)}:{appPort}"; return new List { new Uri(address) }; } private static string ReplaceAddress(string address, string preferredNetworks) { var ip = GetCurrentIp(preferredNetworks); if (address.Contains("*")) { address = address.Replace("*", ip); } else if (address.Contains("+")) { address = address.Replace("+", ip); } else if (address.Contains("localhost", StringComparison.OrdinalIgnoreCase)) { address = address.Replace("localhost", ip, StringComparison.OrdinalIgnoreCase); } else if (address.Contains("0.0.0.0", StringComparison.OrdinalIgnoreCase)) { address = address.Replace("0.0.0.0", ip, StringComparison.OrdinalIgnoreCase); } return address; } private static string GetCurrentIp(string preferredNetworks) { var instanceIp = "127.0.0.1"; try { // 获取可用网卡 var nics = NetworkInterface.GetAllNetworkInterfaces()?.Where(network => network.OperationalStatus == OperationalStatus.Up); // 获取所有可用网卡IP信息 var ipCollection = nics?.Select(x => x.GetIPProperties())?.SelectMany(x => x.UnicastAddresses); foreach (var ipadd in ipCollection) { if (!IPAddress.IsLoopback(ipadd.Address) && ipadd.Address.AddressFamily == AddressFamily.InterNetwork) { if (string.IsNullOrEmpty(preferredNetworks)) { instanceIp = ipadd.Address.ToString(); break; } if (!ipadd.Address.ToString().StartsWith(preferredNetworks)) continue; instanceIp = ipadd.Address.ToString(); break; } } } catch { // ignored } return instanceIp; } }