How to cache images to disk that were retrieved via a custom image provider #104
-
Hello, I've setup a custom ImageProvider and ImageResolver, right now this works as expected. Whenever I hit the endpoint /custom/blah/github.jpg, I create an HttpClient request to download the image. But when the same image is requested again, I would like for it to use the version on the disk (for 30 seconds), I was told by @JimBobSquarePants to use this forum instead of Glitter chat. Any help would be greatly appreciated. public class MyCustomImageProvider : IImageProvider
{
private readonly IFileProvider fileProvider;
private readonly FormatUtilities formatUtilities;
public MyCustomImageProvider(
IWebHostEnvironment environment,
FormatUtilities formatUtilities)
{
this.formatUtilities = formatUtilities;
}
public Func<HttpContext, bool> Match { get; set; } = x => x.Request.Path.Value.Contains("custom/");
public bool IsValidRequest(HttpContext context) => this.formatUtilities.GetExtensionFromUri(context.Request.GetDisplayUrl()) != null;
public async Task<IImageResolver> GetAsync(HttpContext context)
{
// Path has already been correctly parsed before here.
var filePath = context.Request.Path.Value;
var filePathArray = filePath.Split('/');
if (filePathArray[2].Equals("blah", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(filePathArray[3]))
{
var downloadUrl = $"https://MYPRIVATESITE/{filePathArray[3]}";
var client = new HttpClient();
var data = await client.GetStreamAsync(downloadUrl);
var metadata = new ImageMetadata(DateTime.Now.AddSeconds(30));
return new MyCustomImageResolver(data, metadata);
}
return null;
//// Check to see if the file exists.
//if (!fileInfo.Exists)
//{
// return Task.FromResult<IImageResolver>(null);
//}
}
public ProcessingBehavior ProcessingBehavior { get; } = ProcessingBehavior.All;
} Here is the image resolver: public class MyCustomImageResolver : IImageResolver
{
private readonly Stream stream;
private readonly ImageMetadata metadata;
public MyCustomImageResolver(Stream stream, in ImageMetadata metadata)
{
this.stream = stream;
this.metadata = metadata;
}
public Task<ImageMetadata> GetMetaDataAsync()
{
//Response<BlobProperties> properties = await this.stream.;
//return new ImageMetadata(properties?.Value.LastModified.DateTime ?? DateTime.UtcNow);
return Task.FromResult(metadata);
}
public Task<Stream> OpenReadAsync() => Task.FromResult(this.stream);
} And finally my ConfigureServices: public void ConfigureServices(IServiceCollection services)
{
services.AddImageSharpCore(options => {
options.MaxBrowserCacheDays = 1;
})
.SetRequestParser<QueryCollectionRequestParser>()
.Configure<PhysicalFileSystemCacheOptions>(options =>
{
options.CacheFolder = "is-cache";
})
.SetCache(provider =>
{
return new PhysicalFileSystemCache(
provider.GetRequiredService<IOptions<PhysicalFileSystemCacheOptions>>(),
provider.GetRequiredService<IWebHostEnvironment>(),
provider.GetRequiredService<IOptions<ImageSharpMiddlewareOptions>>(),
provider.GetRequiredService<FormatUtilities>());
})
.SetCacheHash<CacheHash>()
.AddProvider<MyCustomImageProvider>()
.AddProcessor<ResizeWebProcessor>()
.AddProcessor<FormatWebProcessor>()
.AddProcessor<BackgroundColorWebProcessor>();
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hi @tekguy You need to implement your own cache. The On a side note you should be using UTC date for your metadata. |
Beta Was this translation helpful? Give feedback.
-
Hi @tekguy I've refactored the cache to use two new properties |
Beta Was this translation helpful? Give feedback.
Hi @tekguy
I've refactored the cache to use two new properties
BrowserMaxAge
andCacheMaxAge
. You'll be able to set either to use any supportedTimeSpan
configuration.