internal string GetComponentsHelper(Uri uri, UriComponents components, UriFormat format) { UriElements elements = UriParseComponents.ParseComponents(uri.OriginalString.Trim(), UriKind.Absolute); string scheme = scheme_name; int dp = default_port; if ((scheme == null) || (scheme == "*")) { scheme = elements.scheme; dp = Uri.GetDefaultPort(scheme); } else if (String.Compare(scheme, elements.scheme, true) != 0) { throw new SystemException("URI Parser: scheme mismatch: " + scheme + " vs. " + elements.scheme); } var formatFlags = UriHelper.FormatFlags.None; if (UriHelper.HasCharactersToNormalize(uri.OriginalString)) { formatFlags |= UriHelper.FormatFlags.HasUriCharactersToNormalize; } if (uri.UserEscaped) { formatFlags |= UriHelper.FormatFlags.UserEscaped; } if (!string.IsNullOrEmpty(elements.host)) { formatFlags |= UriHelper.FormatFlags.HasHost; } // it's easier to answer some case directly (as the output isn't identical // when mixed with others components, e.g. leading slash, # ...) switch (components) { case UriComponents.Scheme: return(scheme); case UriComponents.UserInfo: return(elements.user ?? ""); case UriComponents.Host: return(elements.host); case UriComponents.Port: { int p = elements.port; if (p != null && p >= 0 && p != dp) { return(p.ToString(CultureInfo.InvariantCulture)); } return(String.Empty); } case UriComponents.Path: var path = elements.path; if (scheme != Uri.UriSchemeMailto && scheme != Uri.UriSchemeNews) { path = IgnoreFirstCharIf(elements.path, '/'); } return(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags)); case UriComponents.Query: return(UriHelper.FormatAbsolute(elements.query, scheme, UriComponents.Query, format, formatFlags)); case UriComponents.Fragment: return(UriHelper.FormatAbsolute(elements.fragment, scheme, UriComponents.Fragment, format, formatFlags)); case UriComponents.StrongPort: { return(elements.port >= 0 ? elements.port.ToString(CultureInfo.InvariantCulture) : dp.ToString(CultureInfo.InvariantCulture)); } case UriComponents.SerializationInfoString: components = UriComponents.AbsoluteUri; break; } // now we deal with multiple flags... StringBuilder sb = new StringBuilder(); if ((components & UriComponents.Scheme) != 0) { sb.Append(scheme); sb.Append(elements.delimiter); } if ((components & UriComponents.UserInfo) != 0) { string userinfo = elements.user; if (userinfo != null) { sb.Append(elements.user); sb.Append('@'); } } if ((components & UriComponents.Host) != 0) { sb.Append(elements.host); } // for StrongPort always show port - even if -1 // otherwise only display if ut's not the default port if ((components & UriComponents.StrongPort) != 0) { sb.Append(":"); if (elements.port >= 0) { sb.Append(elements.port); } else { sb.Append(dp); } } if ((components & UriComponents.Port) != 0) { int p = elements.port; if (p != null && p >= 0 && p != dp) { sb.Append(":"); sb.Append(elements.port); } } if ((components & UriComponents.Path) != 0) { string path = elements.path; if ((components & UriComponents.PathAndQuery) != 0 && (path.Length == 0 || !path.StartsWith("/", StringComparison.Ordinal)) && elements.delimiter == Uri.SchemeDelimiter) { sb.Append("/"); } sb.Append(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags)); } if ((components & UriComponents.Query) != 0) { string query = elements.query; if (query != null) { sb.Append("?"); sb.Append(UriHelper.FormatAbsolute(query, scheme, UriComponents.Query, format, formatFlags)); } } if ((components & UriComponents.Fragment) != 0) { string f = elements.fragment; if (f != null) { sb.Append("#"); sb.Append(UriHelper.FormatAbsolute(f, scheme, UriComponents.Fragment, format, formatFlags)); } } return(sb.ToString()); }
private static string Format(string str, string schemeName, UriKind uriKind, UriComponents component, UriFormat uriFormat, FormatFlags formatFlags) { if (string.IsNullOrEmpty(str)) { return(""); } if (UriHelper.HasCharactersToNormalize(str)) { formatFlags |= UriHelper.FormatFlags.HasComponentCharactersToNormalize | FormatFlags.HasUriCharactersToNormalize; } if (component == UriComponents.Fragment && UriHelper.HasPercentage(str)) { formatFlags |= UriHelper.FormatFlags.HasFragmentPercentage; } if (component == UriComponents.Host && str.Length > 1 && str [0] == '[' && str [str.Length - 1] == ']') { formatFlags |= UriHelper.FormatFlags.IPv6Host; } if (component == UriComponents.Path && str.Length >= 2 && str [1] != ':' && ('a' <= str [0] && str [0] <= 'z') || ('A' <= str [0] && str [0] <= 'Z')) { formatFlags |= UriHelper.FormatFlags.HasWindowsPath; } UriSchemes scheme = GetScheme(schemeName); if (scheme == UriSchemes.Custom && (formatFlags & FormatFlags.HasHost) != 0) { scheme = UriSchemes.CustomWithHost; } var reduceAfter = UriSchemes.Http | UriSchemes.Https | UriSchemes.File | UriSchemes.NetPipe | UriSchemes.NetTcp; if (IriParsing) { reduceAfter |= UriSchemes.Ftp; } else if (component == UriComponents.Path && (formatFlags & FormatFlags.NoSlashReplace) == 0) { if (scheme == UriSchemes.Ftp) { str = Reduce(str.Replace('\\', '/'), !IriParsing); } if (scheme == UriSchemes.CustomWithHost) { str = Reduce(str.Replace('\\', '/'), false); } } str = FormatString(str, scheme, uriKind, component, uriFormat, formatFlags); if (component == UriComponents.Path && (formatFlags & FormatFlags.NoReduce) == 0) { if (SchemeContains(scheme, reduceAfter)) { str = Reduce(str, !IriParsing); } if (IriParsing && scheme == UriSchemes.CustomWithHost) { str = Reduce(str, false); } } return(str); }