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