static void Validate(UriTemplatePathPartiallyEquivalentSet pes, bool allowDuplicateEquivalentUriTemplates)
        {
            // A set with 0 or 1 items is valid by definition
            if (pes.Items.Count < 2)
            {
                return;
            }
            // Assert all paths are partially-equivalent
            for (int i = 0; i < pes.Items.Count - 1; ++i)
            {
                Fx.Assert(pes.Items[i].Key.IsPathPartiallyEquivalentAt(pes.Items[i + 1].Key, pes.SegmentsCount),
                          "all elements of a PES must be path partially-equivalent");
            }
            // We will check that the queries disambiguate only for templates, which are
            //  matched completely at the segments count; templates, which are match at
            //  that point due to terminal defaults, will be ruled out.
            UriTemplate[] a          = new UriTemplate[pes.Items.Count];
            int           arrayIndex = 0;

            foreach (KeyValuePair <UriTemplate, object> kvp in pes.Items)
            {
                if (pes.SegmentsCount < kvp.Key.segments.Count)
                {
                    continue;
                }
                Fx.Assert(arrayIndex < a.Length, "We made enough room for all the items");
                a[arrayIndex++] = kvp.Key;
            }
            // Ensure that queries disambiguate (if needed) :
            if (arrayIndex > 0)
            {
                UriTemplateHelpers.DisambiguateSamePath(a, 0, arrayIndex, allowDuplicateEquivalentUriTemplates);
            }
        }
Exemple #2
0
        void VerifyThatFastPathAndSlowPathHaveSameResults(Uri uri, Collection <string> fastPathRelativePathSegments,
                                                          IList <UriTemplateTableMatchCandidate> fastPathCandidates)
        {
            Collection <string> slowPathRelativePathSegments         = new Collection <string>();
            List <UriTemplateTableMatchCandidate> slowPathCandidates = new List <UriTemplateTableMatchCandidate>();

            if (!SlowComputeRelativeSegmentsAndLookup(uri, UriTemplateHelpers.GetUriPath(uri),
                                                      slowPathRelativePathSegments, slowPathCandidates))
            {
                Fx.Assert("fast path yielded a result but slow path yielded no result");
            }
            // compare results
            if (fastPathRelativePathSegments.Count != slowPathRelativePathSegments.Count)
            {
                Fx.Assert("fast path yielded different number of segments from slow path");
            }
            for (int i = 0; i < fastPathRelativePathSegments.Count; ++i)
            {
                if (fastPathRelativePathSegments[i] != slowPathRelativePathSegments[i])
                {
                    Fx.Assert("fast path yielded different segments from slow path");
                }
            }
            if (fastPathCandidates.Count != slowPathCandidates.Count)
            {
                Fx.Assert("fast path yielded different number of candidates from slow path");
            }
            for (int i = 0; i < fastPathCandidates.Count; i++)
            {
                if (!slowPathCandidates.Contains(fastPathCandidates[i]))
                {
                    Fx.Assert("fast path yielded different candidates from slow path");
                }
            }
        }
        public static UriTemplatePathSegment CreateFromUriTemplate(string segment, UriTemplate template)
        {
            // Identifying the type of segment - Literal|Compound|Variable
            switch (UriTemplateHelpers.IdentifyPartType(segment))
            {
            case UriTemplatePartType.Literal:
                return(UriTemplateLiteralPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Compound:
                return(UriTemplateCompoundPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Variable:
                if (segment.EndsWith("/", StringComparison.Ordinal))
                {
                    string varName = template.AddPathVariable(UriTemplatePartType.Variable,
                                                              segment.Substring(1, segment.Length - 3));
                    return(new UriTemplateVariablePathSegment(segment, true, varName));
                }
                else
                {
                    string varName = template.AddPathVariable(UriTemplatePartType.Variable,
                                                              segment.Substring(1, segment.Length - 2));
                    return(new UriTemplateVariablePathSegment(segment, false, varName));
                }

            default:
                Fx.Assert("Invalid value from IdentifyStringNature");
                return(null);
            }
        }
 private void ConstructFastPathTable()
 {
     this.noTemplateHasQueryPart = true;
     foreach (KeyValuePair <UriTemplate, object> pair in this.templates)
     {
         UriTemplate key = pair.Key;
         if (!UriTemplateHelpers.CanMatchQueryTrivially(key))
         {
             this.noTemplateHasQueryPart = false;
         }
         if (key.HasNoVariables && !key.HasWildcard)
         {
             if (this.fastPathTable == null)
             {
                 this.fastPathTable = new Dictionary <string, FastPathInfo>();
             }
             Uri    uri     = key.BindByPosition(this.originalUncanonicalizedBaseAddress, new string[0]);
             string uriPath = UriTemplateHelpers.GetUriPath(uri);
             if (!this.fastPathTable.ContainsKey(uriPath))
             {
                 FastPathInfo info = new FastPathInfo();
                 if (this.ComputeRelativeSegmentsAndLookup(uri, info.RelativePathSegments, info.Candidates))
                 {
                     info.Freeze();
                     this.fastPathTable.Add(uriPath, info);
                 }
             }
         }
     }
 }
        public static UriTemplateQueryValue CreateFromUriTemplate(string value, UriTemplate template)
        {
            // Checking for empty value
            if (value == null)
            {
                return(UriTemplateQueryValue.Empty);
            }
            // Identifying the type of value - Literal|Compound|Variable
            switch (UriTemplateHelpers.IdentifyPartType(value))
            {
            case UriTemplatePartType.Literal:
                return(UriTemplateLiteralQueryValue.CreateFromUriTemplate(value));

            case UriTemplatePartType.Compound:
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(
                                                                                                            SR.UTQueryCannotHaveCompoundValue, template.originalTemplate)));

            case UriTemplatePartType.Variable:
                return(new UriTemplateVariableQueryValue(template.AddQueryVariable(value.Substring(1, value.Length - 2))));

            default:
                Fx.Assert("Invalid value from IdentifyStringNature");
                return(null);
            }
        }
Exemple #6
0
 static bool AtLeastOneCandidateHasQueryPart(IList <UriTemplateTableMatchCandidate> candidates)
 {
     for (int i = 0; i < candidates.Count; i++)
     {
         if (!UriTemplateHelpers.CanMatchQueryTrivially(candidates[i].Template))
         {
             return(true);
         }
     }
     return(false);
 }
 void PopulateQueryParameters()
 {
     if (this.requestUri != null)
     {
         this.queryParameters = UriTemplateHelpers.ParseQueryString(this.requestUri.Query);
     }
     else
     {
         this.queryParameters = new NameValueCollection();
     }
 }
        private bool FastComputeRelativeSegmentsAndLookup(Uri uri, out Collection <string> relativePathSegments, out IList <UriTemplateTableMatchCandidate> candidates)
        {
            string       uriPath = UriTemplateHelpers.GetUriPath(uri);
            FastPathInfo info    = null;

            if ((this.fastPathTable != null) && this.fastPathTable.TryGetValue(uriPath, out info))
            {
                relativePathSegments = info.RelativePathSegments;
                candidates           = info.Candidates;
                return(true);
            }
            relativePathSegments = new Collection <string>();
            candidates           = new Collection <UriTemplateTableMatchCandidate>();
            return(this.SlowComputeRelativeSegmentsAndLookup(uri, uriPath, relativePathSegments, candidates));
        }
Exemple #9
0
        static bool NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(
            IList <UriTemplateTableMatchCandidate> candidates)
        {
            bool thereIsAmEmptyFallback = false;

            for (int i = 0; i < candidates.Count; i++)
            {
                if (UriTemplateHelpers.HasQueryLiteralRequirements(candidates[i].Template))
                {
                    return(false);
                }
                if (candidates[i].Template.queries.Count == 0)
                {
                    thereIsAmEmptyFallback = true;
                }
            }
            return(thereIsAmEmptyFallback);
        }
        public static UriTemplatePathSegment CreateFromUriTemplate(string segment, UriTemplate template)
        {
            switch (UriTemplateHelpers.IdentifyPartType(segment))
            {
            case UriTemplatePartType.Literal:
                return(UriTemplateLiteralPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Compound:
                return(UriTemplateCompoundPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Variable:
                if (!segment.EndsWith("/", StringComparison.Ordinal))
                {
                    return(new UriTemplateVariablePathSegment(segment, false, template.AddPathVariable(UriTemplatePartType.Variable, segment.Substring(1, segment.Length - 2))));
                }
                return(new UriTemplateVariablePathSegment(segment, true, template.AddPathVariable(UriTemplatePartType.Variable, segment.Substring(1, segment.Length - 3))));
            }
            return(null);
        }
 private void NormalizeBaseAddress()
 {
     if (this.baseAddress != null)
     {
         UriBuilder builder = new UriBuilder(this.baseAddress);
         if (!builder.Path.EndsWith("/", StringComparison.Ordinal))
         {
             builder.Path = builder.Path + "/";
         }
         builder.Host     = "localhost";
         builder.Port     = -1;
         builder.UserName = null;
         builder.Password = null;
         builder.Path     = builder.Path.ToUpperInvariant();
         builder.Scheme   = Uri.UriSchemeHttp;
         this.baseAddress = builder.Uri;
         this.basePath    = UriTemplateHelpers.GetUriPath(this.baseAddress);
     }
 }
        private static bool NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(IList <UriTemplateTableMatchCandidate> candidates)
        {
            bool flag = false;

            for (int i = 0; i < candidates.Count; i++)
            {
                UriTemplateTableMatchCandidate candidate = candidates[i];
                if (UriTemplateHelpers.HasQueryLiteralRequirements(candidate.Template))
                {
                    return(false);
                }
                UriTemplateTableMatchCandidate candidate2 = candidates[i];
                if (candidate2.Template.queries.Count == 0)
                {
                    flag = true;
                }
            }
            return(flag);
        }
Exemple #13
0
        public static UriTemplateQueryValue CreateFromUriTemplate(string value, UriTemplate template)
        {
            if (value == null)
            {
                return(Empty);
            }
            switch (UriTemplateHelpers.IdentifyPartType(value))
            {
            case UriTemplatePartType.Literal:
                return(UriTemplateLiteralQueryValue.CreateFromUriTemplate(value));

            case UriTemplatePartType.Compound:
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("UTQueryCannotHaveCompoundValue", new object[] { template.originalTemplate })));

            case UriTemplatePartType.Variable:
                return(new UriTemplateVariableQueryValue(template.AddQueryVariable(value.Substring(1, value.Length - 2))));
            }
            return(null);
        }
Exemple #14
0
 void NormalizeBaseAddress()
 {
     if (this.baseAddress != null)
     {
         // ensure trailing slash on baseAddress, so that IsBaseOf will work later
         UriBuilder ub = new UriBuilder(this.baseAddress);
         if (this.addTrailingSlashToBaseAddress && !ub.Path.EndsWith("/", StringComparison.Ordinal))
         {
             ub.Path = ub.Path + "/";
         }
         ub.Host          = "localhost"; // always normalize to localhost
         ub.Port          = -1;
         ub.UserName      = null;
         ub.Password      = null;
         ub.Path          = ub.Path.ToUpperInvariant();
         ub.Scheme        = Uri.UriSchemeHttp;
         this.baseAddress = ub.Uri;
         basePath         = UriTemplateHelpers.GetUriPath(this.baseAddress);
     }
 }
        private void VerifyThatFastPathAndSlowPathHaveSameResults(Uri uri, Collection <string> fastPathRelativePathSegments, IList <UriTemplateTableMatchCandidate> fastPathCandidates)
        {
            Collection <string> relativePathSegments         = new Collection <string>();
            List <UriTemplateTableMatchCandidate> candidates = new List <UriTemplateTableMatchCandidate>();

            this.SlowComputeRelativeSegmentsAndLookup(uri, UriTemplateHelpers.GetUriPath(uri), relativePathSegments, candidates);
            int count = relativePathSegments.Count;
            int num3  = fastPathRelativePathSegments.Count;

            for (int i = 0; i < fastPathRelativePathSegments.Count; i++)
            {
                bool flag1 = fastPathRelativePathSegments[i] != relativePathSegments[i];
            }
            int num4 = candidates.Count;
            int num5 = fastPathCandidates.Count;

            for (int j = 0; j < fastPathCandidates.Count; j++)
            {
                candidates.Contains(fastPathCandidates[j]);
            }
        }
 private static void Validate(UriTemplatePathPartiallyEquivalentSet pes, bool allowDuplicateEquivalentUriTemplates)
 {
     if (pes.Items.Count >= 2)
     {
         for (int i = 0; i < (pes.Items.Count - 1); i++)
         {
         }
         UriTemplate[] array = new UriTemplate[pes.Items.Count];
         int           b     = 0;
         foreach (KeyValuePair <UriTemplate, object> pair in pes.Items)
         {
             if (pes.SegmentsCount >= pair.Key.segments.Count)
             {
                 array[b++] = pair.Key;
             }
         }
         if (b > 0)
         {
             UriTemplateHelpers.DisambiguateSamePath(array, 0, b, allowDuplicateEquivalentUriTemplates);
         }
     }
 }
Exemple #17
0
        // this method checks the literal cache for a match if none, goes through the slower path of cracking the segments
        bool FastComputeRelativeSegmentsAndLookup(Uri uri, out Collection <string> relativePathSegments,
                                                  out IList <UriTemplateTableMatchCandidate> candidates)
        {
            // Consider fast-path and lookup
            // return false if not under base uri
            string       uriPath = UriTemplateHelpers.GetUriPath(uri);
            FastPathInfo fpInfo  = null;

            if ((this.fastPathTable != null) && this.fastPathTable.TryGetValue(uriPath, out fpInfo))
            {
                relativePathSegments = fpInfo.RelativePathSegments;
                candidates           = fpInfo.Candidates;
                VerifyThatFastPathAndSlowPathHaveSameResults(uri, relativePathSegments, candidates);
                return(true);
            }
            else
            {
                relativePathSegments = new Collection <string>();
                candidates           = new Collection <UriTemplateTableMatchCandidate>();
                return(SlowComputeRelativeSegmentsAndLookup(uri, uriPath, relativePathSegments, candidates));
            }
        }
Exemple #18
0
 void ConstructFastPathTable()
 {
     this.noTemplateHasQueryPart = true;
     foreach (KeyValuePair <UriTemplate, object> kvp in this.templates)
     {
         UriTemplate ut = kvp.Key;
         if (!UriTemplateHelpers.CanMatchQueryTrivially(ut))
         {
             this.noTemplateHasQueryPart = false;
         }
         if (ut.HasNoVariables && !ut.HasWildcard)
         {
             // eligible for fast path
             if (this.fastPathTable == null)
             {
                 this.fastPathTable = new Dictionary <string, FastPathInfo>();
             }
             Uri    uri     = ut.BindByPosition(this.originalUncanonicalizedBaseAddress);
             string uriPath = UriTemplateHelpers.GetUriPath(uri);
             if (this.fastPathTable.ContainsKey(uriPath))
             {
                 // nothing to do, we've already seen it
             }
             else
             {
                 FastPathInfo fpInfo = new FastPathInfo();
                 if (ComputeRelativeSegmentsAndLookup(uri, fpInfo.RelativePathSegments,
                                                      fpInfo.Candidates))
                 {
                     fpInfo.Freeze();
                     this.fastPathTable.Add(uriPath, fpInfo);
                 }
             }
         }
     }
 }
Exemple #19
0
        public Collection <UriTemplateMatch> Match(Uri uri)
        {
            if (uri == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri");
            }
            if (!uri.IsAbsoluteUri)
            {
                return(None());
            }

            this.MakeReadOnly(true);

            // Matching path :
            Collection <String> relativeSegments;
            IList <UriTemplateTableMatchCandidate> candidates;

            if (!FastComputeRelativeSegmentsAndLookup(uri, out relativeSegments, out candidates))
            {
                return(None());
            }
            // Matching query :
            NameValueCollection queryParameters = null;

            if (!this.noTemplateHasQueryPart && AtLeastOneCandidateHasQueryPart(candidates))
            {
                Collection <UriTemplateTableMatchCandidate> nextCandidates = new Collection <UriTemplateTableMatchCandidate>();
                Fx.Assert(nextCandidates.Count == 0, "nextCandidates should be empty");

                // then deal with query
                queryParameters = UriTemplateHelpers.ParseQueryString(uri.Query);
                bool mustBeEspeciallyInteresting = NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(candidates);
                for (int i = 0; i < candidates.Count; i++)
                {
                    if (UriTemplateHelpers.CanMatchQueryInterestingly(candidates[i].Template, queryParameters, mustBeEspeciallyInteresting))
                    {
                        nextCandidates.Add(candidates[i]);
                    }
                }
                if (nextCandidates.Count > 1)
                {
                    Fx.Assert(AllEquivalent(nextCandidates, 0, nextCandidates.Count), "demux algorithm problem, multiple non-equivalent matches");
                }

                if (nextCandidates.Count == 0)
                {
                    for (int i = 0; i < candidates.Count; i++)
                    {
                        if (UriTemplateHelpers.CanMatchQueryTrivially(candidates[i].Template))
                        {
                            nextCandidates.Add(candidates[i]);
                        }
                    }
                }
                if (nextCandidates.Count == 0)
                {
                    return(None());
                }
                if (nextCandidates.Count > 1)
                {
                    Fx.Assert(AllEquivalent(nextCandidates, 0, nextCandidates.Count), "demux algorithm problem, multiple non-equivalent matches");
                }

                candidates = nextCandidates;
            }
            // Verifying that we have not broken the allowDuplicates settings because of terminal defaults
            //  This situation can be caused when we are hosting ".../" and ".../{foo=xyz}" in the same
            //  table. They are not equivalent; yet they reside together in the same path partially-equivalent
            //  set. If we hit a uri that ends up in that particular end-of-path set, we want to provide the
            //  user only the 'best' match and not both; thus preventing inconsistancy between the MakeReadonly
            //  settings and the matching results. We will assume that the 'best' matches will be the ones with
            //  the smallest number of segments - this will prefer ".../" over ".../{x=1}[/...]".
            if (NotAllCandidatesArePathFullyEquivalent(candidates))
            {
                Collection <UriTemplateTableMatchCandidate> nextCandidates = new Collection <UriTemplateTableMatchCandidate>();
                int minSegmentsCount = -1;
                for (int i = 0; i < candidates.Count; i++)
                {
                    UriTemplateTableMatchCandidate candidate = candidates[i];
                    if (minSegmentsCount == -1)
                    {
                        minSegmentsCount = candidate.Template.segments.Count;
                        nextCandidates.Add(candidate);
                    }
                    else if (candidate.Template.segments.Count < minSegmentsCount)
                    {
                        minSegmentsCount = candidate.Template.segments.Count;
                        nextCandidates.Clear();
                        nextCandidates.Add(candidate);
                    }
                    else if (candidate.Template.segments.Count == minSegmentsCount)
                    {
                        nextCandidates.Add(candidate);
                    }
                }
                Fx.Assert(minSegmentsCount != -1, "At least the first entry in the list should be kept");
                Fx.Assert(nextCandidates.Count >= 1, "At least the first entry in the list should be kept");
                Fx.Assert(nextCandidates[0].Template.segments.Count == minSegmentsCount, "Trivial");
                candidates = nextCandidates;
            }

            // Building the actual result
            Collection <UriTemplateMatch> actualResults = new Collection <UriTemplateMatch>();

            for (int i = 0; i < candidates.Count; i++)
            {
                UriTemplateTableMatchCandidate candidate = candidates[i];
                UriTemplateMatch match = candidate.Template.CreateUriTemplateMatch(this.originalUncanonicalizedBaseAddress,
                                                                                   uri, candidate.Data, candidate.SegmentsCount, relativeSegments, queryParameters);
                actualResults.Add(match);
            }
            return(actualResults);
        }
        public Collection <UriTemplateMatch> Match(Uri uri)
        {
            Collection <string> collection;
            IList <UriTemplateTableMatchCandidate> list;

            if (uri == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri");
            }
            if (!uri.IsAbsoluteUri)
            {
                return(None());
            }
            this.MakeReadOnly(true);
            if (!this.FastComputeRelativeSegmentsAndLookup(uri, out collection, out list))
            {
                return(None());
            }
            NameValueCollection query = null;

            if (!this.noTemplateHasQueryPart && AtLeastOneCandidateHasQueryPart(list))
            {
                Collection <UriTemplateTableMatchCandidate> collection2 = new Collection <UriTemplateTableMatchCandidate>();
                query = UriTemplateHelpers.ParseQueryString(uri.Query);
                bool mustBeEspeciallyInteresting = NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(list);
                for (int j = 0; j < list.Count; j++)
                {
                    UriTemplateTableMatchCandidate candidate3 = list[j];
                    if (UriTemplateHelpers.CanMatchQueryInterestingly(candidate3.Template, query, mustBeEspeciallyInteresting))
                    {
                        collection2.Add(list[j]);
                    }
                }
                int count = collection2.Count;
                if (collection2.Count == 0)
                {
                    for (int k = 0; k < list.Count; k++)
                    {
                        UriTemplateTableMatchCandidate candidate4 = list[k];
                        if (UriTemplateHelpers.CanMatchQueryTrivially(candidate4.Template))
                        {
                            collection2.Add(list[k]);
                        }
                    }
                }
                if (collection2.Count == 0)
                {
                    return(None());
                }
                int num6 = collection2.Count;
                list = collection2;
            }
            if (NotAllCandidatesArePathFullyEquivalent(list))
            {
                Collection <UriTemplateTableMatchCandidate> collection3 = new Collection <UriTemplateTableMatchCandidate>();
                int num3 = -1;
                for (int m = 0; m < list.Count; m++)
                {
                    UriTemplateTableMatchCandidate item = list[m];
                    if (num3 == -1)
                    {
                        num3 = item.Template.segments.Count;
                        collection3.Add(item);
                    }
                    else if (item.Template.segments.Count < num3)
                    {
                        num3 = item.Template.segments.Count;
                        collection3.Clear();
                        collection3.Add(item);
                    }
                    else if (item.Template.segments.Count == num3)
                    {
                        collection3.Add(item);
                    }
                }
                list = collection3;
            }
            Collection <UriTemplateMatch> collection4 = new Collection <UriTemplateMatch>();

            for (int i = 0; i < list.Count; i++)
            {
                UriTemplateTableMatchCandidate candidate2 = list[i];
                UriTemplateMatch match = candidate2.Template.CreateUriTemplateMatch(this.originalUncanonicalizedBaseAddress, uri, candidate2.Data, candidate2.SegmentsCount, collection, query);
                collection4.Add(match);
            }
            return(collection4);
        }