using System;
using System.IO;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Core
{
///
/// Provides extension methods to .
///
public static class UriExtensions
{
///
/// Checks if the current uri is a back office request
///
///
///
internal static bool IsBackOfficeRequest(this Uri url)
{
var authority = url.GetLeftPart(UriPartial.Authority);
var afterAuthority = url.GetLeftPart(UriPartial.Query)
.TrimStart(authority)
.TrimStart("/");
//check if this is in the umbraco back office
return afterAuthority.InvariantStartsWith(GlobalSettings.Path.TrimStart("/"));
}
///
/// Checks if the current uri is an install request
///
///
///
internal static bool IsInstallerRequest(this Uri url)
{
var authority = url.GetLeftPart(UriPartial.Authority);
var afterAuthority = url.GetLeftPart(UriPartial.Query)
.TrimStart(authority)
.TrimStart("/");
//check if this is in the umbraco back office
return afterAuthority.InvariantStartsWith(IOHelper.ResolveUrl("~/install").TrimStart("/"));
}
///
/// This is a performance tweak to check if this is a .css, .js or .ico, .jpg, .jpeg, .png, .gif file request since
/// .Net will pass these requests through to the module when in integrated mode.
/// We want to ignore all of these requests immediately.
///
///
///
internal static bool IsClientSideRequest(this Uri url)
{
// fixme - IsClientSideRequest should not use an hard-coded list of extensions
// a client-side request is anything that has an extension that is not .aspx?
var toIgnore = new[] { ".js", ".css", ".ico", ".png", ".jpg", ".jpeg", ".gif", ".html", ".svg" };
return toIgnore.Any(x => Path.GetExtension(url.LocalPath).InvariantEquals(x));
}
///
/// Rewrites the path of uri.
///
/// The uri.
/// The new path, which must begin with a slash.
/// The rewritten uri.
/// Everything else remains unchanged, except for the fragment which is removed.
public static Uri Rewrite(this Uri uri, string path)
{
if (path.StartsWith("/") == false)
throw new ArgumentException("Path must start with a slash.", "path");
return uri.IsAbsoluteUri
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + uri.Query)
: new Uri(path + uri.GetSafeQuery(), UriKind.Relative);
}
///
/// Rewrites the path and query of a uri.
///
/// The uri.
/// The new path, which must begin with a slash.
/// The new query, which must be empty or begin with a question mark.
/// The rewritten uri.
/// Everything else remains unchanged, except for the fragment which is removed.
public static Uri Rewrite(this Uri uri, string path, string query)
{
if (path.StartsWith("/") == false)
throw new ArgumentException("Path must start with a slash.", "path");
if (query.Length > 0 && query.StartsWith("?") == false)
throw new ArgumentException("Query must start with a question mark.", "query");
if (query == "?")
query = "";
return uri.IsAbsoluteUri
? new Uri(uri.GetLeftPart(UriPartial.Authority) + path + query)
: new Uri(path + query, UriKind.Relative);
}
///
/// Gets the absolute path of the uri, even if the uri is relative.
///
/// The uri.
/// The absolute path of the uri.
/// Default uri.AbsolutePath does not support relative uris.
public static string GetSafeAbsolutePath(this Uri uri)
{
if (uri.IsAbsoluteUri)
return uri.AbsolutePath;
// cannot get .AbsolutePath on relative uri (InvalidOperation)
var s = uri.OriginalString;
var posq = s.IndexOf("?", StringComparison.Ordinal);
var posf = s.IndexOf("#", StringComparison.Ordinal);
var pos = posq > 0 ? posq : (posf > 0 ? posf : 0);
var path = pos > 0 ? s.Substring(0, pos) : s;
return path;
}
///
/// Gets the decoded, absolute path of the uri.
///
/// The uri.
/// The absolute path of the uri.
/// Only for absolute uris.
public static string GetAbsolutePathDecoded(this Uri uri)
{
return System.Web.HttpUtility.UrlDecode(uri.AbsolutePath);
}
///
/// Gets the decoded, absolute path of the uri, even if the uri is relative.
///
/// The uri.
/// The absolute path of the uri.
/// Default uri.AbsolutePath does not support relative uris.
public static string GetSafeAbsolutePathDecoded(this Uri uri)
{
return System.Web.HttpUtility.UrlDecode(uri.GetSafeAbsolutePath());
}
///
/// Rewrites the path of the uri so it ends with a slash.
///
/// The uri.
/// The rewritten uri.
/// Everything else remains unchanged.
public static Uri EndPathWithSlash(this Uri uri)
{
var path = uri.GetSafeAbsolutePath();
if (uri.IsAbsoluteUri)
{
if (path != "/" && path.EndsWith("/") == false)
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path + "/" + uri.Query);
return uri;
}
if (path != "/" && path.EndsWith("/") == false)
uri = new Uri(path + "/" + uri.Query, UriKind.Relative);
return uri;
}
///
/// Rewrites the path of the uri so it does not end with a slash.
///
/// The uri.
/// The rewritten uri.
/// Everything else remains unchanged.
public static Uri TrimPathEndSlash(this Uri uri)
{
var path = uri.GetSafeAbsolutePath();
if (uri.IsAbsoluteUri)
{
if (path != "/")
uri = new Uri(uri.GetLeftPart(UriPartial.Authority) + path.TrimEnd('/') + uri.Query);
}
else
{
if (path != "/")
uri = new Uri(path.TrimEnd('/') + uri.Query, UriKind.Relative);
}
return uri;
}
///
/// Transforms a relative uri into an absolute uri.
///
/// The relative uri.
/// The base absolute uri.
/// The absolute uri.
public static Uri MakeAbsolute(this Uri uri, Uri baseUri)
{
if (uri.IsAbsoluteUri)
throw new ArgumentException("Uri is already absolute.", "uri");
return new Uri(baseUri.GetLeftPart(UriPartial.Authority) + uri.GetSafeAbsolutePath() + uri.GetSafeQuery());
}
static string GetSafeQuery(this Uri uri)
{
if (uri.IsAbsoluteUri)
return uri.Query;
// cannot get .Query on relative uri (InvalidOperation)
var s = uri.OriginalString;
var posq = s.IndexOf("?", StringComparison.Ordinal);
var posf = s.IndexOf("#", StringComparison.Ordinal);
var query = posq < 0 ? null : (posf < 0 ? s.Substring(posq) : s.Substring(posq, posf - posq));
return query;
}
}
}