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());
+ }
+ }
+}