GetParts() private method

private GetParts ( UriComponents uriParts, UriFormat formatAs ) : string
uriParts UriComponents
formatAs UriFormat
return string
Beispiel #1
0
        //
        // This is for languages that do not support == != operators overloading
        //
        // Note that Uri.Equals will get an optimized path but is limited to true/fasle result only
        //
        public static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat,
                                  StringComparison comparisonType)
        {
            if ((object)uri1 == null)
            {
                if (uri2 == null)
                {
                    return(0); // Equal
                }
                return(-1);    // null < non-null
            }
            if ((object)uri2 == null)
            {
                return(1);     // non-null > null
            }
            // a relative uri is always less than an absolute one
            if (!uri1.IsAbsoluteUri || !uri2.IsAbsoluteUri)
            {
                return(uri1.IsAbsoluteUri ? 1 : uri2.IsAbsoluteUri ? -1 : string.Compare(uri1.OriginalString,
                                                                                         uri2.OriginalString, comparisonType));
            }

            return(string.Compare(
                       uri1.GetParts(partsToCompare, compareFormat),
                       uri2.GetParts(partsToCompare, compareFormat),
                       comparisonType
                       ));
        }
 internal void FetchRequest(System.Uri uri, WebRequest request)
 {
     this._Request              = request;
     this._Policy               = request.CachePolicy;
     this._Response             = null;
     this._ResponseCount        = 0;
     this._ValidationStatus     = CacheValidationStatus.DoNotUseCache;
     this._CacheFreshnessStatus = System.Net.Cache.CacheFreshnessStatus.Undefined;
     this._CacheStream          = null;
     this._CacheStreamOffset    = 0L;
     this._CacheStreamLength    = 0L;
     if (!uri.Equals(this._Uri))
     {
         this._CacheKey = uri.GetParts(UriComponents.AbsoluteUri, UriFormat.Unescaped);
     }
     this._Uri = uri;
 }
Beispiel #3
0
        //
        // Resolves into either baseUri or relativeUri according to conditions OR if not possible it uses newUriString
        // to  return combined URI strings from both Uris
        // otherwise if e != null on output the operation has failed
        //
        internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped,
                                          out UriFormatException e)
        {
            Debug.Assert(!baseUri.IsNotAbsoluteUri && !baseUri.UserDrivenParsing, "Uri::ResolveHelper()|baseUri is not Absolute or is controlled by User Parser.");

            e = null;
            string relativeStr = string.Empty;

            if ((object)relativeUri != null)
            {
                if (relativeUri.IsAbsoluteUri)
                {
                    return(relativeUri);
                }

                relativeStr = relativeUri.OriginalString;
                userEscaped = relativeUri.UserEscaped;
            }
            else
            {
                relativeStr = string.Empty;
            }

            // Here we can assert that passed "relativeUri" is indeed a relative one

            if (relativeStr.Length > 0 && (IsLWS(relativeStr[0]) || IsLWS(relativeStr[relativeStr.Length - 1])))
            {
                relativeStr = relativeStr.Trim(s_WSchars);
            }

            if (relativeStr.Length == 0)
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri,
                                                baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
                return(null);
            }

            // Check for a simple fragment in relative part
            if (relativeStr[0] == '#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment,
                                                UriFormat.UriEscaped) + relativeStr;
                return(null);
            }

            // Check for a simple query in relative part
            if (relativeStr[0] == '?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Query & ~UriComponents.Fragment,
                                                UriFormat.UriEscaped) + relativeStr;
                return(null);
            }

            // Check on the DOS path in the relative Uri (a special case)
            if (relativeStr.Length >= 3 &&
                (relativeStr[1] == ':' || relativeStr[1] == '|') &&
                IsAsciiLetter(relativeStr[0]) &&
                (relativeStr[2] == '\\' || relativeStr[2] == '/'))
            {
                if (baseUri.IsImplicitFile)
                {
                    // It could have file:/// prepended to the result but we want to keep it as *Implicit* File Uri
                    newUriString = relativeStr;
                    return(null);
                }
                else if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
                {
                    // The scheme is not changed just the path gets replaced
                    string prefix;
                    if (baseUri.InFact(Flags.AuthorityFound))
                    {
                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://";
                    }
                    else
                    {
                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":";
                    }

                    newUriString = baseUri.Scheme + prefix + relativeStr;
                    return(null);
                }
                // If we are here then input like "http://host/path/" + "C:\x" will produce the result  http://host/path/c:/x
            }


            ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString);

            if (err != ParsingError.None)
            {
                e = GetException(err);
                return(null);
            }

            if ((object)newUriString == (object)baseUri._string)
            {
                return(baseUri);
            }

            return(null);
        }
        /*-------------- internal members -------------*/
        //
        internal void FetchRequest(Uri uri, WebRequest request)
        {
            _Request = request;
            _Policy  = request.CachePolicy;
            _Response = null;
            _ResponseCount = 0;
            _ValidationStatus     = CacheValidationStatus.DoNotUseCache;
            _CacheFreshnessStatus = CacheFreshnessStatus.Undefined;
            _CacheStream          = null;
            _CacheStreamOffset    = 0L;
            _CacheStreamLength    = 0L;

            if (!uri.Equals(_Uri))
            {
                // it's changed from previous call
                _CacheKey = uri.GetParts(UriComponents.AbsoluteUri, UriFormat.Unescaped);
            }
            _Uri = uri;
        }
Beispiel #5
0
        //
        //
        // This is for languages that do not support == != operators overloading
        //
        // Note that Uri.Equals will get an optimized path but is limited to true/fasle result only
        //
        public static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat, 
            StringComparison comparisonType)
        {

            if ((object) uri1 == null)
            {
                if (uri2 == null)
                    return 0; // Equal
                return -1;    // null < non-null
            }
            if ((object) uri2 == null)
                return 1;     // non-null > null

            // a relative uri is always less than an absolute one
            if (!uri1.IsAbsoluteUri || !uri2.IsAbsoluteUri)
                return uri1.IsAbsoluteUri? 1: uri2.IsAbsoluteUri? -1: string.Compare(uri1.OriginalString, 
                    uri2.OriginalString, comparisonType);

            return string.Compare(
                                    uri1.GetParts(partsToCompare, compareFormat),
                                    uri2.GetParts(partsToCompare, compareFormat),
                                    comparisonType
                                  );
        }
Beispiel #6
0
        //
        //
        //
        internal bool IsBaseOfHelper(Uri uriLink)
        {
            //TO 
            if (!IsAbsoluteUri || UserDrivenParsing)
                return false;

            if (!uriLink.IsAbsoluteUri)
            {
                //a relative uri could have quite tricky form, it's better to fix it now.
                string newUriString = null;
                UriFormatException e;
                bool dontEscape = false;

                uriLink = ResolveHelper(this, uriLink, ref newUriString, ref dontEscape, out e);
                if (e != null)
                    return false;

                if ((object)uriLink == null)
                    uriLink = CreateHelper(newUriString, dontEscape, UriKind.Absolute, ref e);

                if (e != null)
                    return false;
            }

            if (Syntax.SchemeName != uriLink.Syntax.SchemeName)
                return false;

            // Canonicalize and test for substring match up to the last path slash
            string me = GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);
            string she = uriLink.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);

            unsafe
            {
                fixed (char* pMe = me)
                {
                    fixed (char* pShe = she)
                    {
                        return UriHelper.TestForSubPath(pMe, (ushort)me.Length, pShe, (ushort)she.Length, 
                            IsUncOrDosPath || uriLink.IsUncOrDosPath);
                    }
                }
            }
        }
Beispiel #7
0
        //
        // Resolves into either baseUri or relativeUri according to conditions OR if not possible it uses newUriString 
        // to  return combined URI strings from both Uris 
        // otherwise if e != null on output the operation has failed
        //

        internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped, 
            out UriFormatException e)
        {
            Debug.Assert(!baseUri.IsNotAbsoluteUri && !baseUri.UserDrivenParsing, "Uri::ResolveHelper()|baseUri is not Absolute or is controlled by User Parser.");

            e = null;
            string relativeStr = string.Empty;

            if ((object)relativeUri != null)
            {
                if (relativeUri.IsAbsoluteUri)
                    return relativeUri;

                relativeStr = relativeUri.OriginalString;
                userEscaped = relativeUri.UserEscaped;
            }
            else
                relativeStr = string.Empty;

            // Here we can assert that passed "relativeUri" is indeed a relative one

            if (relativeStr.Length > 0 && (IsLWS(relativeStr[0]) || IsLWS(relativeStr[relativeStr.Length - 1])))
                relativeStr = relativeStr.Trim(_WSchars);

            if (relativeStr.Length == 0)
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri, 
                    baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
                return null;
            }

            // Check for a simple fragment in relative part
            if (relativeStr[0] == '#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, 
                    UriFormat.UriEscaped) + relativeStr;
                return null;
            }
            
            // Check for a simple query in relative part
            if (relativeStr[0] == '?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
            {
                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Query & ~UriComponents.Fragment, 
                    UriFormat.UriEscaped) + relativeStr;
                return null;
            }
            
            // Check on the DOS path in the relative Uri (a special case)
            if (relativeStr.Length >= 3
                && (relativeStr[1] == ':' || relativeStr[1] == '|')
                && IsAsciiLetter(relativeStr[0])
                && (relativeStr[2] == '\\' || relativeStr[2] == '/'))
            {

                if (baseUri.IsImplicitFile)
                {
                    // It could have file:/// prepended to the result but we want to keep it as *Implicit* File Uri
                    newUriString = relativeStr;
                    return null;
                }
                else if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
                {
                    // The scheme is not changed just the path gets replaced
                    string prefix;
                    if (baseUri.InFact(Flags.AuthorityFound))
                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://";
                    else
                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":";

                    newUriString = baseUri.Scheme + prefix + relativeStr;
                    return null;
                }
                // If we are here then input like "http://host/path/" + "C:\x" will produce the result  http://host/path/c:/x
            }


            ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString);

            if (err != ParsingError.None)
            {
                e = GetException(err);
                return null;
            }

            if ((object)newUriString == (object)baseUri.m_String)
                return baseUri;

            return null;
        }
 internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped, out UriFormatException e)
 {
     e = null;
     string relativeStr = string.Empty;
     if (relativeUri != null)
     {
         if (relativeUri.IsAbsoluteUri)
         {
             return relativeUri;
         }
         relativeStr = relativeUri.OriginalString;
         userEscaped = relativeUri.UserEscaped;
     }
     else
     {
         relativeStr = string.Empty;
     }
     if ((relativeStr.Length > 0) && (IsLWS(relativeStr[0]) || IsLWS(relativeStr[relativeStr.Length - 1])))
     {
         relativeStr = relativeStr.Trim(_WSchars);
     }
     if (relativeStr.Length == 0)
     {
         newUriString = baseUri.GetParts(UriComponents.AbsoluteUri, baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
         return null;
     }
     if (((relativeStr[0] == '#') && !baseUri.IsImplicitFile) && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
     {
         newUriString = baseUri.GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.UriEscaped) + relativeStr;
         return null;
     }
     if (((relativeStr[0] == '?') && !baseUri.IsImplicitFile) && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
     {
         newUriString = baseUri.GetParts(UriComponents.Path | UriComponents.SchemeAndServer | UriComponents.UserInfo, UriFormat.UriEscaped) + relativeStr;
         return null;
     }
     if (((relativeStr.Length >= 3) && ((relativeStr[1] == ':') || (relativeStr[1] == '|'))) && (IsAsciiLetter(relativeStr[0]) && ((relativeStr[2] == '\\') || (relativeStr[2] == '/'))))
     {
         if (baseUri.IsImplicitFile)
         {
             newUriString = relativeStr;
             return null;
         }
         if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
         {
             string str2;
             if (baseUri.InFact(Flags.AuthorityFound))
             {
                 str2 = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://";
             }
             else
             {
                 str2 = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":";
             }
             newUriString = baseUri.Scheme + str2 + relativeStr;
             return null;
         }
     }
     ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString);
     if (err != ParsingError.None)
     {
         e = GetException(err);
         return null;
     }
     if (newUriString == baseUri.m_String)
     {
         return baseUri;
     }
     return null;
 }
 public Uri MakeRelativeUri(Uri uri)
 {
     if (uri == null)
     {
         throw new ArgumentNullException("uri");
     }
     if (this.IsNotAbsoluteUri || uri.IsNotAbsoluteUri)
     {
         throw new InvalidOperationException(System.SR.GetString("net_uri_NotAbsolute"));
     }
     if ((!(this.Scheme == uri.Scheme) || !(this.Host == uri.Host)) || (this.Port != uri.Port))
     {
         return uri;
     }
     string absolutePath = uri.AbsolutePath;
     string uriString = PathDifference(this.AbsolutePath, absolutePath, !this.IsUncOrDosPath);
     if (CheckForColonInFirstPathSegment(uriString) && (!uri.IsDosPath || !absolutePath.Equals(uriString, StringComparison.Ordinal)))
     {
         uriString = "./" + uriString;
     }
     return new Uri(uriString + uri.GetParts(UriComponents.Fragment | UriComponents.Query, UriFormat.UriEscaped), UriKind.Relative);
 }
 internal unsafe bool IsBaseOfHelper(Uri uriLink)
 {
     if (!this.IsAbsoluteUri || this.UserDrivenParsing)
     {
         return false;
     }
     if (!uriLink.IsAbsoluteUri)
     {
         UriFormatException exception;
         string newUriString = null;
         bool userEscaped = false;
         uriLink = ResolveHelper(this, uriLink, ref newUriString, ref userEscaped, out exception);
         if (exception != null)
         {
             return false;
         }
         if (uriLink == null)
         {
             uriLink = CreateHelper(newUriString, userEscaped, UriKind.Absolute, ref exception);
         }
         if (exception != null)
         {
             return false;
         }
     }
     if (this.Syntax.SchemeName != uriLink.Syntax.SchemeName)
     {
         return false;
     }
     string parts = this.GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.SafeUnescaped);
     string str3 = uriLink.GetParts(UriComponents.HttpRequestUrl | UriComponents.UserInfo, UriFormat.SafeUnescaped);
     fixed (char* str4 = ((char*) parts))
     {
         char* pMe = str4;
         fixed (char* str5 = ((char*) str3))
         {
             char* pShe = str5;
             return TestForSubPath(pMe, (ushort) parts.Length, pShe, (ushort) str3.Length, this.IsUncOrDosPath || uriLink.IsUncOrDosPath);
         }
     }
 }
 public static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat, StringComparison comparisonType)
 {
     if (uri1 == null)
     {
         if (uri2 == null)
         {
             return 0;
         }
         return -1;
     }
     if (uri2 == null)
     {
         return 1;
     }
     if (uri1.IsAbsoluteUri && uri2.IsAbsoluteUri)
     {
         return string.Compare(uri1.GetParts(partsToCompare, compareFormat), uri2.GetParts(partsToCompare, compareFormat), comparisonType);
     }
     if (uri1.IsAbsoluteUri)
     {
         return 1;
     }
     if (!uri2.IsAbsoluteUri)
     {
         return string.Compare(uri1.OriginalString, uri2.OriginalString, comparisonType);
     }
     return -1;
 }
 private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat)
 {
     string parts;
     int length;
     char[] chArray;
     char ch = relativePart[0];
     if ((basePart.IsDosPath && ((ch == '/') || (ch == '\\'))) && ((relativePart.Length == 1) || ((relativePart[1] != '/') && (relativePart[1] != '\\'))))
     {
         int index = basePart.OriginalString.IndexOf(':');
         if (!basePart.IsImplicitFile)
         {
             index = basePart.OriginalString.IndexOf(':', index + 1);
         }
         return (basePart.OriginalString.Substring(0, index + 1) + relativePart);
     }
     if (!StaticIsFile(basePart.Syntax) || ((ch != '\\') && (ch != '/')))
     {
         bool flag = basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);
         parts = null;
         if ((ch == '/') || ((ch == '\\') && flag))
         {
             if ((relativePart.Length >= 2) && (relativePart[1] == '/'))
             {
                 return (basePart.Scheme + ':' + relativePart);
             }
             if (basePart.HostType == (Flags.HostNotParsed | Flags.IPv6HostType))
             {
                 parts = string.Concat(new object[] { basePart.GetParts(UriComponents.UserInfo | UriComponents.Scheme, uriFormat), '[', basePart.DnsSafeHost, ']', basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat) });
             }
             else
             {
                 parts = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
             }
             if (flag && (ch == '\\'))
             {
                 relativePart = '/' + relativePart.Substring(1);
             }
             return (parts + relativePart);
         }
         parts = basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Path, basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
         length = parts.Length;
         chArray = new char[length + relativePart.Length];
         if (length > 0)
         {
             parts.CopyTo(0, chArray, 0, length);
             while (length > 0)
             {
                 if (chArray[--length] == '/')
                 {
                     length++;
                     break;
                 }
             }
         }
     }
     else
     {
         if ((relativePart.Length >= 2) && ((relativePart[1] == '\\') || (relativePart[1] == '/')))
         {
             if (!basePart.IsImplicitFile)
             {
                 return ("file:" + relativePart);
             }
             return relativePart;
         }
         if (!basePart.IsUnc)
         {
             return ("file://" + relativePart);
         }
         string str = basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Path, UriFormat.Unescaped);
         for (int i = 1; i < str.Length; i++)
         {
             if (str[i] == '/')
             {
                 str = str.Substring(0, i);
                 break;
             }
         }
         if (basePart.IsImplicitFile)
         {
             return (@"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped) + str + relativePart);
         }
         return ("file://" + basePart.GetParts(UriComponents.Host, uriFormat) + str + relativePart);
     }
     relativePart.CopyTo(0, chArray, length, relativePart.Length);
     ch = basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : ((char) 0xffff);
     char ch2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' : ((char) 0xffff);
     string str3 = string.Empty;
     if ((ch == 0xffff) && (ch2 == 0xffff))
     {
         length += relativePart.Length;
     }
     else
     {
         int startIndex = 0;
         while (startIndex < relativePart.Length)
         {
             if ((chArray[length + startIndex] == ch) || (chArray[length + startIndex] == ch2))
             {
                 break;
             }
             startIndex++;
         }
         if (startIndex == 0)
         {
             str3 = relativePart;
         }
         else if (startIndex < relativePart.Length)
         {
             str3 = relativePart.Substring(startIndex);
         }
         length += startIndex;
     }
     if (basePart.HostType == (Flags.HostNotParsed | Flags.IPv6HostType))
     {
         if (basePart.IsImplicitFile)
         {
             parts = @"\\[" + basePart.DnsSafeHost + ']';
         }
         else
         {
             parts = string.Concat(new object[] { basePart.GetParts(UriComponents.UserInfo | UriComponents.Scheme, uriFormat), '[', basePart.DnsSafeHost, ']', basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat) });
         }
     }
     else if (basePart.IsImplicitFile)
     {
         if (basePart.IsDosPath)
         {
             return (new string(Compress(chArray, 3, ref length, basePart.Syntax), 1, length - 1) + str3);
         }
         parts = @"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
     }
     else
     {
         parts = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
     }
     chArray = Compress(chArray, basePart.SecuredPathIndex, ref length, basePart.Syntax);
     return (parts + new string(chArray, 0, length) + str3);
 }
Beispiel #13
0
        //
        // CombineUri
        //
        //  Given 2 URI strings, combine them into a single resultant URI string
        //
        // Inputs:
        //  <argument>  basePart
        //      Base URI to combine with
        //
        //  <argument>  relativePart
        //      String expected to be relative URI
        //
        // Assumes:
        //  <basePart> is in canonic form
        //
        // Returns:
        //  Resulting combined URI string
        //
        private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat)
        {
            //NB: relativePart is ensured as not empty by the caller
            //    Another assumption is that basePart is an AbsoluteUri

            // This method was not optimized for efficiency
            // Means a relative Uri ctor may be relatively slow plus it increases the footprint of the baseUri

            char c1 = relativePart[0];

            //check a special case for the base as DOS path and a rooted relative string
            if (basePart.IsDosPath &&
                (c1 == '/' || c1 == '\\') &&
                (relativePart.Length == 1 || (relativePart[1] != '/' && relativePart[1] != '\\')))
            {
                // take relative part appended to the base string after the drive letter
                int idx = basePart.OriginalString.IndexOf(':');
                if (basePart.IsImplicitFile)
                {
                    return basePart.OriginalString.Substring(0, idx + 1) + relativePart;
                }
                // The basePart has explicit scheme (could be not file:), take the DOS drive ':' position
                idx = basePart.OriginalString.IndexOf(':', idx + 1);
                return basePart.OriginalString.Substring(0, idx + 1) + relativePart;
            }

            // Check special case for Unc or absolute path in relativePart when base is FILE
            if (StaticIsFile(basePart.Syntax))
            {
                if (c1 == '\\' || c1 == '/')
                {
                    if (relativePart.Length >= 2 && (relativePart[1] == '\\' || relativePart[1] == '/'))
                    {
                        //Assuming relative is a Unc path and base is a file uri.
                        return basePart.IsImplicitFile ? relativePart : "file:" + relativePart;
                    }

                    // here we got an absolute path in relativePart,
                    // For compatibility with V1.0 parser we restrict the compression scope to Unc Share, i.e. \\host\share\
                    if (basePart.IsUnc)
                    {
                        string share = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter,
                            UriFormat.Unescaped);
                        for (int i = 1; i < share.Length; ++i)
                        {
                            if (share[i] == '/')
                            {
                                share = share.Substring(0, i);
                                break;
                            }
                        }
                        if (basePart.IsImplicitFile)
                        {
                            return @"\\"
                                    + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped)
                                    + share
                                    + relativePart;
                        }
                        return "file://"
                                + basePart.GetParts(UriComponents.Host, uriFormat)
                                + share
                                + relativePart;
                    }
                    // It's not obvious but we've checked (for this relativePart format) that baseUti is nor UNC nor DOS path
                    //
                    // Means base is a Unix style path and, btw, IsImplicitFile cannot be the case either
                    return "file://" + relativePart;
                }
            }

            // If we are here we did not recognize absolute DOS/UNC path for a file: base uri
            // Note that DOS path may still happen in the relativePart and if so it may override the base uri scheme.

            bool convBackSlashes = basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);

            string left = null;

            // check for network or local absolute path
            if (c1 == '/' || (c1 == '\\' && convBackSlashes))
            {
                if (relativePart.Length >= 2 && relativePart[1] == '/')
                {
                    // got an authority in relative path and the base scheme is not file (checked)
                    return basePart.Scheme + ':' + relativePart;
                }

                // Got absolute relative path, and the base is nor FILE nor a DOS path (checked at the method start)
                if (basePart.HostType == Flags.IPv6HostType)
                {
                    left = basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat)
                                     + '[' + basePart.DnsSafeHost + ']'
                                     + basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat);
                }
                else
                {
                    left = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
                }

                if (convBackSlashes && c1 == '\\')
                    relativePart = '/' + relativePart.Substring(1);

                return left + relativePart;
            }

            // Here we got a relative path
            // Need to run path Compression because this is how relative Uri combining works

            // Take the base part path up to and including the last slash
            left = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter,
                basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
            int length = left.Length;
            char[] path = new char[length + relativePart.Length];

            if (length > 0)
            {
                left.CopyTo(0, path, 0, length);
                while (length > 0)
                {
                    if (path[--length] == '/')
                    {
                        ++length;
                        break;
                    }
                }
            }

            //Append relative path to the result
            relativePart.CopyTo(0, path, length, relativePart.Length);

            // Split relative on path and extra (for compression)
            c1 = basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : c_DummyChar;

            // The  implicit file check is to avoid a fragment in the implicit file combined uri.
            char c2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' :
                c_DummyChar;
            string extra = string.Empty;

            // assuming c_DummyChar may not happen in an unicode uri string
            if (!(c1 == c_DummyChar && c2 == c_DummyChar))
            {
                int i = 0;
                for (; i < relativePart.Length; ++i)
                {
                    if (path[length + i] == c1 || path[length + i] == c2)
                    {
                        break;
                    }
                }
                if (i == 0)
                {
                    extra = relativePart;
                }
                else if (i < relativePart.Length)
                {
                    extra = relativePart.Substring(i);
                }
                length += i;
            }
            else
            {
                length += relativePart.Length;
            }

            // Take the base part up to the path
            if (basePart.HostType == Flags.IPv6HostType)
            {
                if (basePart.IsImplicitFile)
                {
                    left = @"\\[" + basePart.DnsSafeHost + ']';
                }
                else
                {
                    left = basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat)
                            + '[' + basePart.DnsSafeHost + ']'
                            + basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat);
                }
            }
            else
            {
                if (basePart.IsImplicitFile)
                {
                    if (basePart.IsDosPath)
                    {
                        // The FILE DOS path comes as /c:/path, we have to exclude first 3 chars from compression
                        path = Compress(path, 3, ref length, basePart.Syntax);
                        return new string(path, 1, length - 1) + extra;
                    }
                    else
                    {
                        left = @"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
                    }
                }
                else
                {
                    left = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
                }
            }
            //compress the path
            path = Compress(path, basePart.SecuredPathIndex, ref length, basePart.Syntax);
            return left + new string(path, 0, length) + extra;
        }
Beispiel #14
0
        public Uri MakeRelativeUri(Uri uri)
        {
            if ((object)uri == null)
                throw new ArgumentNullException(nameof(uri));

            if (IsNotAbsoluteUri || uri.IsNotAbsoluteUri)
                throw new InvalidOperationException(SR.net_uri_NotAbsolute);

            // Note that the UserInfo part is ignored when computing a relative Uri.
            if ((Scheme == uri.Scheme) && (Host == uri.Host) && (Port == uri.Port))
            {
                string otherPath = uri.AbsolutePath;

                // Relative Path
                string relativeUriString = PathDifference(AbsolutePath, otherPath, !IsUncOrDosPath);

                // Relative Uri's cannot have a colon ':' in the first path segment (RFC 3986, Section 4.2)
                if (CheckForColonInFirstPathSegment(relativeUriString)
                    // Except for full implicit dos file paths
                    && !(uri.IsDosPath && otherPath.Equals(relativeUriString, StringComparison.Ordinal)))
                    relativeUriString = "./" + relativeUriString;

                // Query & Fragment
                relativeUriString += uri.GetParts(UriComponents.Query | UriComponents.Fragment, UriFormat.UriEscaped);

                return new Uri(relativeUriString, UriKind.Relative);
            }
            return uri;
        }
Beispiel #15
0
        //
        // Private stuff: We want to serialize on updates on one thread
        //
        private static string GetCanonicalKey(string key)
        {
            if( key == null ) {
                throw new ArgumentNullException("key");
            }
            try {
                Uri uri = new Uri(key);
                key = uri.GetParts(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.SafeUnescaped);
#if !DISABLE_CAS_USE
                new WebPermission(NetworkAccess.Connect, new Uri(key)).Demand();
#endif
            }
            catch(UriFormatException e) {
                throw new ArgumentException(SR.GetString(SR.net_mustbeuri, "key"), "key", e);
            }
            return key;
        }