Пример #1
0
        /// <summary>
        /// Returns list of segments in the specified path (eg: /abc/pqr -&gt; abc, pqr).
        /// </summary>
        /// <param name="absoluteUri">The absolute URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>List of unescaped segments.</returns>
        internal List <string> EnumerateSegments(Uri absoluteUri, Uri serviceBaseUri)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(absoluteUri != null, "absoluteUri != null");
            Debug.Assert(absoluteUri.IsAbsoluteUri, "absoluteRequestUri.IsAbsoluteUri(" + absoluteUri.IsAbsoluteUri + ")");
            Debug.Assert(serviceBaseUri != null, "serviceBaseUri != null");
            Debug.Assert(serviceBaseUri.IsAbsoluteUri, "serviceBaseUri.IsAbsoluteUri(" + serviceBaseUri + ")");

            //// This is a copy of the RequestUriProcessor.EnumerateSegments

            // COMPAT 29: Slash in key lookup breaks URI parser
            // TODO: The code below has a bug that / in the named values will be considered a segment separator
            //   so for example /Customers('abc/pqr') is treated as two segments, which is wrong.
            if (!UriUtils.UriInvariantInsensitiveIsBaseOf(serviceBaseUri, absoluteUri))
            {
                throw new ODataException(Strings.UriQueryPathParser_RequestUriDoesNotHaveTheCorrectBaseUri(absoluteUri, serviceBaseUri));
            }

            try
            {
                Uri uri = absoluteUri;
                int numberOfSegmentsToSkip = 0;

                // Skip over the base URI segments
#if SILVERLIGHT
                numberOfSegmentsToSkip = serviceBaseUri.AbsolutePath.Split('/').Length;
                string[] uriSegments = uri.AbsolutePath.Split('/');
#else
                numberOfSegmentsToSkip = serviceBaseUri.Segments.Length;
                string[] uriSegments = uri.Segments;
#endif

                List <string> segments = new List <string>();
                for (int i = numberOfSegmentsToSkip; i < uriSegments.Length; i++)
                {
                    string segment = uriSegments[i];
                    if (segment.Length != 0 && segment != "/")
                    {
                        if (segment[segment.Length - 1] == '/')
                        {
                            segment = segment.Substring(0, segment.Length - 1);
                        }

                        if (segments.Count == this.maxSegments)
                        {
                            throw new ODataException(Strings.UriQueryPathParser_TooManySegments);
                        }

                        segments.Add(Uri.UnescapeDataString(segment));
                    }
                }

                return(segments);
            }
            catch (UriFormatException uriFormatException)
            {
                throw new ODataException(Strings.UriQueryPathParser_SyntaxError, uriFormatException);
            }
        }
Пример #2
0
        /// <summary>
        /// Returns list of segments in the specified path (eg: /foo/bar -&gt; foo, bar).
        /// </summary>
        /// <param name="absoluteUri">The absolute URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>List of unescaped segments.</returns>
        private List <string> EnumerateSegments(Uri absoluteUri, Uri serviceBaseUri)
        {
            Debug.Assert(absoluteUri != null, "absoluteUri != null");
            Debug.Assert(absoluteUri.IsAbsoluteUri, "absoluteRequestUri.IsAbsoluteUri(" + absoluteUri.IsAbsoluteUri + ")");
            Debug.Assert(serviceBaseUri != null, "serviceBaseUri != null");
            Debug.Assert(serviceBaseUri.IsAbsoluteUri, "serviceBaseUri.IsAbsoluteUri(" + serviceBaseUri + ")");

            //// This is a copy of the RequestUriProcessor.EnumerateSegments

            if (!UriUtils.UriInvariantInsensitiveIsBaseOf(serviceBaseUri, absoluteUri))
            {
                throw new ODataException(Strings.UriQueryPathParser_RequestUriDoesNotHaveTheCorrectBaseUri(absoluteUri, serviceBaseUri));
            }

            try
            {
                Uri uri = absoluteUri;
                int numberOfSegmentsToSkip = 0;

                // Skip over the base URI segments
#if SILVERLIGHT
                numberOfSegmentsToSkip = serviceBaseUri.AbsolutePath.Split('/').Length;
                string[] uriSegments = uri.AbsolutePath.Split('/');
#else
                numberOfSegmentsToSkip = serviceBaseUri.Segments.Length;
                string[] uriSegments = uri.Segments;
#endif

                List <string> segments = new List <string>();
                for (int i = numberOfSegmentsToSkip; i < uriSegments.Length; i++)
                {
                    string segment = uriSegments[i];
                    if (segment.Length != 0 && segment != "/")
                    {
                        if (segment[segment.Length - 1] == '/')
                        {
                            segment = segment.Substring(0, segment.Length - 1);
                        }

                        if (segments.Count == this.maxDepth)
                        {
                            throw new ODataException(Strings.UriQueryPathParser_TooManySegments);
                        }

                        segments.Add(Uri.UnescapeDataString(segment));
                    }
                }

                return(segments);
            }
            catch (UriFormatException uriFormatException)
            {
                throw new ODataException(Strings.UriQueryPathParser_SyntaxError, uriFormatException);
            }
        }
Пример #3
0
        /// <summary>
        /// Converts the given <paramref name="uri"/> Uri to a string.
        /// If the provided baseUri is not null and is a base Uri of the <paramref name="uri"/> Uri
        /// the method returns the string form of the relative Uri.
        /// </summary>
        /// <param name="uri">The Uri to convert.</param>
        /// <param name="baseUri">An optional base Uri</param>
        /// <returns>The string form of the <paramref name="uri"/> Uri. If the Uri is absolute and
        /// the <paramref name="baseUri"/> is the base Uri of the <paramref name="uri"/> Uri it returns a relative Uri;
        /// otherwise the string form of the absolute Uri. If the <paramref name="uri"/> Uri is not absolute
        /// it returns the original string of the Uri.</returns>
        internal static string ToUrlAttributeValue(this Uri uri, Uri baseUri)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(uri != null, "uri != null");

            if (baseUri == null)
            {
                if (!uri.IsAbsoluteUri)
                {
                    throw new ODataException(Strings.ODataWriter_RelativeUriUsedWithoutBaseUriSpecified(UriUtils.UriToString(uri)));
                }
            }
            else
            {
                if (uri.IsAbsoluteUri && UriUtils.UriInvariantInsensitiveIsBaseOf(baseUri, uri))
                {
                    uri = baseUri.MakeRelativeUri(uri);
                }
            }

            return(UriUtils.UriToString(uri));
        }
Пример #4
0
 public void UriInvariantInsensitiveIsBaseOf_ShouldIgnoreHostAndSchemeAndPort()
 {
     UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("https://different.org:1234/One/"), new Uri("http://www.example.com:4567/One/Two")).Should().BeTrue();
 }
Пример #5
0
 public void UriInvariantInsensitiveIsBaseOf_ShouldBeCaseInsensitive()
 {
     UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("HTTP://WwW.ExAmPlE.cOm/OnE/"), new Uri("http://www.example.com/One/")).Should().BeTrue();
 }
Пример #6
0
 public void UriInvariantInsensitiveIsBaseOf_IdenticalUrisShouldReturnTrue()
 {
     UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/One/"), new Uri("http://www.example.com/One/")).Should().BeTrue();
 }
Пример #7
0
        public void UriInvariantInsensitiveIsBaseOf_RelativeFirstUrlIsNotAllowed()
        {
            Action method = () => UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("/One/", UriKind.Relative), new Uri("http://www.example.com/One/Two"));

            method.ShouldThrow <InvalidOperationException>();
        }
Пример #8
0
        /// <summary>
        /// Returns list of segments in the specified path (eg: /abc/pqr -&gt; abc, pqr).
        /// </summary>
        /// <param name="fullUri">The full URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>List of unescaped segments.</returns>
        public virtual ICollection <string> ParsePathIntoSegments(Uri fullUri, Uri serviceBaseUri)
        {
            if (serviceBaseUri == null)
            {
                Debug.Assert(!fullUri.IsAbsoluteUri, "fullUri must be relative Uri");
                serviceBaseUri = UriUtils.CreateMockAbsoluteUri();
                fullUri        = UriUtils.CreateMockAbsoluteUri(fullUri);
            }

            if (!UriUtils.UriInvariantInsensitiveIsBaseOf(serviceBaseUri, fullUri))
            {
                throw new ODataException(Strings.UriQueryPathParser_RequestUriDoesNotHaveTheCorrectBaseUri(fullUri, serviceBaseUri));
            }

            // COMPAT 29: Slash in key lookup breaks URI parser
            // TODO: The code below has a bug that / in the named values will be considered a segment separator
            //   so for example /Customers('abc/pqr') is treated as two segments, which is wrong.
            try
            {
                Uri uri = fullUri;
                int numberOfSegmentsToSkip = 0;

                // Skip over the base URI segments
#if !ORCAS
                // need to calculate the number of segments to skip in the full
                // uri (so that we can skip over http://blah.com/basePath for example,
                // get only the odata specific parts of the path).
                //
                // because of differences in system.uri between portable lib and
                // the desktop library, we need to handle this differently.
                // in this case we get the number of segments to skip as simply
                // then number of tokens in the serviceBaseUri split on slash, with
                // length - 1 since its a zero based array.
                numberOfSegmentsToSkip = serviceBaseUri.AbsolutePath.Split('/').Length - 1;
                string[] uriSegments = uri.AbsolutePath.Split('/');
#else
                numberOfSegmentsToSkip = serviceBaseUri.Segments.Length;
                string[] uriSegments = uri.Segments;
#endif

                int           escapedStart = -1;
                List <string> segments     = new List <string>();
                for (int i = numberOfSegmentsToSkip; i < uriSegments.Length; i++)
                {
                    string segment = uriSegments[i];
                    // Skip the empty segment or the "/" segment
                    if (segment.Length == 0 || segment == "/")
                    {
                        continue;
                    }

                    // When we use "uri.Segments" to get the segments,
                    // The segment element includes the "/", we should remove that.
                    if (segment[segment.Length - 1] == '/')
                    {
                        segment = segment.Substring(0, segment.Length - 1);
                    }

                    if (segments.Count == this.maxSegments)
                    {
                        throw new ODataException(Strings.UriQueryPathParser_TooManySegments);
                    }

                    // Handle the "root...::/{xyz}"
                    if (segment.Length >= 2 && segment.EndsWith("::", StringComparison.Ordinal))
                    {
                        // It should be the terminal of the provious escape segment and the start of next escape semgent.
                        // Otherwise, it's an invalid Uri.
                        if (escapedStart == -1)
                        {
                            throw new ODataException(Strings.UriQueryPathParser_InvalidEscapeUri(segment));
                        }
                        else
                        {
                            string value = String.Join("/", uriSegments, escapedStart, i - escapedStart + 1);
                            segments.Add(":" + value.Substring(0, value.Length - 1));// because the last one has "::", remove one.
                            escapedStart = i + 1;
                        }
                    }
                    else if (segment.Length >= 1 && segment[segment.Length - 1] == ':')
                    {
                        // root:/{abc}....
                        if (escapedStart == -1)
                        {
                            if (segment != ":")
                            {
                                segments.Add(segment.Substring(0, segment.Length - 1));// remove the last ':'
                            }

                            escapedStart = i + 1;
                        }
                        else
                        {
                            // root:/{abc}:....
                            string escapedSegment = ":" + String.Join("/", uriSegments, escapedStart, i - escapedStart + 1); // the last has one ":";
                            segments.Add(escapedSegment);
                            escapedStart = -1;
                        }
                    }
                    else
                    {
                        // if we didn't find a starting escape, the current segment is normal segment, accept it.
                        // otherwise, it's part of the escape, skip it and process it when we find the ending delimiter.
                        if (escapedStart == -1)
                        {
                            segments.Add(Uri.UnescapeDataString(segment));
                        }
                    }
                }

                if (escapedStart != -1 && escapedStart < uriSegments.Length)
                {
                    string escapedSegment = ":" + String.Join("/", uriSegments, escapedStart, uriSegments.Length - escapedStart);
                    segments.Add(escapedSegment); // We should not use "segments.Add(Uri.UnescapeDataString(escapedSegment));" to keep the orignal string.
                }

                return(segments.ToArray());
            }
#if !ORCAS
            catch (FormatException uriFormatException)
#else
            catch (UriFormatException uriFormatException)
#endif
            {
                throw new ODataException(Strings.UriQueryPathParser_SyntaxError, uriFormatException);
            }
        }
        /// <summary>
        /// Returns list of segments in the specified path (eg: /abc/pqr -&gt; abc, pqr).
        /// </summary>
        /// <param name="fullUri">The full URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>List of unescaped segments.</returns>
        internal ICollection <string> ParsePathIntoSegments(Uri fullUri, Uri serviceBaseUri)
        {
            if (serviceBaseUri == null)
            {
                Debug.Assert(!fullUri.IsAbsoluteUri, "fullUri must be relative Uri");
                serviceBaseUri = UriUtils.CreateMockAbsoluteUri();
                fullUri        = UriUtils.CreateMockAbsoluteUri(fullUri);
            }

            if (!UriUtils.UriInvariantInsensitiveIsBaseOf(serviceBaseUri, fullUri))
            {
                throw new ODataException(Strings.UriQueryPathParser_RequestUriDoesNotHaveTheCorrectBaseUri(fullUri, serviceBaseUri));
            }

            try
            {
                Uri uri = fullUri;
                int numberOfSegmentsToSkip = 0;

                // Skip over the base URI segments
#if !ORCAS
                // need to calculate the number of segments to skip in the full
                // uri (so that we can skip over http://blah.com/basePath for example,
                // get only the odata specific parts of the path).
                //
                // because of differences in system.uri between portable lib and
                // the desktop library, we need to handle this differently.
                // in this case we get the number of segments to skip as simply
                // then number of tokens in the serviceBaseUri split on slash, with
                // length - 1 since its a zero based array.
                numberOfSegmentsToSkip = serviceBaseUri.AbsolutePath.Split('/').Length - 1;
                string[] uriSegments = uri.AbsolutePath.Split('/');
#else
                numberOfSegmentsToSkip = serviceBaseUri.Segments.Length;
                string[] uriSegments = uri.Segments;
#endif

                List <string> segments = new List <string>();
                for (int i = numberOfSegmentsToSkip; i < uriSegments.Length; i++)
                {
                    string segment = uriSegments[i];
                    if (segment.Length != 0 && segment != "/")
                    {
                        if (segment[segment.Length - 1] == '/')
                        {
                            segment = segment.Substring(0, segment.Length - 1);
                        }

                        if (segments.Count == this.maxSegments)
                        {
                            throw new ODataException(Strings.UriQueryPathParser_TooManySegments);
                        }

                        segments.Add(Uri.UnescapeDataString(segment));
                    }
                }

                return(segments.ToArray());
            }
#if !ORCAS
            catch (FormatException uriFormatException)
#else
            catch (UriFormatException uriFormatException)
#endif
            {
                throw new ODataException(Strings.UriQueryPathParser_SyntaxError, uriFormatException);
            }
        }
Пример #10
0
        public void UriInvariantInsensitiveIsBaseOf_ShouldIgnoreStuffAfterFinalSlash()
        {
            var result = UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc"), new Uri("http://www.example.com/One/Two"));

            Assert.True(result);
        }
Пример #11
0
        public void UriInvariantInsensitiveIsBaseOf_ShouldBeCaseInsensitive()
        {
            var result = UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("HTTP://WwW.ExAmPlE.cOm/OnE/"), new Uri("http://www.example.com/One/"));

            Assert.True(result);
        }
Пример #12
0
        public void UriInvariantInsensitiveIsBaseOf_IdenticalUrisShouldReturnTrue()
        {
            var result = UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/One/"), new Uri("http://www.example.com/One/"));

            Assert.True(result);
        }
Пример #13
0
        public void UriInvariantInsensitiveIsBaseOf_RelativeSecondUrlIsNotAllowed()
        {
            Action method = () => UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/One/"), new Uri("/One/Two", UriKind.Relative));

            Assert.Throws <InvalidOperationException>(method);
        }
Пример #14
0
        /// <summary>
        /// Returns list of segments in the specified path (eg: /abc/pqr -&gt; abc, pqr).
        /// </summary>
        /// <param name="fullUri">The full URI of the request.</param>
        /// <param name="serviceBaseUri">The service base URI for the request.</param>
        /// <returns>List of unescaped segments.</returns>
        public virtual ICollection <string> ParsePathIntoSegments(Uri fullUri, Uri serviceBaseUri)
        {
            if (serviceBaseUri == null)
            {
                Debug.Assert(!fullUri.IsAbsoluteUri, "fullUri must be relative Uri");
                serviceBaseUri = UriUtils.CreateMockAbsoluteUri();
                fullUri        = UriUtils.CreateMockAbsoluteUri(fullUri);
            }

            if (!UriUtils.UriInvariantInsensitiveIsBaseOf(serviceBaseUri, fullUri))
            {
                throw new ODataException(Strings.UriQueryPathParser_RequestUriDoesNotHaveTheCorrectBaseUri(fullUri, serviceBaseUri));
            }

            // COMPAT 29: Slash in key lookup breaks URI parser
            // TODO: The code below has a bug that / in the named values will be considered a segment separator
            //   so for example /Customers('abc/pqr') is treated as two segments, which is wrong.
            try
            {
                Uri uri = fullUri;
                int numberOfSegmentsToSkip = 0;

                // Skip over the base URI segments
                // need to calculate the number of segments to skip in the full
                // uri (so that we can skip over http://blah.com/basePath for example,
                // get only the odata specific parts of the path).
                //
                // because of differences in system.uri between portable lib and
                // the desktop library, we need to handle this differently.
                // in this case we get the number of segments to skip as simply
                // then number of tokens in the serviceBaseUri split on slash, with
                // length - 1 since its a zero based array.
                numberOfSegmentsToSkip = serviceBaseUri.AbsolutePath.Split('/').Length - 1;
                string[] uriSegments = uri.AbsolutePath.Split('/');

                List <string> segments = new List <string>();
                for (int i = numberOfSegmentsToSkip; i < uriSegments.Length; i++)
                {
                    string segment = uriSegments[i];

                    // Skip the empty segment or the "/" segment
                    if (segment.Length == 0 || segment == "/")
                    {
                        continue;
                    }

                    // When we use "uri.Segments" to get the segments,
                    // The segment element includes the "/", we should remove that.
                    if (segment[segment.Length - 1] == '/')
                    {
                        segment = segment.Substring(0, segment.Length - 1);
                    }

                    if (segments.Count == this.maxSegments)
                    {
                        throw new ODataException(Strings.UriQueryPathParser_TooManySegments);
                    }

                    segments.Add(Uri.UnescapeDataString(segment));
                }

                return(segments.ToArray());
            }
            catch (FormatException uriFormatException)
            {
                throw new ODataException(Strings.UriQueryPathParser_SyntaxError, uriFormatException);
            }
        }
Пример #15
0
 public void UriInvariantInsensitiveIsBaseOf_ShouldIgnoreStuffAfterFinalSlash()
 {
     UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc"), new Uri("http://www.example.com/One/Two")).Should().BeTrue();
 }
Пример #16
0
 public void UriInvariantInsensitiveIsBaseOf_DifferentBaseShouldReturnFalse()
 {
     UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc/"), new Uri("http://www.example.com/One/Two")).Should().BeFalse();
 }
Пример #17
0
        public void UriInvariantInsensitiveIsBaseOf_DifferentBaseShouldReturnFalse()
        {
            var result = UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc/"), new Uri("http://www.example.com/One/Two"));

            Assert.False(result);
        }