// 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 System; using System.Text; namespace Microsoft.AspNet.Http.Extensions { /// /// A helper class for constructing encoded Uris for use in headers and other Uris. /// public static class UriHelper { private const string SchemeDelimiter = "://"; /// /// Combines the given URI components into a string that is properly encoded for use in HTTP headers. /// /// /// /// /// /// public static string Encode( PathString pathBase = new PathString(), PathString path = new PathString(), QueryString query = new QueryString(), FragmentString fragment = new FragmentString()) { string combinePath = (pathBase.HasValue || path.HasValue) ? (pathBase + path).ToString() : "/"; return combinePath + query.ToString() + fragment.ToString(); } /// /// Combines the given URI components into a string that is properly encoded for use in HTTP headers. /// Note that unicode in the HostString will be encoded as punycode. /// /// /// /// /// /// /// /// public static string Encode( string scheme, HostString host, PathString pathBase = new PathString(), PathString path = new PathString(), QueryString query = new QueryString(), FragmentString fragment = new FragmentString()) { var combinedPath = (pathBase.HasValue || path.HasValue) ? (pathBase + path).ToString() : "/"; var encodedHost = host.ToString(); var encodedQuery = query.ToString(); var encodedFragment = fragment.ToString(); // PERF: Calculate string length to allocate correct buffer size for StringBuilder. var length = scheme.Length + SchemeDelimiter.Length + encodedHost.Length + combinedPath.Length + encodedQuery.Length + encodedFragment.Length; return new StringBuilder(length) .Append(scheme) .Append(SchemeDelimiter) .Append(encodedHost) .Append(combinedPath) .Append(encodedQuery) .Append(encodedFragment) .ToString(); } /// /// Generates a string from the given absolute or relative Uri that is appropriately encoded for use in /// HTTP headers. Note that a unicode host name will be encoded as punycode. /// /// /// public static string Encode(Uri uri) { if (uri.IsAbsoluteUri) { return Encode( scheme: uri.Scheme, host: HostString.FromUriComponent(uri), pathBase: PathString.FromUriComponent(uri), query: QueryString.FromUriComponent(uri), fragment: FragmentString.FromUriComponent(uri)); } else { 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) { var host = request.Host.Value; var pathBase = request.PathBase.Value; var path = request.Path.Value; var queryString = request.QueryString.Value; // PERF: Calculate string length to allocate correct buffer size for StringBuilder. var length = request.Scheme.Length + SchemeDelimiter.Length + host.Length + pathBase.Length + path.Length + queryString.Length; return new StringBuilder(length) .Append(request.Scheme) .Append(SchemeDelimiter) .Append(host) .Append(pathBase) .Append(path) .Append(queryString) .ToString(); } } }