Skip to content

Commit a285ce7

Browse files
Merge pull request #64 from umbraco/bugfix/use-directory-delimiter
Use directory delimiter when listing blobs
2 parents 66d3001 + 46617eb commit a285ce7

File tree

2 files changed

+24
-32
lines changed

2 files changed

+24
-32
lines changed

src/Umbraco.StorageProviders.AzureBlob/IO/AzureBlobFileSystem.cs

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Diagnostics.CodeAnalysis;
4-
using System.IO;
5-
using System.Linq;
6-
using System.Threading.Tasks;
71
using Azure;
82
using Azure.Storage.Blobs;
93
using Azure.Storage.Blobs.Models;
@@ -59,6 +53,7 @@ public AzureBlobFileSystem(AzureBlobFileSystemOptions options, IHostingEnvironme
5953
/// <exception cref="System.ArgumentNullException"><paramref name="blobContainerClient" /> is <c>null</c>.</exception>
6054
/// <exception cref="System.ArgumentNullException"><paramref name="ioHelper" /> is <c>null</c>.</exception>
6155
/// <exception cref="System.ArgumentNullException"><paramref name="contentTypeProvider" /> is <c>null</c>.</exception>
56+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "This parameter is only a part of the URL.")]
6257
public AzureBlobFileSystem(string rootUrl, BlobContainerClient blobContainerClient, IIOHelper ioHelper, IContentTypeProvider contentTypeProvider, string? containerRootPath = null)
6358
{
6459
ArgumentNullException.ThrowIfNull(rootUrl);
@@ -98,7 +93,7 @@ public IEnumerable<string> GetDirectories(string path)
9893
{
9994
ArgumentNullException.ThrowIfNull(path);
10095

101-
return ListBlobs(GetDirectoryPath(path))
96+
return ListBlobs(path)
10297
.Where(x => x.IsPrefix)
10398
.Select(x => GetRelativePath($"/{x.Prefix}").Trim('/'));
10499
}
@@ -118,13 +113,9 @@ public void DeleteDirectory(string path, bool recursive)
118113
{
119114
ArgumentNullException.ThrowIfNull(path);
120115

121-
foreach (var blob in ListBlobs(GetDirectoryPath(path)))
116+
foreach (BlobHierarchyItem blob in ListBlobs(path, true))
122117
{
123-
if (blob.IsPrefix)
124-
{
125-
DeleteDirectory(blob.Prefix, true);
126-
}
127-
else if (blob.IsBlob)
118+
if (blob.IsBlob)
128119
{
129120
_container.GetBlobClient(blob.Blob.Name).DeleteIfExists();
130121
}
@@ -137,7 +128,10 @@ public bool DirectoryExists(string path)
137128
{
138129
ArgumentNullException.ThrowIfNull(path);
139130

140-
return GetBlobClient(GetDirectoryPath(path)).Exists();
131+
// Try getting a single item/page
132+
Page<BlobHierarchyItem>? firstPage = ListBlobs(path).AsPages(pageSizeHint: 1).FirstOrDefault();
133+
134+
return firstPage?.Values.Count > 0;
141135
}
142136

143137
/// <inheritdoc />
@@ -159,10 +153,10 @@ public void AddFile(string path, Stream stream, bool overrideIfExists)
159153
ArgumentNullException.ThrowIfNull(path);
160154
ArgumentNullException.ThrowIfNull(stream);
161155

162-
var blob = GetBlobClient(path);
156+
BlobClient blob = GetBlobClient(path);
163157
if (!overrideIfExists && blob.Exists())
164158
{
165-
throw new InvalidOperationException($"A file at path '{path}' already exists");
159+
throw new InvalidOperationException($"A file at path '{path}' already exists.");
166160
}
167161

168162
var headers = new BlobHttpHeaders();
@@ -187,10 +181,10 @@ public void AddFile(string path, string physicalPath, bool overrideIfExists = tr
187181
ArgumentNullException.ThrowIfNull(path);
188182
ArgumentNullException.ThrowIfNull(physicalPath);
189183

190-
var destinationBlob = GetBlobClient(path);
184+
BlobClient destinationBlob = GetBlobClient(path);
191185
if (!overrideIfExists && destinationBlob.Exists())
192186
{
193-
throw new InvalidOperationException($"A file at path '{path}' already exists");
187+
throw new InvalidOperationException($"A file at path '{path}' already exists.");
194188
}
195189

196190
var sourceBlob = GetBlobClient(physicalPath);
@@ -227,7 +221,7 @@ public IEnumerable<string> GetFiles(string path, string? filter)
227221
{
228222
ArgumentNullException.ThrowIfNull(path);
229223

230-
var files = ListBlobs(GetDirectoryPath(path)).Where(x => x.IsBlob).Select(x => x.Blob.Name);
224+
IEnumerable<string> files = ListBlobs(path).Where(x => x.IsBlob).Select(x => x.Blob.Name);
231225
if (!string.IsNullOrEmpty(filter) && filter != "*.*")
232226
{
233227
// TODO: Might be better to use a globbing library
@@ -267,6 +261,7 @@ public bool FileExists(string path)
267261

268262
/// <inheritdoc />
269263
/// <exception cref="System.ArgumentNullException"><paramref name="fullPathOrUrl" /> is <c>null</c>.</exception>
264+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "This method is inherited from an interface.")]
270265
public string GetRelativePath(string fullPathOrUrl)
271266
{
272267
ArgumentNullException.ThrowIfNull(fullPathOrUrl);
@@ -297,6 +292,7 @@ public string GetFullPath(string path)
297292

298293
/// <inheritdoc />
299294
/// <exception cref="System.ArgumentNullException"><paramref name="path" /> is <c>null</c>.</exception>
295+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1055:URI-like return values should not be strings", Justification = "This method is inherited from an interface.")]
300296
public string GetUrl(string? path)
301297
{
302298
ArgumentNullException.ThrowIfNull(path);
@@ -337,7 +333,7 @@ public BlobClient GetBlobClient(string path)
337333
{
338334
ArgumentNullException.ThrowIfNull(path);
339335

340-
return _container.GetBlobClient(GetBlobPath(path));
336+
return _container.GetBlobClient(GetBlobName(path));
341337
}
342338

343339
/// <inheritdoc />
@@ -346,19 +342,15 @@ public BlobClient GetBlobClient(string path)
346342
private static string EnsureUrlSeparatorChar(string path)
347343
=> path.Replace("\\", "/", StringComparison.InvariantCultureIgnoreCase);
348344

349-
private string GetDirectoryPath(string fullPathOrUrl)
345+
private Pageable<BlobHierarchyItem> ListBlobs(string path, bool recursive = false)
350346
{
351-
var path = GetFullPath(fullPathOrUrl);
347+
string? delimiter = recursive ? null : "/";
348+
string prefix = GetFullPath(path).EnsureEndsWith('/');
352349

353-
return path.Length == 0 ? path : path.EnsureEndsWith('/');
354-
}
355-
356-
private IEnumerable<BlobHierarchyItem> ListBlobs(string path)
357-
{
358-
return _container.GetBlobsByHierarchy(prefix: path);
350+
return _container.GetBlobsByHierarchy(delimiter: delimiter, prefix: prefix);
359351
}
360352

361-
private string GetBlobPath(string path)
353+
private string GetBlobName(string path)
362354
{
363355
path = EnsureUrlSeparatorChar(path);
364356

version.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3-
"version": "10.1.0-alpha",
2+
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
3+
"version": "10.0.1",
44
"assemblyVersion": {
55
"precision": "build"
66
},
@@ -20,4 +20,4 @@
2020
"release": {
2121
"branchName": "release/{version}"
2222
}
23-
}
23+
}

0 commit comments

Comments
 (0)