/// <summary> /// Returns list of segments in the specified path (eg: /abc/pqr -> 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); } }
/// <summary> /// Returns list of segments in the specified path (eg: /foo/bar -> 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); } }
/// <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)); }
public void UriInvariantInsensitiveIsBaseOf_ShouldIgnoreHostAndSchemeAndPort() { UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("https://different.org:1234/One/"), new Uri("http://www.example.com:4567/One/Two")).Should().BeTrue(); }
public void UriInvariantInsensitiveIsBaseOf_ShouldBeCaseInsensitive() { UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("HTTP://WwW.ExAmPlE.cOm/OnE/"), new Uri("http://www.example.com/One/")).Should().BeTrue(); }
public void UriInvariantInsensitiveIsBaseOf_IdenticalUrisShouldReturnTrue() { UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/One/"), new Uri("http://www.example.com/One/")).Should().BeTrue(); }
public void UriInvariantInsensitiveIsBaseOf_RelativeFirstUrlIsNotAllowed() { Action method = () => UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("/One/", UriKind.Relative), new Uri("http://www.example.com/One/Two")); method.ShouldThrow <InvalidOperationException>(); }
/// <summary> /// Returns list of segments in the specified path (eg: /abc/pqr -> 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 -> 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); } }
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); }
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); }
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); }
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); }
/// <summary> /// Returns list of segments in the specified path (eg: /abc/pqr -> 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); } }
public void UriInvariantInsensitiveIsBaseOf_ShouldIgnoreStuffAfterFinalSlash() { UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc"), new Uri("http://www.example.com/One/Two")).Should().BeTrue(); }
public void UriInvariantInsensitiveIsBaseOf_DifferentBaseShouldReturnFalse() { UriUtils.UriInvariantInsensitiveIsBaseOf(new Uri("http://www.example.com/OData.svc/"), new Uri("http://www.example.com/One/Two")).Should().BeFalse(); }
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); }