umbraco / Umbraco.StorageProviders

MIT License
29 stars 21 forks source link

Fix getting blob path with empty container root path #60

Closed ronaldbarendse closed 1 year ago

ronaldbarendse commented 1 year ago

Fixes issue https://github.com/umbraco/Umbraco.StorageProviders/issues/58 by ensuring the root URL is removed if the container root path is empty.

This can be tested by adding the following composer/component into an empty project, uploading media and restarting the site:

using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Services;

internal sealed class GetMediaFileContentStreamComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
        => builder
        .AddAzureBlobMediaFileSystem(options =>
        {
            //options.ConnectionString = "UseDevelopmentStorage=true";
            //options.ContainerName = "umbraco-storageproviders";
            options.ContainerRootPath = "";
        })
        .AddComponent<GetMediaFileContentStreamComponent>();

    private sealed class GetMediaFileContentStreamComponent : IComponent
    {
        private readonly IMediaService _mediaService;
        private readonly MediaUrlGeneratorCollection _mediaUrlGenerators;

        public GetMediaFileContentStreamComponent(IMediaService mediaService, MediaUrlGeneratorCollection mediaUrlGenerators)
        {
            _mediaService = mediaService;
            _mediaUrlGenerators = mediaUrlGenerators;
        }

        public void Initialize()
        {
            foreach (var media in _mediaService.GetPagedDescendants(Constants.System.Root, 0, int.MaxValue, out _))
            {
                if (media.TryGetMediaPath(Constants.Conventions.Media.File, _mediaUrlGenerators, out string? mediaFilePath) &&
                    !string.IsNullOrEmpty(mediaFilePath))
                {
                    // Check if we can resolve the path back to the media item
                    _ = _mediaService.GetMediaByPath(mediaFilePath) ?? throw new InvalidOperationException("Could not resolve media by path.");

                    // Check whether we can get a valid file stream
                    using Stream mediaFileStream = _mediaService.GetMediaFileContentStream(mediaFilePath);
                    if (mediaFileStream.GetType() == Stream.Null.GetType())
                    {
                        throw new InvalidOperationException("Could not get media file content stream.");
                    }
                }
            }
        }

        public void Terminate()
        { }
    }
}