public override string ToString() { if (_username.Length == 0 && _password.Length > 0) { throw new UriFormatException(SR.net_uri_BadUserPassword); } if (_scheme.Length != 0) { UriParser syntax = UriParser.GetSyntax(_scheme); if (syntax != null) { _schemeDelimiter = syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || (_host.Length != 0 && syntax.NotAny(UriSyntaxFlags.MailToLikeUri) && syntax.InFact(UriSyntaxFlags.OptionalAuthority)) ? Uri.SchemeDelimiter : ":"; } else { _schemeDelimiter = _host.Length != 0 ? Uri.SchemeDelimiter : ":"; } } string result = _scheme.Length != 0 ? (_scheme + _schemeDelimiter) : string.Empty; return(result + _username + ((_password.Length > 0) ? (":" + _password) : string.Empty) + ((_username.Length > 0) ? "@" : string.Empty) + _host + (((_port != -1) && (_host.Length > 0)) ? (":" + _port) : string.Empty) + (((_host.Length > 0) && (_path.Length != 0) && (_path[0] != '/')) ? "/" : string.Empty) + _path + _query + _fragment); }
public static bool IsKnownScheme(string schemeName) { if (schemeName == null) { throw new ArgumentNullException("schemeName"); } if (!CheckSchemeName(schemeName)) { throw new ArgumentOutOfRangeException("schemeName"); } UriParser syntax = GetSyntax(schemeName.ToLower(CultureInfo.InvariantCulture)); return((syntax != null) && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri)); }
// // Is a Uri scheme known to System.Uri? // public static bool IsKnownScheme(string schemeName) { if (schemeName == null) { throw new ArgumentNullException(nameof(schemeName)); } if (!Uri.CheckSchemeName(schemeName)) { throw new ArgumentOutOfRangeException(nameof(schemeName)); } UriParser syntax = UriParser.GetSyntax(schemeName.ToLowerInvariant()); return(syntax != null && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri)); }
private unsafe ushort CheckAuthorityHelper(char* pString, ushort idx, ushort length, ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost) { char ch; int end = length; int num2 = idx; ushort index = idx; newHost = null; bool justNormalized = false; bool iriParsing = s_IriParsing && IriParsingStatic(syntax); bool hasUnicode = (flags & Flags.HasUnicode) != Flags.HostNotParsed; bool flag4 = (flags & (Flags.HostNotParsed | Flags.HostUnicodeNormalized)) == Flags.HostNotParsed; UriSyntaxFlags flags2 = syntax.Flags; if ((hasUnicode && iriParsing) && flag4) { newHost = this.m_originalUnicodeString.Substring(0, num2); } if ((((idx == length) || ((ch = pString[idx]) == '/')) || ((ch == '\\') && StaticIsFile(syntax))) || ((ch == '#') || (ch == '?'))) { if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost)) { flags &= ~(Flags.HostNotParsed | Flags.UncPath); if (StaticInFact(flags, Flags.HostNotParsed | Flags.ImplicitFile)) { err = ParsingError.BadHostName; } else { flags |= Flags.BasicHostType; } } else { err = ParsingError.BadHostName; } if ((hasUnicode && iriParsing) && flag4) { flags |= Flags.HostNotParsed | Flags.HostUnicodeNormalized; } return idx; } string userInfoString = null; if ((flags2 & UriSyntaxFlags.MayHaveUserInfo) != UriSyntaxFlags.None) { while (index < end) { if (((index == (end - 1)) || (pString[index] == '?')) || (((pString[index] == '#') || (pString[index] == '\\')) || (pString[index] == '/'))) { index = idx; break; } if (pString[index] == '@') { flags |= Flags.HasUserInfo; if (iriParsing || (s_IdnScope != null)) { if ((iriParsing && hasUnicode) && flag4) { userInfoString = this.EscapeUnescapeIri(pString, num2, index + 1, UriComponents.UserInfo); try { userInfoString = userInfoString.Normalize(NormalizationForm.FormC); } catch (ArgumentException) { err = ParsingError.BadFormat; return idx; } newHost = newHost + userInfoString; } else { userInfoString = new string(pString, num2, (index - num2) + 1); } } index = (ushort) (index + 1); ch = pString[index]; break; } index = (ushort) (index + 1); } } bool notCanonical = (flags2 & UriSyntaxFlags.SimpleUserSyntax) == UriSyntaxFlags.None; if (((ch == '[') && syntax.InFact(UriSyntaxFlags.AllowIPv6Host)) && IPv6AddressHelper.IsValid(pString, index + 1, ref end)) { flags |= Flags.HostNotParsed | Flags.IPv6HostType; if (!s_ConfigInitialized) { InitializeUriConfig(); this.m_iriParsing = s_IriParsing && IriParsingStatic(syntax); } if ((hasUnicode && iriParsing) && flag4) { newHost = newHost + new string(pString, index, end - index); flags |= Flags.HostNotParsed | Flags.HostUnicodeNormalized; justNormalized = true; } } else if (((ch <= '9') && (ch >= '0')) && (syntax.InFact(UriSyntaxFlags.AllowIPv4Host) && IPv4AddressHelper.IsValid(pString, index, ref end, false, StaticNotAny(flags, Flags.HostNotParsed | Flags.ImplicitFile)))) { flags |= Flags.HostNotParsed | Flags.IPv4HostType; if ((hasUnicode && iriParsing) && flag4) { newHost = newHost + new string(pString, index, end - index); flags |= Flags.HostNotParsed | Flags.HostUnicodeNormalized; justNormalized = true; } } else if ((((flags2 & UriSyntaxFlags.AllowDnsHost) != UriSyntaxFlags.None) && !iriParsing) && DomainNameHelper.IsValid(pString, index, ref end, ref notCanonical, StaticNotAny(flags, Flags.HostNotParsed | Flags.ImplicitFile))) { flags |= Flags.DnsHostType; if (!notCanonical) { flags |= Flags.CanonicalDnsHost; } if (s_IdnScope != null) { if ((s_IdnScope == 1) && this.IsIntranet(new string(pString, 0, end))) { flags |= Flags.HostNotParsed | Flags.IntranetUri; } if (this.AllowIdnStatic(syntax, flags)) { bool allAscii = true; bool atLeastOneValidIdn = false; string str2 = DomainNameHelper.UnicodeEquivalent(pString, index, end, ref allAscii, ref atLeastOneValidIdn); if (atLeastOneValidIdn) { if (StaticNotAny(flags, Flags.HasUnicode)) { this.m_originalUnicodeString = this.m_String; } flags |= Flags.HostNotParsed | Flags.IdnHost; newHost = this.m_originalUnicodeString.Substring(0, num2) + userInfoString + str2; flags |= Flags.CanonicalDnsHost; this.m_DnsSafeHost = new string(pString, index, end - index); justNormalized = true; } flags |= Flags.HostNotParsed | Flags.HostUnicodeNormalized; } } } else if ((((iriParsing || (s_IdnScope != null)) && ((flags2 & UriSyntaxFlags.AllowDnsHost) != UriSyntaxFlags.None)) && ((iriParsing && flag4) || this.AllowIdnStatic(syntax, flags))) && DomainNameHelper.IsValidByIri(pString, index, ref end, ref notCanonical, StaticNotAny(flags, Flags.HostNotParsed | Flags.ImplicitFile))) { this.CheckAuthorityHelperHandleDnsIri(pString, index, end, num2, iriParsing, hasUnicode, syntax, userInfoString, ref flags, ref justNormalized, ref newHost, ref err); } else if ((((s_IdnScope == null) && !s_IriParsing) && (((flags2 & UriSyntaxFlags.AllowUncHost) != UriSyntaxFlags.None) && UncNameHelper.IsValid(pString, index, ref end, StaticNotAny(flags, Flags.HostNotParsed | Flags.ImplicitFile)))) && ((end - index) <= 0x100)) { flags |= Flags.HostNotParsed | Flags.UncHostType; } if (((end < length) && (pString[end] == '\\')) && (((flags & (Flags.BasicHostType | Flags.IPv4HostType)) != Flags.HostNotParsed) && !StaticIsFile(syntax))) { if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri)) { err = ParsingError.BadHostName; flags |= Flags.BasicHostType | Flags.IPv4HostType; return (ushort) end; } flags &= ~(Flags.BasicHostType | Flags.IPv4HostType); } else if ((end < length) && (pString[end] == ':')) { if (!syntax.InFact(UriSyntaxFlags.MayHavePort)) { flags &= ~(Flags.BasicHostType | Flags.IPv4HostType); } else { int num4 = 0; int startIndex = end; idx = (ushort) (end + 1); while (idx < length) { ushort num6 = pString[idx] - '0'; if ((num6 >= 0) && (num6 <= 9)) { num4 = (num4 * 10) + num6; if (num4 > 0xffff) { break; } } else { if (((num6 == 0xffff) || (num6 == 15)) || (num6 == 0xfff3)) { break; } if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri)) { flags &= ~(Flags.BasicHostType | Flags.IPv4HostType); break; } err = ParsingError.BadPort; return idx; } idx = (ushort) (idx + 1); } if (num4 > 0xffff) { if (!syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost)) { err = ParsingError.BadPort; return idx; } flags &= ~(Flags.BasicHostType | Flags.IPv4HostType); } if ((iriParsing && hasUnicode) && justNormalized) { newHost = newHost + new string(pString, startIndex, idx - startIndex); } } } if ((flags & (Flags.BasicHostType | Flags.IPv4HostType)) == Flags.HostNotParsed) { flags &= ~Flags.HasUserInfo; if (!syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost)) { if (!syntax.InFact(UriSyntaxFlags.V1_UnknownUri)) { if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) { err = ParsingError.BadHostName; flags |= Flags.BasicHostType | Flags.IPv4HostType; return idx; } } else { bool flag8 = false; int num7 = idx; for (end = idx; end < length; end++) { if (flag8 && (((pString[end] == '/') || (pString[end] == '?')) || (pString[end] == '#'))) { break; } if ((end < (idx + 2)) && (pString[end] == '.')) { flag8 = true; } else { err = ParsingError.BadHostName; flags |= Flags.BasicHostType | Flags.IPv4HostType; return idx; } } flags |= Flags.BasicHostType; if ((iriParsing && hasUnicode) && StaticNotAny(flags, Flags.HostNotParsed | Flags.HostUnicodeNormalized)) { string str3 = new string(pString, num7, num7 - end); try { newHost = newHost + str3.Normalize(NormalizationForm.FormC); } catch (ArgumentException) { err = ParsingError.BadFormat; return idx; } flags |= Flags.HostNotParsed | Flags.HostUnicodeNormalized; } } } else { flags |= Flags.BasicHostType; end = idx; while (end < length) { if (((pString[end] == '/') || (pString[end] == '?')) || (pString[end] == '#')) { break; } end++; } this.CheckAuthorityHelperHandleAnyHostIri(pString, num2, end, iriParsing, hasUnicode, syntax, ref flags, ref newHost, ref err); } } return (ushort) end; }
private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax) { ushort num = 0; ushort num2 = 0; ushort num3 = 0; ushort num4 = 0; ushort index = (ushort) (((ushort) destLength) - 1); start = (ushort) (start - 1); while (index != start) { char ch = dest[index]; if ((ch == '\\') && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) { dest[index] = ch = '/'; } if (ch == '/') { num = (ushort) (num + 1); } else { if (num > 1) { num2 = (ushort) (index + 1); } num = 0; } if (ch == '.') { num3 = (ushort) (num3 + 1); goto Label_017F; } if (num3 == 0) { goto Label_0148; } bool flag = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) && (((num3 > 2) || (ch != '/')) || (index == start)); if (!flag && (ch == '/')) { if ((num2 != ((index + num3) + 1)) && ((num2 != 0) || (((index + num3) + 1) != destLength))) { goto Label_0146; } num2 = (ushort) (((index + 1) + num3) + ((num2 == 0) ? 0 : 1)); Buffer.BlockCopy(dest, num2 << 1, dest, (index + 1) << 1, (destLength - num2) << 1); destLength -= (num2 - index) - 1; num2 = index; if (num3 == 2) { num4 = (ushort) (num4 + 1); } num3 = 0; goto Label_017F; } if ((!flag && (num4 == 0)) && ((num2 == ((index + num3) + 1)) || ((num2 == 0) && (((index + num3) + 1) == destLength)))) { num3 = (ushort) ((index + 1) + num3); Buffer.BlockCopy(dest, num3 << 1, dest, (index + 1) << 1, (destLength - num3) << 1); destLength -= (num3 - index) - 1; num2 = 0; num3 = 0; goto Label_017F; } Label_0146: num3 = 0; Label_0148: if (ch == '/') { if (num4 != 0) { num4 = (ushort) (num4 - 1); num2 = (ushort) (num2 + 1); Buffer.BlockCopy(dest, num2 << 1, dest, (index + 1) << 1, (destLength - num2) << 1); destLength -= (num2 - index) - 1; } num2 = index; } Label_017F: index = (ushort) (index - 1); } start = (ushort) (start + 1); if (((((ushort) destLength) > start) && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath)) && (num <= 1)) { if ((num4 != 0) && (dest[start] != '/')) { num2 = (ushort) (num2 + 1); Buffer.BlockCopy(dest, num2 << 1, dest, start << 1, (destLength - num2) << 1); destLength -= num2; return dest; } if ((num3 != 0) && ((num2 == (num3 + 1)) || ((num2 == 0) && ((num3 + 1) == destLength)))) { num3 = (ushort) (num3 + ((num2 == 0) ? 0 : 1)); Buffer.BlockCopy(dest, num3 << 1, dest, start << 1, (destLength - num3) << 1); destLength -= num3; } } return dest; }
// // This will compress any "\" "/../" "/./" "///" "/..../" /XXX.../, etc found in the input // // The passed syntax controls whether to use aggressive compression or the one specified in RFC 2396 // private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax) { ushort slashCount = 0; ushort lastSlash = 0; ushort dotCount = 0; ushort removeSegments = 0; unchecked { //ushort i == -1 and start == -1 overflow is ok here ushort i = (ushort)((ushort)destLength - (ushort)1); start = (ushort)(start - 1); for (; i != start; --i) { char ch = dest[i]; if (ch == '\\' && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) { dest[i] = ch = '/'; } // // compress multiple '/' for file URI // if (ch == '/') { ++slashCount; } else { if (slashCount > 1) { // else preserve repeated slashes lastSlash = (ushort)(i + 1); } slashCount = 0; } if (ch == '.') { ++dotCount; continue; } else if (dotCount != 0) { bool skipSegment = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) && (dotCount > 2 || ch != '/' || i == start); // // Cases: // /./ = remove this segment // /../ = remove this segment, mark next for removal // /....x = DO NOT TOUCH, leave as is // x.../ = DO NOT TOUCH, leave as is, except for V2 legacy mode // if (!skipSegment && ch == '/') { if ((lastSlash == i + dotCount + 1 // "/..../" || (lastSlash == 0 && i + dotCount + 1 == destLength)) // "/..." && (dotCount <= 2)) { // // /./ or /.<eos> or /../ or /..<eos> // // just reusing a variable slot we perform //dest.Remove(i+1, dotCount + (lastSlash==0?0:1)); lastSlash = (ushort)(i + 1 + dotCount + (lastSlash == 0 ? 0 : 1)); Buffer.BlockCopy(dest, lastSlash << 1, dest, (i + 1) << 1, (destLength - lastSlash) << 1); destLength -= (lastSlash - i - 1); lastSlash = i; if (dotCount == 2) { // // We have 2 dots in between like /../ or /..<eos>, // Mark next segment for removal and remove this /../ or /.. // ++removeSegments; } dotCount = 0; continue; } } // .NET 4.5 no longer removes trailing dots in a path segment x.../ or x...<eos> dotCount = 0; // // Here all other cases go such as // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0) } // // Now we may want to remove a segment because of previous /../ // if (ch == '/') { if (removeSegments != 0) { --removeSegments; // just reusing a variable slot we perform //dest.Remove(i+1, lastSlash - i); lastSlash = (ushort)(lastSlash + 1); Buffer.BlockCopy(dest, lastSlash << 1, dest, (i + 1) << 1, (destLength - lastSlash) << 1); destLength -= (lastSlash - i - 1); } lastSlash = i; } } start = (ushort)((ushort)start + (ushort)1); } //end of unchecked if ((ushort)destLength > start && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath)) { if (slashCount <= 1) { if (removeSegments != 0 && dest[start] != '/') { //remove first not rooted segment lastSlash = (ushort)(lastSlash + 1); Buffer.BlockCopy(dest, lastSlash << 1, dest, start << 1, (destLength - lastSlash) << 1); destLength -= lastSlash; } else if (dotCount != 0) { // If final string starts with a segment looking like .[...]/ or .[...]<eos> // then we remove this first segment if (lastSlash == dotCount + 1 || (lastSlash == 0 && dotCount + 1 == destLength)) { dotCount = (ushort)(dotCount + (lastSlash == 0 ? 0 : 1)); Buffer.BlockCopy(dest, dotCount << 1, dest, start << 1, (destLength - dotCount) << 1); destLength -= dotCount; } } } } return dest; }
// // Checks the syntax of an authority component. It may also get a userInfo if present // Returns an error if no/mailformed authority found // Does not NOT touch m_Info // Returns position of the Path component // // Must be called in the ctor only private unsafe ushort CheckAuthorityHelper(char* pString, ushort idx, ushort length, ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost) { int end = length; char ch; int startInput = idx; ushort start = idx; newHost = null; bool justNormalized = false; bool iriParsing = (s_IriParsing && IriParsingStatic(syntax)); // perf bool hasUnicode = ((flags & Flags.HasUnicode) != 0); // perf bool hostNotUnicodeNormalized = ((flags & Flags.HostUnicodeNormalized) == 0); // perf UriSyntaxFlags syntaxFlags = syntax.Flags; // need to build new Iri'zed string if (hasUnicode && iriParsing && hostNotUnicodeNormalized) { newHost = _originalUnicodeString.Substring(0, startInput); } //Special case is an empty authority if (idx == length || ((ch = pString[idx]) == '/' || (ch == '\\' && StaticIsFile(syntax)) || ch == '#' || ch == '?')) { if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost)) { flags &= ~Flags.UncPath; //UNC cannot have an empty hostname if (StaticInFact(flags, Flags.ImplicitFile)) err = ParsingError.BadHostName; else flags |= Flags.BasicHostType; } else err = ParsingError.BadHostName; if (hasUnicode && iriParsing && hostNotUnicodeNormalized) { flags |= Flags.HostUnicodeNormalized;// no host } return idx; } string userInfoString = null; // Attempt to parse user info first if ((syntaxFlags & UriSyntaxFlags.MayHaveUserInfo) != 0) { for (; start < end; ++start) { if (start == end - 1 || pString[start] == '?' || pString[start] == '#' || pString[start] == '\\' || pString[start] == '/') { start = idx; break; } else if (pString[start] == '@') { flags |= Flags.HasUserInfo; // Iri'ze userinfo if (iriParsing || (s_IdnScope != UriIdnScope.None)) { if (iriParsing && hasUnicode && hostNotUnicodeNormalized) { // Normalize user info userInfoString = IriHelper.EscapeUnescapeIri(pString, startInput, start + 1, UriComponents.UserInfo); newHost += userInfoString; } else { userInfoString = new string(pString, startInput, start - startInput + 1); } } ++start; ch = pString[start]; break; } } } // DNS name only optimization // Fo an overridden parsing the optimization is suppressed since hostname can be changed to anything bool dnsNotCanonical = ((syntaxFlags & UriSyntaxFlags.SimpleUserSyntax) == 0); if (ch == '[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) && IPv6AddressHelper.IsValid(pString, (int)start + 1, ref end)) { flags |= Flags.IPv6HostType; _iriParsing = (s_IriParsing && IriParsingStatic(syntax)); if (hasUnicode && iriParsing && hostNotUnicodeNormalized) { newHost += new string(pString, start, end - start); flags |= Flags.HostUnicodeNormalized; justNormalized = true; } } else if (ch <= '9' && ch >= '0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) && IPv4AddressHelper.IsValid(pString, (int)start, ref end, false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri))) { flags |= Flags.IPv4HostType; if (hasUnicode && iriParsing && hostNotUnicodeNormalized) { newHost += new string(pString, start, end - start); flags |= Flags.HostUnicodeNormalized; justNormalized = true; } } else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost) != 0) && !iriParsing && DomainNameHelper.IsValid(pString, start, ref end, ref dnsNotCanonical, StaticNotAny(flags, Flags.ImplicitFile))) { // comes here if there are only ascii chars in host with original parsing and no Iri flags |= Flags.DnsHostType; if (!dnsNotCanonical) { flags |= Flags.CanonicalDnsHost; } if ((s_IdnScope != UriIdnScope.None)) { // check if intranet // if ((s_IdnScope == UriIdnScope.AllExceptIntranet) && IsIntranet(new string(pString, 0, end))) { flags |= Flags.IntranetUri; } if (AllowIdnStatic(syntax, flags)) { bool allAscii = true; bool atLeastOneIdn = false; string idnValue = DomainNameHelper.UnicodeEquivalent(pString, start, end, ref allAscii, ref atLeastOneIdn); // did we find at least one valid idn if (atLeastOneIdn) { // need to switch string here since we didn't know beforehand there was an idn host if (StaticNotAny(flags, Flags.HasUnicode)) _originalUnicodeString = _string; // lazily switching strings flags |= Flags.IdnHost; // need to build string for this special scenario newHost = _originalUnicodeString.Substring(0, startInput) + userInfoString + idnValue; flags |= Flags.CanonicalDnsHost; _dnsSafeHost = new string(pString, start, end - start); justNormalized = true; } flags |= Flags.HostUnicodeNormalized; } } } else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost) != 0) && ((syntax.InFact(UriSyntaxFlags.AllowIriParsing) && hostNotUnicodeNormalized) || syntax.InFact(UriSyntaxFlags.AllowIdn)) && DomainNameHelper.IsValidByIri(pString, start, ref end, ref dnsNotCanonical, StaticNotAny(flags, Flags.ImplicitFile))) { CheckAuthorityHelperHandleDnsIri(pString, start, end, startInput, iriParsing, hasUnicode, syntax, userInfoString, ref flags, ref justNormalized, ref newHost, ref err); } else if ((syntaxFlags & UriSyntaxFlags.AllowUncHost) != 0) { // // This must remain as the last check before BasicHost type // if (UncNameHelper.IsValid(pString, start, ref end, StaticNotAny(flags, Flags.ImplicitFile))) { if (end - start <= UncNameHelper.MaximumInternetNameLength) flags |= Flags.UncHostType; } } // The deal here is that we won't allow '\' host terminator except for the File scheme // If we see '\' we try to make it a part of a Basic host if (end < length && pString[end] == '\\' && (flags & Flags.HostTypeMask) != Flags.HostNotParsed && !StaticIsFile(syntax)) { if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri)) { err = ParsingError.BadHostName; flags |= Flags.UnknownHostType; return (ushort)end; } flags &= ~Flags.HostTypeMask; } // Here we have checked the syntax up to the end of host // The only thing that can cause an exception is the port value // Spend some (duplicated) cycles on that. else if (end < length && pString[end] == ':') { if (syntax.InFact(UriSyntaxFlags.MayHavePort)) { int port = 0; int startPort = end; for (idx = (ushort)(end + 1); idx < length; ++idx) { ushort val = (ushort)((ushort)pString[idx] - (ushort)'0'); if ((val >= 0) && (val <= 9)) { if ((port = (port * 10 + val)) > 0xFFFF) break; } else if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') || val == unchecked((ushort)('#' - '0'))) { break; } else { // The second check is to keep compatibility with V1 until the UriParser is registered if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri)) { flags &= ~Flags.HostTypeMask; break; } else { err = ParsingError.BadPort; return idx; } } } // check on 0-ffff range if (port > 0xFFFF) { if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost)) { flags &= ~Flags.HostTypeMask; } else { err = ParsingError.BadPort; return idx; } } if (iriParsing && hasUnicode && justNormalized) { newHost += new string(pString, startPort, idx - startPort); } } else { flags &= ~Flags.HostTypeMask; } } // check on whether nothing has worked out if ((flags & Flags.HostTypeMask) == Flags.HostNotParsed) { //No user info for a Basic hostname flags &= ~Flags.HasUserInfo; // Some schemes do not allow HostType = Basic (plus V1 almost never understands this issue) // if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost)) { flags |= Flags.BasicHostType; for (end = idx; end < length; ++end) { if (pString[end] == '/' || (pString[end] == '?' || pString[end] == '#')) { break; } } CheckAuthorityHelperHandleAnyHostIri(pString, startInput, end, iriParsing, hasUnicode, syntax, ref flags, ref newHost, ref err); } else { // // ATTN V1 compat: V1 supports hostnames like ".." and ".", and so we do but only for unknown schemes. // if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri)) { // Can assert here that the host is not empty so we will set dotFound // at least once or fail before exiting the loop bool dotFound = false; int startOtherHost = idx; for (end = idx; end < length; ++end) { if (dotFound && (pString[end] == '/' || pString[end] == '?' || pString[end] == '#')) break; else if (end < (idx + 2) && pString[end] == '.') { // allow one or two dots dotFound = true; } else { //failure err = ParsingError.BadHostName; flags |= Flags.UnknownHostType; return idx; } } //success flags |= Flags.BasicHostType; if (iriParsing && hasUnicode && StaticNotAny(flags, Flags.HostUnicodeNormalized)) { // Normalize any other host string user = new string(pString, startOtherHost, startOtherHost - end); try { newHost += user.Normalize(NormalizationForm.FormC); } catch (ArgumentException) { err = ParsingError.BadFormat; return idx; } flags |= Flags.HostUnicodeNormalized; } } else if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || (syntax.InFact(UriSyntaxFlags.MailToLikeUri))) { err = ParsingError.BadHostName; flags |= Flags.UnknownHostType; return idx; } } } return (ushort)end; }
public override string ToString() { if ((this.m_username.Length == 0) && (this.m_password.Length > 0)) { throw new UriFormatException(SR.GetString("net_uri_BadUserPassword")); } if (this.m_scheme.Length != 0) { UriParser syntax = UriParser.GetSyntax(this.m_scheme); if (syntax != null) { this.m_schemeDelimiter = (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) || (((this.m_host.Length != 0) && syntax.NotAny(UriSyntaxFlags.MailToLikeUri)) && syntax.InFact(UriSyntaxFlags.OptionalAuthority))) ? System.Uri.SchemeDelimiter : ":"; } else { this.m_schemeDelimiter = (this.m_host.Length != 0) ? System.Uri.SchemeDelimiter : ":"; } } string str = (this.m_scheme.Length != 0) ? (this.m_scheme + this.m_schemeDelimiter) : string.Empty; string[] strArray = new string[] { str, this.m_username, (this.m_password.Length > 0) ? (":" + this.m_password) : string.Empty, (this.m_username.Length > 0) ? "@" : string.Empty, this.m_host, ((this.m_port != -1) && (this.m_host.Length > 0)) ? (":" + this.m_port) : string.Empty, (((this.m_host.Length > 0) && (this.m_path.Length != 0)) && (this.m_path[0] != '/')) ? "/" : string.Empty, this.m_path, this.m_query, this.m_fragment }; return(string.Concat(strArray)); }