Skip to content

Commit

Permalink
Add cache busting parameter to media thumbnails and links in Media Li…
Browse files Browse the repository at this point in the history
…brary (#15276)

Co-authored-by: Hisham Bin Ateya <hishamco_2007@yahoo.com>
  • Loading branch information
Piedone and hishamco authored Mar 1, 2024
1 parent 1a79732 commit ecd563c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ function initializeMediaApplication(displayMediaApplication, mediaApplicationUrl
}
});

bus.$on('mediaRenamed', function (newName, newPath, oldPath) {
bus.$on('mediaRenamed', function (newName, newPath, oldPath, newUrl) {
var media = self.mediaItems.filter(function (item) {
return item.mediaPath === oldPath;
})[0];

media.mediaPath = newPath;
media.name = newName;
media.url = newUrl;
});

bus.$on('createFolderRequested', function (media) {
Expand Down Expand Up @@ -501,7 +502,7 @@ function initializeMediaApplication(displayMediaApplication, mediaApplicationUrl
success: function (data) {
var modal = bootstrap.Modal.getOrCreateInstance($('#renameMediaModal'));
modal.hide();
bus.$emit('mediaRenamed', newName, newPath, oldPath);
bus.$emit('mediaRenamed', newName, newPath, oldPath, data.newUrl);
},
error: function (error) {
$('#renameMediaModal-errors').empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -32,6 +34,8 @@ public class AdminController : Controller
private readonly MediaOptions _mediaOptions;
private readonly IUserAssetFolderNameProvider _userAssetFolderNameProvider;
private readonly IChunkFileUploadService _chunkFileUploadService;
private readonly IFileVersionProvider _fileVersionProvider;
private readonly IServiceProvider _serviceProvider;

public AdminController(
IMediaFileStore mediaFileStore,
Expand All @@ -42,8 +46,9 @@ public AdminController(
ILogger<AdminController> logger,
IStringLocalizer<AdminController> stringLocalizer,
IUserAssetFolderNameProvider userAssetFolderNameProvider,
IChunkFileUploadService chunkFileUploadService
)
IChunkFileUploadService chunkFileUploadService,
IFileVersionProvider fileVersionProvider,
IServiceProvider serviceProvider)
{
_mediaFileStore = mediaFileStore;
_mediaNameNormalizerService = mediaNameNormalizerService;
Expand All @@ -54,6 +59,8 @@ IChunkFileUploadService chunkFileUploadService
S = stringLocalizer;
_userAssetFolderNameProvider = userAssetFolderNameProvider;
_chunkFileUploadService = chunkFileUploadService;
_fileVersionProvider = fileVersionProvider;
_serviceProvider = serviceProvider;
}

[Admin("Media", "Media.Index")]
Expand Down Expand Up @@ -118,7 +125,10 @@ public async Task<ActionResult<IEnumerable<object>>> GetMediaItems(string path,
var allowedExtensions = GetRequestedExtensions(extensions, false);

var allowed = _mediaFileStore.GetDirectoryContentAsync(path)
.WhereAwait(async e => !e.IsDirectory && (allowedExtensions.Count == 0 || allowedExtensions.Contains(Path.GetExtension(e.Path))) && await _authorizationService.AuthorizeAsync(User, Permissions.ManageMediaFolder, (object)e.Path))
.WhereAwait(async e =>
!e.IsDirectory
&& (allowedExtensions.Count == 0 || allowedExtensions.Contains(Path.GetExtension(e.Path)))
&& await _authorizationService.AuthorizeAsync(User, Permissions.ManageMediaFolder, (object)e.Path))
.Select(e => CreateFileResult(e));

return Ok(await allowed.ToListAsync());
Expand Down Expand Up @@ -205,6 +215,9 @@ public async Task<IActionResult> Upload(string path, string extensions)

var mediaFile = await _mediaFileStore.GetFileInfoAsync(mediaFilePath);

stream.Position = 0;
await PreCacheRemoteMedia(mediaFile, stream);

result.Add(CreateFileResult(mediaFile));
}
catch (Exception ex)
Expand Down Expand Up @@ -312,7 +325,10 @@ public async Task<IActionResult> MoveMedia(string oldPath, string newPath)

await _mediaFileStore.MoveFileAsync(oldPath, newPath);

return Ok();
var newFileInfo = await _mediaFileStore.GetFileInfoAsync(newPath);
await PreCacheRemoteMedia(newFileInfo);

return Ok(new { newUrl = GetCacheBustingMediaPublicUrl(newPath) });
}

[HttpPost]
Expand Down Expand Up @@ -445,7 +461,7 @@ public object CreateFileResult(IFileStoreEntry mediaFile)
size = mediaFile.Length,
lastModify = mediaFile.LastModifiedUtc.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds,
folder = mediaFile.DirectoryPath,
url = _mediaFileStore.MapPathToPublicUrl(mediaFile.Path),
url = GetCacheBustingMediaPublicUrl(mediaFile.Path),
mediaPath = mediaFile.Path,
mime = contentType ?? "application/octet-stream",
mediaText = string.Empty,
Expand Down Expand Up @@ -493,5 +509,37 @@ private HashSet<string> GetRequestedExtensions(string exts, bool fallback)

return [];
}

private string GetCacheBustingMediaPublicUrl(string path) =>
_fileVersionProvider.AddFileVersionToPath(HttpContext.Request.PathBase, _mediaFileStore.MapPathToPublicUrl(path));

// If a remote storage is used, then we need to preemptively cache the newly uploaded or renamed file. Without
// this, the Media Library page will try to load the thumbnail without a cache busting parameter, since
// ShellFileVersionProvider won't find it in the local cache.
// This is not required for files moved across folders, because the folder will be reopened anyway.
private async Task PreCacheRemoteMedia(IFileStoreEntry mediaFile, Stream stream = null)
{
var mediaFileStoreCache = _serviceProvider.GetService<IMediaFileStoreCache>();
if (mediaFileStoreCache == null)
{
return;
}

Stream localStream = null;

if (stream == null)
{
stream = localStream = await _mediaFileStore.GetFileStreamAsync(mediaFile);
}

try
{
await mediaFileStoreCache.SetCacheAsync(stream, mediaFile, HttpContext.RequestAborted);
}
finally
{
localStream?.Dispose();
}
}
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public Task<bool> IsCachedAsync(string path)

public async Task SetCacheAsync(Stream stream, IFileStoreEntry fileStoreEntry, CancellationToken cancellationToken)
{
// File store semantics include a leading slash.
var cachePath = Path.Combine(Root, fileStoreEntry.Path[1..]);
// File store semantics may include a leading slash.
var cachePath = Path.Combine(Root, fileStoreEntry.Path.TrimStart('/'));
var directory = Path.GetDirectoryName(cachePath);

if (!Directory.Exists(directory))
Expand Down

0 comments on commit ecd563c

Please sign in to comment.