RemoteImageProvider POC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Microsoft.Extensions.Options; | |
namespace SixLabors.ImageSharp.Web.Providers | |
{ | |
public class AllowedDomainsRemoteImageUrlValidator: IRemoteImageUrlValidator | |
{ | |
private readonly List<string> _allowedDomains; | |
public AllowedDomainsRemoteImageUrlValidator(IOptions<AllowedDomainsRemoteImageUrlValidatorOptions> options) | |
{ | |
_allowedDomains = options.Value.AllowedDomains | |
.Select(domain => domain.ToLower()) | |
.ToList(); | |
} | |
public bool IsValidUrl(Uri url) | |
{ | |
return _allowedDomains.Contains(url.Host); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace SixLabors.ImageSharp.Web.Providers | |
{ | |
public class AllowedDomainsRemoteImageUrlValidatorOptions | |
{ | |
public ICollection<string> AllowedDomains { get; set; } = new List<string>(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"ImageSharp.Web": { | |
"Presets": { | |
"preset1": "rmode=crop&width=232&height=164", | |
}, | |
"AllowedDomains": [ | |
"example.com" | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace SixLabors.ImageSharp.Web.Providers | |
{ | |
public interface IRemoteImageUrlValidator | |
{ | |
bool IsValidUrl(Uri url); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Http; | |
using SixLabors.ImageSharp.Web.Providers; | |
using SixLabors.ImageSharp.Web.Resolvers; | |
namespace SixLabors.ImageSharp.Web.Providers | |
{ | |
public class RemoteImageProvider : IImageProvider | |
{ | |
public ProcessingBehavior ProcessingBehavior => ProcessingBehavior.All; | |
public Func<HttpContext, bool> Match { get; set; } = PathStartsWithRemote; | |
public const string RemotePath = "/remote"; | |
private readonly IHttpClientFactory _clientFactory; | |
private readonly IRemoteImageUrlValidator _urlValidator; | |
public RemoteImageProvider(IHttpClientFactory clientFactory, IRemoteImageUrlValidator urlValidator) | |
{ | |
_clientFactory = clientFactory; | |
_urlValidator = urlValidator; | |
} | |
public bool IsValidRequest(HttpContext context) | |
{ | |
var url = GetRemoteUrl(context); | |
return Uri.IsWellFormedUriString(url, UriKind.Absolute) && _urlValidator.IsValidUrl(new Uri(url)); | |
} | |
public Task<IImageResolver> GetAsync(HttpContext context) | |
{ | |
var url = GetRemoteUrl(context); | |
return Task.FromResult(new RemoteImageResolver(_clientFactory, url) as IImageResolver); | |
} | |
private static bool PathStartsWithRemote(HttpContext context) | |
{ | |
return context.Request.Path.StartsWithSegments(RemotePath, StringComparison.OrdinalIgnoreCase); | |
} | |
private static string GetRemoteUrl(HttpContext context) | |
{ | |
if (!context.Request.Path.HasValue || context.Request.Path.Value.Length <= RemotePath.Length) | |
{ | |
return null; | |
} | |
var remoteUrl = context.Request.Path.Value?.Substring(RemotePath.Length + 1); | |
return remoteUrl.Replace(" ", "%20"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using SixLabors.ImageSharp.Web; | |
using SixLabors.ImageSharp.Web.Resolvers; | |
namespace SixLabors.ImageSharp.Web.Providers | |
{ | |
public class RemoteImageResolver: IImageResolver | |
{ | |
private readonly IHttpClientFactory _clientFactory; | |
private readonly string _url; | |
public const string HttpClientName = "RemoteImageResolver"; | |
public RemoteImageResolver(IHttpClientFactory clientFactory, string url) | |
{ | |
_clientFactory = clientFactory; | |
_url = url; | |
} | |
public async Task<ImageMetadata> GetMetaDataAsync() | |
{ | |
var client = _clientFactory.CreateClient(HttpClientName); | |
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, _url), HttpCompletionOption.ResponseHeadersRead); | |
if (!response.Content.Headers.ContentLength.HasValue) | |
{ | |
throw new Exception("Required header ContentLength is missing."); | |
} | |
if (!response.Content.Headers.LastModified.HasValue || !response.Content.Headers.ContentLength.HasValue) | |
{ | |
throw new Exception("Required header LastModified is missing."); | |
} | |
return new ImageMetadata(response.Content.Headers.LastModified.Value.UtcDateTime, response.Content.Headers.ContentLength.Value); | |
} | |
public async Task<Stream> OpenReadAsync() | |
{ | |
var client = _clientFactory.CreateClient(HttpClientName); | |
var response = await client.GetAsync(_url); | |
return await response.Content.ReadAsStreamAsync(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace PMP.Frontend.Core.Startup | |
{ | |
public class Startup | |
{ | |
//... | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
//... | |
services.AddHttpClient(RemoteImageResolver.HttpClientName, client => | |
{ | |
client.Timeout = TimeSpan.FromSeconds(5); | |
client.MaxResponseContentBufferSize = 8388608; //8mb | |
}); | |
services | |
.AddImageSharp() | |
.ClearProviders() | |
.AddProvider<RemoteImageProvider>() | |
.SetRequestParser<PresetRequestParser>() | |
.Configure<PresetRequestParserOptions>(_configuration.GetSection("ImageSharp.Web")) | |
.Configure<AllowedDomainsRemoteImageUrlValidatorOptions>(_configuration.GetSection("ImageSharp.Web")); | |
//... | |
} | |
//... | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment