Skip to content

Commit eebcbca

Browse files
committed
adds config and method to verify that a url exists (returns success status code) when selecting provider
1 parent c7ae121 commit eebcbca

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/ImageSharpCommunity.Providers.Remote/Configuration/RemoteImageProviderSetting.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,10 @@ public RemoteImageProviderSetting(string prefix)
5757
/// </summary>
5858
public bool AllowAllDomains { get; set; }
5959

60+
/// <summary>
61+
/// Verify that the input url returns a succesful status code.
62+
/// </summary>
63+
public bool VerifyUrl { get; set; } = true;
64+
6065
internal string ClientDictionaryKey => $"{HttpClientName}_{UserAgent}_{Timeout}_{MaxBytes}";
6166
}

src/ImageSharpCommunity.Providers.Remote/RemoteImageProvider.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using ImageSharpCommunity.Providers.Remote.Configuration;
22
using Microsoft.AspNetCore.Http;
3+
using Microsoft.Extensions.Caching.Memory;
34
using Microsoft.Extensions.Logging;
45
using Microsoft.Extensions.Options;
56
using SixLabors.ImageSharp.Web.Providers;
@@ -13,13 +14,15 @@ public class RemoteImageProvider : IImageProvider
1314
private readonly RemoteImageProviderOptions _options;
1415
private readonly ILogger<RemoteImageProvider> _logger;
1516
private readonly ILogger<RemoteImageResolver> _resolverLogger;
17+
private readonly IMemoryCache _cache;
1618

17-
public RemoteImageProvider(IHttpClientFactory clientFactory, IOptions<RemoteImageProviderOptions> options, ILogger<RemoteImageProvider> logger, ILogger<RemoteImageResolver> resolverLogger)
19+
public RemoteImageProvider(IHttpClientFactory clientFactory, IOptions<RemoteImageProviderOptions> options, ILogger<RemoteImageProvider> logger, ILogger<RemoteImageResolver> resolverLogger, IMemoryCache cache)
1820
{
1921
_clientFactory = clientFactory;
2022
_options = options.Value;
2123
_logger = logger;
2224
_resolverLogger = resolverLogger;
25+
_cache = cache;
2326
}
2427

2528
public ProcessingBehavior ProcessingBehavior => ProcessingBehavior.All;
@@ -37,7 +40,8 @@ public bool IsValidRequest(HttpContext context)
3740
context.Request.Path.GetMatchingRemoteImageProviderSetting(_options) is RemoteImageProviderSetting setting
3841
&& context.Request.Path.GetSourceUrlForRemoteImageProviderUrl(_options) is string url
3942
&& Uri.TryCreate(url, UriKind.Absolute, out Uri? uri) && uri != null
40-
&& uri.IsValidForSetting(setting);
43+
&& uri.IsValidForSetting(setting)
44+
&& UrlReturnsSuccess(setting, uri);
4145
}
4246

4347
public Task<IImageResolver?> GetAsync(HttpContext context)
@@ -60,4 +64,30 @@ private bool IsMatch(HttpContext context)
6064
{
6165
return context.Request.Path.GetMatchingRemoteImageProviderSetting(_options) != null;
6266
}
67+
68+
private bool UrlReturnsSuccess(RemoteImageProviderSetting setting, Uri uri)
69+
{
70+
if (setting.VerifyUrl == false)
71+
{
72+
_logger.LogDebug("Skipping verification of URL {Url} as VerifyUrl is set to false", uri);
73+
return true;
74+
}
75+
76+
if (_cache.TryGetValue(nameof(RemoteImageProvider) + uri, out bool cachedResult))
77+
{
78+
_logger.LogDebug("Using cached result for URL {Url}", uri);
79+
return cachedResult;
80+
}
81+
82+
var client = _clientFactory.GetRemoteImageProviderHttpClient(setting);
83+
var request = new HttpRequestMessage(HttpMethod.Head, uri);
84+
var response = client.SendAsync(request).Result;
85+
86+
if (response.Headers.CacheControl?.MaxAge is not null)
87+
{
88+
_cache.Set(nameof(RemoteImageProvider) + uri, response.IsSuccessStatusCode, response.Headers.CacheControl.MaxAge ?? TimeSpan.Zero);
89+
}
90+
91+
return response.IsSuccessStatusCode;
92+
}
6393
}

0 commit comments

Comments
 (0)