aspnetcore/src/ApiAuth.IS/Extensions/AbsoluteUrlFactory.cs

64 lines
2.2 KiB
C#

// 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.AspNetCore.Http;
using System;
namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer
{
internal class AbsoluteUrlFactory : IAbsoluteUrlFactory
{
public AbsoluteUrlFactory(IHttpContextAccessor httpContextAccessor)
{
// We need the context accessor here in order to produce an absolute url from a potentially relative url.
ContextAccessor = httpContextAccessor;
}
public IHttpContextAccessor ContextAccessor { get; }
// Call this method when you are overriding a service that doesn't have an HttpContext instance available.
public string GetAbsoluteUrl(string path)
{
var (process, result) = ShouldProcessPath(path);
if (!process)
{
return result;
}
if (ContextAccessor.HttpContext?.Request == null)
{
throw new InvalidOperationException("The request is not currently available. This service can only be used within the context of an existing HTTP request.");
}
return GetAbsoluteUrl(ContextAccessor.HttpContext, path);
}
// Call this method when you are implementing a service that has an HttpContext instance available.
public string GetAbsoluteUrl(HttpContext context, string path)
{
var (process, result) = ShouldProcessPath(path);
if (!process)
{
return result;
}
var request = context.Request;
return $"{request.Scheme}://{request.Host.ToUriComponent()}{request.PathBase.ToUriComponent()}{path}";
}
private (bool, string) ShouldProcessPath(string path)
{
if (path == null || !Uri.IsWellFormedUriString(path, UriKind.RelativeOrAbsolute))
{
return (false, null);
}
if (Uri.IsWellFormedUriString(path, UriKind.Absolute))
{
return (false, path);
}
return (true, path);
}
}
}