From 73c4e734b35aac3903a520a91d6882c266614bba Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 21 Feb 2019 12:20:10 +0100 Subject: [PATCH] Move to UniqueMediaPathScheme --- .../CompositionExtensions/FileSystems.cs | 2 +- .../CombinedGuidsMediaPathScheme.cs | 1 + .../MediaPathSchemes/UniqueMediaPathScheme.cs | 38 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + src/Umbraco.Tests/IO/FileSystemsTests.cs | 2 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 2 +- 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs b/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs index 4fbbec0265..078a505be9 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs @@ -79,7 +79,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(factory => factory.GetInstance()); // register the scheme for media paths - composition.RegisterUnique(); + composition.RegisterUnique(); // register the IMediaFileSystem implementation composition.RegisterFileSystem(); diff --git a/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs b/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs index fa5ec12142..8a4c0e5dc0 100644 --- a/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs +++ b/src/Umbraco.Core/IO/MediaPathSchemes/CombinedGuidsMediaPathScheme.cs @@ -8,6 +8,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes /// /// /// Path is "{combinedGuid}/{filename}" where combinedGuid is a combination of itemGuid and propertyGuid. + /// This scheme is dangerous, as it does not prevent potential collisions. /// public class CombinedGuidsMediaPathScheme : IMediaPathScheme { diff --git a/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs b/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs new file mode 100644 index 0000000000..722c92d3de --- /dev/null +++ b/src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; + +namespace Umbraco.Core.IO.MediaPathSchemes +{ + /// + /// Implements a unique directory media path scheme. + /// + /// + /// This scheme provides short paths, yet handle potential collisions. + /// + public class UniqueMediaPathScheme : IMediaPathScheme + { + private const int DirectoryLength = 8; + + /// + public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null) + { + string directory; + + // no point "combining" guids if all we want is some random guid - just get a new one + // and then, because we don't want collisions, ensure that the directory does not already exist + // (should be quite rare, but eh...) + + do + { + var combinedGuid = Guid.NewGuid(); + directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength); // see also HexEncoder, we may want to fragment path eg 12/e4/f3... + + } while (fileSystem.DirectoryExists(directory)); + + return Path.Combine(directory, filename).Replace('\\', '/'); + } + + /// + public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath) => Path.GetDirectoryName(filepath); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index c3fe7be10a..d07c2e54eb 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -205,6 +205,7 @@ + diff --git a/src/Umbraco.Tests/IO/FileSystemsTests.cs b/src/Umbraco.Tests/IO/FileSystemsTests.cs index 1f0250c066..d4124530ba 100644 --- a/src/Umbraco.Tests/IO/FileSystemsTests.cs +++ b/src/Umbraco.Tests/IO/FileSystemsTests.cs @@ -33,7 +33,7 @@ namespace Umbraco.Tests.IO composition.Register(_ => Mock.Of()); composition.Register(_ => Mock.Of()); composition.Register(_ => Mock.Of()); - composition.RegisterUnique(); + composition.RegisterUnique(); composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings); composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings); diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 8fb8984fea..fedc94d45b 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -243,7 +243,7 @@ namespace Umbraco.Tests.Testing Composition.WithCollectionBuilder(); Composition.RegisterUnique(); - Composition.RegisterUnique(); + Composition.RegisterUnique(); // register empty content apps collection Composition.WithCollectionBuilder();