diff --git a/src/Microsoft.AspNet.Http.Extensions/UriHelper.cs b/src/Microsoft.AspNet.Http.Extensions/UriHelper.cs index 33f589cb..3e137acc 100644 --- a/src/Microsoft.AspNet.Http.Extensions/UriHelper.cs +++ b/src/Microsoft.AspNet.Http.Extensions/UriHelper.cs @@ -71,5 +71,27 @@ public static string Encode(Uri uri) return uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); } } + + /// + /// Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers + /// and other HTTP operations. + /// + /// + /// + public static string GetEncodedUrl(this HttpRequest request) + { + return Encode(request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString); + } + + /// + /// Returns the combined components of the request URL in a fully un-escaped form (except for the QueryString) + /// suitable only for display. This format should not be used in HTTP headers or other HTTP operations. + /// + /// + /// + public static string GetDisplayUrl(this HttpRequest request) + { + return request.Scheme + "://" + request.Host.Value + request.PathBase.Value + request.Path.Value + request.QueryString.Value; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Http.Extensions.Tests/UriHelperTests.cs b/test/Microsoft.AspNet.Http.Extensions.Tests/UriHelperTests.cs new file mode 100644 index 00000000..0846dd71 --- /dev/null +++ b/test/Microsoft.AspNet.Http.Extensions.Tests/UriHelperTests.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http.Internal; +using Xunit; + +namespace Microsoft.AspNet.Http.Extensions +{ + public class UriHelperTests + { + [Fact] + public void EncodeEmptyPartialUrl() + { + var result = UriHelper.Encode(); + + Assert.Equal("/", result); + } + + [Fact] + public void EncodePartialUrl() + { + var result = UriHelper.Encode(new PathString("/un?escaped/base"), new PathString("/un?escaped"), + new QueryString("?name=val%23ue"), new FragmentString("#my%20value")); + + Assert.Equal("/un%3Fescaped/base/un%3Fescaped?name=val%23ue#my%20value", result); + } + + [Fact] + public void EncodeEmptyFullUrl() + { + var result = UriHelper.Encode("http", new HostString(string.Empty)); + + Assert.Equal("http:///", result); + } + + [Fact] + public void EncodeFullUrl() + { + var result = UriHelper.Encode("http", new HostString("my.HoΨst:80"), new PathString("/un?escaped/base"), new PathString("/un?escaped"), + new QueryString("?name=val%23ue"), new FragmentString("#my%20value")); + + Assert.Equal("http://my.xn--host-cpd:80/un%3Fescaped/base/un%3Fescaped?name=val%23ue#my%20value", result); + } + + [Fact] + public void GetEncodedUrlFromRequest() + { + var request = new DefaultHttpContext().Request; + request.Scheme = "http"; + request.Host = new HostString("my.HoΨst:80"); + request.PathBase = new PathString("/un?escaped/base"); + request.Path = new PathString("/un?escaped"); + request.QueryString = new QueryString("?name=val%23ue"); + + Assert.Equal("http://my.xn--host-cpd:80/un%3Fescaped/base/un%3Fescaped?name=val%23ue", request.GetEncodedUrl()); + } + + [Fact] + public void GetDisplayUrlFromRequest() + { + var request = new DefaultHttpContext().Request; + request.Scheme = "http"; + request.Host = new HostString("my.HoΨst:80"); + request.PathBase = new PathString("/un?escaped/base"); + request.Path = new PathString("/un?escaped"); + request.QueryString = new QueryString("?name=val%23ue"); + + Assert.Equal("http://my.hoψst:80/un?escaped/base/un?escaped?name=val%23ue", request.GetDisplayUrl()); + } + } +}