mirror of https://github.com/abpframework/abp.git
12 changed files with 339 additions and 28 deletions
@ -0,0 +1,52 @@ |
|||||
|
using System.Text.RegularExpressions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.BlobStoring.Azure |
||||
|
{ |
||||
|
public class DefaultAzureBlobNamingNormalizerProvider : IBlobNamingNormalizerProvider, ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
///https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata#container-names
|
||||
|
/// </summary>
|
||||
|
public virtual string NormalizeContainerName(string containerName) |
||||
|
{ |
||||
|
// All letters in a container name must be lowercase.
|
||||
|
containerName = containerName.ToLower(); |
||||
|
|
||||
|
// Container names can contain only letters, numbers, and the dash (-) character.
|
||||
|
containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty); |
||||
|
|
||||
|
// Every dash (-) character must be immediately preceded and followed by a letter or number;
|
||||
|
// consecutive dashes are not permitted in container names.
|
||||
|
// Container names must start or end with a letter or number
|
||||
|
containerName = Regex.Replace(containerName, "-{2,}", "-"); |
||||
|
containerName = Regex.Replace(containerName, "^-", string.Empty); |
||||
|
containerName = Regex.Replace(containerName, "-$", string.Empty); |
||||
|
|
||||
|
// Container names must be from 3 through 63 characters long.
|
||||
|
if (containerName.Length < 3) |
||||
|
{ |
||||
|
var length = containerName.Length; |
||||
|
for (var i = 0; i < 3 - length; i++) |
||||
|
{ |
||||
|
containerName += "0"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (containerName.Length > 63) |
||||
|
{ |
||||
|
containerName = containerName.Substring(0, 63); |
||||
|
} |
||||
|
|
||||
|
return containerName; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
///https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata#blob-names
|
||||
|
/// </summary>
|
||||
|
public virtual string NormalizeBlobName(string blobName) |
||||
|
{ |
||||
|
return blobName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System; |
||||
|
using System.Runtime; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.BlobStoring.FileSystem |
||||
|
{ |
||||
|
public class DefaultFileSystemBlobNamingNormalizerProvider : IBlobNamingNormalizerProvider, ITransientDependency |
||||
|
{ |
||||
|
private readonly IOSPlatformProvider _iosPlatformProvider; |
||||
|
|
||||
|
public DefaultFileSystemBlobNamingNormalizerProvider(IOSPlatformProvider iosPlatformProvider) |
||||
|
{ |
||||
|
_iosPlatformProvider = iosPlatformProvider; |
||||
|
} |
||||
|
|
||||
|
public virtual string NormalizeContainerName(string containerName) |
||||
|
{ |
||||
|
return Normalize(containerName); |
||||
|
} |
||||
|
|
||||
|
public virtual string NormalizeBlobName(string blobName) |
||||
|
{ |
||||
|
return Normalize(blobName); |
||||
|
} |
||||
|
|
||||
|
protected virtual string Normalize(string fileName) |
||||
|
{ |
||||
|
var os = _iosPlatformProvider.GetCurrentOSPlatform(); |
||||
|
if (os == OSPlatform.Windows) |
||||
|
{ |
||||
|
// A filename cannot contain any of the following characters: \ / : * ? " < > |
|
||||
|
// In order to support the directory included in the blob name, remove / and \
|
||||
|
fileName = Regex.Replace(fileName, "[:\\*\\?\"<>\\|]", string.Empty); |
||||
|
} |
||||
|
|
||||
|
return fileName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Volo.Abp.BlobStoring |
||||
|
{ |
||||
|
public interface IBlobNamingNormalizerProvider |
||||
|
{ |
||||
|
string NormalizeContainerName(string containerName); |
||||
|
|
||||
|
string NormalizeBlobName(string blobName); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace System.Runtime |
||||
|
{ |
||||
|
public interface IOSPlatformProvider |
||||
|
{ |
||||
|
OSPlatform GetCurrentOSPlatform(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System.Runtime.InteropServices; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace System.Runtime |
||||
|
{ |
||||
|
public class OSPlatformProvider : IOSPlatformProvider, ITransientDependency |
||||
|
{ |
||||
|
public OSPlatform GetCurrentOSPlatform() |
||||
|
{ |
||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
||||
|
{ |
||||
|
//MAC
|
||||
|
return OSPlatform.OSX; |
||||
|
} |
||||
|
|
||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
||||
|
{ |
||||
|
return OSPlatform.Linux; |
||||
|
} |
||||
|
|
||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
||||
|
{ |
||||
|
return OSPlatform.Windows; |
||||
|
} |
||||
|
|
||||
|
throw new Exception("Cannot determine operating system!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.BlobStoring.Azure |
||||
|
{ |
||||
|
public class DefaultAzureBlobNamingNormalizerProvider_Tests : AbpBlobStoringAzureTestCommonBase |
||||
|
{ |
||||
|
private readonly IBlobNamingNormalizerProvider _blobNamingNormalizerProvider; |
||||
|
|
||||
|
public DefaultAzureBlobNamingNormalizerProvider_Tests() |
||||
|
{ |
||||
|
_blobNamingNormalizerProvider = GetRequiredService<IBlobNamingNormalizerProvider>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName_Lowercase() |
||||
|
{ |
||||
|
var filename = "ThisIsMyContainerName"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe("thisismycontainername"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName_Only_Letters_Numbers_Dash() |
||||
|
{ |
||||
|
var filename = ",./this-i,./s-my-c,./ont,./ai+*/.=!@#$n^&*er-name.+/"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe("this-is-my-container-name"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName_Dash() |
||||
|
{ |
||||
|
var filename = "-this--is----my-container----name-"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe("this-is-my-container-name"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName_Min_Length() |
||||
|
{ |
||||
|
var filename = "a"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.Length.ShouldBeGreaterThanOrEqualTo(3); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName_Max_Length() |
||||
|
{ |
||||
|
var filename = "abpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabp"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.Length.ShouldBeLessThanOrEqualTo(63); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
using System.Runtime; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using NSubstitute; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.BlobStoring.FileSystem |
||||
|
{ |
||||
|
public class DefaultFileSystemBlobNamingNormalizerProvider_Tests : AbpBlobStoringFileSystemTestBase |
||||
|
{ |
||||
|
private readonly IBlobNamingNormalizerProvider _blobNamingNormalizerProvider; |
||||
|
|
||||
|
public DefaultFileSystemBlobNamingNormalizerProvider_Tests() |
||||
|
{ |
||||
|
_blobNamingNormalizerProvider = GetRequiredService<IBlobNamingNormalizerProvider>(); |
||||
|
} |
||||
|
|
||||
|
protected override void AfterAddApplication(IServiceCollection services) |
||||
|
{ |
||||
|
var _iosPlatformProvider = Substitute.For<IOSPlatformProvider>(); |
||||
|
_iosPlatformProvider.GetCurrentOSPlatform().Returns(OSPlatform.Windows); |
||||
|
services.AddSingleton(_iosPlatformProvider); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeContainerName() |
||||
|
{ |
||||
|
var filename = "thisismy:*?\"<>|foldername"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe("thisismyfoldername"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void NormalizeBlobName() |
||||
|
{ |
||||
|
var filename = "thisismy:*?\"<>|filename"; |
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe("thisismyfilename"); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[InlineData("/")] |
||||
|
[InlineData("\\")] |
||||
|
public void NormalizeContainerName_With_Directory(string delimiter) |
||||
|
{ |
||||
|
var filename = $"thisis{delimiter}my:*?\"<>|{delimiter}foldername";
|
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe($"thisis{delimiter}my{delimiter}foldername"); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[InlineData("/")] |
||||
|
[InlineData("\\")] |
||||
|
public void NormalizeBlobName_With_Directory(string delimiter) |
||||
|
{ |
||||
|
var filename = $"thisis{delimiter}my:*?\"<>|{delimiter}filename";
|
||||
|
filename = _blobNamingNormalizerProvider.NormalizeContainerName(filename); |
||||
|
filename.ShouldBe($"thisis{delimiter}my{delimiter}filename"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue