public ParserState(string uri, UriKind kind) { remaining = uri; this.kind = kind; elements = new UriElements(); }
public static bool TryParseComponents(string uri, UriKind kind, out UriElements elements, out string error) { uri = uri.Trim(); ParserState state = new ParserState(uri, kind); elements = state.elements; error = null; if (uri.Length == 0 && (kind == UriKind.Relative || kind == UriKind.RelativeOrAbsolute)) { state.elements.isAbsoluteUri = false; return(true); } if (uri.Length <= 1 && kind == UriKind.Absolute) { error = "Absolute URI is too short"; return(false); } bool ok = ParseFilePath(state) && ParseScheme(state); var scheme = state.elements.scheme; UriParser parser = null; if (!StringUtilities.IsNullOrEmpty(scheme)) { parser = UriParser.GetParser(scheme); if (parser != null && !(parser is DefaultUriParser)) { return(true); } } ok = ok && ParseAuthority(state) && ParsePath(state) && ParseQuery(state) && ParseFragment(state); if (StringUtilities.IsNullOrEmpty(state.elements.host) && (scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeGopher || scheme == Uri.UriSchemeNntp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp)) { state.error = "Invalid URI: The Authority/Host could not be parsed."; } if (!StringUtilities.IsNullOrEmpty(state.elements.host) && Uri.CheckHostName(state.elements.host) == UriHostNameType.Unknown) { state.error = "Invalid URI: The hostname could not be parsed."; } if (!StringUtilities.IsNullOrEmpty(state.error)) { elements = null; error = state.error; return(false); } return(true); }
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.ToLower(), elements.scheme.ToLower()) != 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 (!StringUtilities.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 >= 0 && p != dp) { return(p.ToString()); } 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() : dp.ToString()); } 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 >= 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("/")) && 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()); }