public static BindingAddress Parse(string address) { address = address ?? string.Empty; int schemeDelimiterStart = address.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { throw new FormatException($"Invalid url: '{address}'"); } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; var isUnixPipe = address.IndexOf(UnixPipeHostPrefix, schemeDelimiterEnd, StringComparison.Ordinal) == schemeDelimiterEnd; int pathDelimiterStart; int pathDelimiterEnd; if (!isUnixPipe) { pathDelimiterStart = address.IndexOf("/", schemeDelimiterEnd, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart; } else { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // +2 refers to drive letter + directory seperator char pathDelimiterStart = address.IndexOf(":", schemeDelimiterEnd + UnixPipeHostPrefix.Length + 2, StringComparison.Ordinal); } else { pathDelimiterStart = address.IndexOf(":", schemeDelimiterEnd + UnixPipeHostPrefix.Length, StringComparison.Ordinal); } pathDelimiterEnd = pathDelimiterStart + ":".Length; } if (pathDelimiterStart < 0) { pathDelimiterStart = pathDelimiterEnd = address.Length; } var serverAddress = new BindingAddress(); serverAddress.Scheme = address.Substring(0, schemeDelimiterStart); var hasSpecifiedPort = false; if (!isUnixPipe) { int portDelimiterStart = address.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - schemeDelimiterEnd, StringComparison.Ordinal); if (portDelimiterStart >= 0) { int portDelimiterEnd = portDelimiterStart + ":".Length; string portString = address.Substring(portDelimiterEnd, pathDelimiterStart - portDelimiterEnd); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { hasSpecifiedPort = true; serverAddress.Host = address.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd); serverAddress.Port = portNumber; } } if (!hasSpecifiedPort) { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } } } if (!hasSpecifiedPort) { serverAddress.Host = address.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd); } if (string.IsNullOrEmpty(serverAddress.Host)) { throw new FormatException($"Invalid url: '{address}'"); } if (address[address.Length - 1] == '/') { serverAddress.PathBase = address.Substring(pathDelimiterEnd, address.Length - pathDelimiterEnd - 1); } else { serverAddress.PathBase = address.Substring(pathDelimiterEnd); } return(serverAddress); }
public static BindingAddress Parse(string address) { address = address ?? string.Empty; int schemeDelimiterStart = address.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal); if (schemeDelimiterStart < 0) { throw new FormatException($"Invalid url: '{address}'"); } int schemeDelimiterEnd = schemeDelimiterStart + Uri.SchemeDelimiter.Length; var isUnixPipe = address.IndexOf(UnixPipeHostPrefix, schemeDelimiterEnd, StringComparison.Ordinal) == schemeDelimiterEnd; int pathDelimiterStart; int pathDelimiterEnd; if (!isUnixPipe) { pathDelimiterStart = address.IndexOf("/", schemeDelimiterEnd, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart; } else { var unixPipeHostPrefixLength = UnixPipeHostPrefix.Length; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Windows has drive letters and volume separator (c:) unixPipeHostPrefixLength += 2; if (schemeDelimiterEnd + unixPipeHostPrefixLength > address.Length) { throw new FormatException($"Invalid url: '{address}'"); } } pathDelimiterStart = address.IndexOf(":", schemeDelimiterEnd + unixPipeHostPrefixLength, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart + ":".Length; } if (pathDelimiterStart < 0) { pathDelimiterStart = pathDelimiterEnd = address.Length; } var serverAddress = new BindingAddress(); serverAddress.Scheme = address.Substring(0, schemeDelimiterStart); var hasSpecifiedPort = false; if (!isUnixPipe) { int portDelimiterStart = address.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - schemeDelimiterEnd, StringComparison.Ordinal); if (portDelimiterStart >= 0) { int portDelimiterEnd = portDelimiterStart + ":".Length; string portString = address.Substring(portDelimiterEnd, pathDelimiterStart - portDelimiterEnd); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { hasSpecifiedPort = true; serverAddress.Host = address.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd); serverAddress.Port = portNumber; } } if (!hasSpecifiedPort) { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } } } if (!hasSpecifiedPort) { serverAddress.Host = address.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd); } if (string.IsNullOrEmpty(serverAddress.Host)) { throw new FormatException($"Invalid url: '{address}'"); } if (isUnixPipe && !Path.IsPathRooted(serverAddress.UnixPipePath)) { throw new FormatException($"Invalid url, unix socket path must be absolute: '{address}'"); } if (address[address.Length - 1] == '/') { serverAddress.PathBase = address.Substring(pathDelimiterEnd, address.Length - pathDelimiterEnd - 1); } else { serverAddress.PathBase = address.Substring(pathDelimiterEnd); } return(serverAddress); }