From 7e7abe53f9ed6022329d8ac3ceebad6cb7f8ca63 Mon Sep 17 00:00:00 2001 From: Bruno Gale Date: Wed, 30 Sep 2026 20:50:04 +0200 Subject: [PATCH] fix(storage): close the local file after a resumable upload --- .../Files/ResumableUploadContractTests.cs | 13 +++++++++++++ .../Storage/Extensions/HttpClientProgress.cs | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/Storage/Storage.Tests/Files/ResumableUploadContractTests.cs b/packages/Storage/Storage.Tests/Files/ResumableUploadContractTests.cs index 7b9e6470..332a38ca 100644 --- a/packages/Storage/Storage.Tests/Files/ResumableUploadContractTests.cs +++ b/packages/Storage/Storage.Tests/Files/ResumableUploadContractTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Threading.Tasks; using FluentAssertions; @@ -9,6 +10,7 @@ using WireMock.RequestBuilders; using WireMock.ResponseBuilders; using WireMock.Server; +using FileOptions = Supabase.Storage.FileOptions; namespace Storage.Tests.Files { @@ -77,6 +79,17 @@ public async Task UploadOrResume_ShouldResumeCachedSessionWithoutCreating() } } + [TestMethod] + public async Task UploadOrResume_ShouldCloseTheLocalFile() + { + var path = Path.GetTempFileName(); + await File.WriteAllBytesAsync(path, Payload); + await this.client.From(Bucket).UploadOrResume(path, FileName, new FileOptions()); + FluentActions.Invoking(() => File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None).Dispose()) + .Should().NotThrow("the caller must be able to move or delete the file after the upload"); + File.Delete(path); + } + private void StubTusEndpoints() { var length = Payload.Length.ToString(CultureInfo.InvariantCulture); diff --git a/packages/Storage/Storage/Extensions/HttpClientProgress.cs b/packages/Storage/Storage/Extensions/HttpClientProgress.cs index e5df27b0..13d55f0e 100644 --- a/packages/Storage/Storage/Extensions/HttpClientProgress.cs +++ b/packages/Storage/Storage/Extensions/HttpClientProgress.cs @@ -253,7 +253,7 @@ public static async Task UploadAsync( } } - public static Task UploadOrContinueFileAsync( + public static async Task UploadOrContinueFileAsync( this HttpClient client, Uri uri, string filePath, @@ -263,8 +263,8 @@ public static Task UploadOrContinueFileAsync( CancellationToken cancellationToken = default ) { - var fileStream = new FileStream(filePath, mode: FileMode.Open, FileAccess.Read); - return ResumableUploadAsync( + using var fileStream = new FileStream(filePath, mode: FileMode.Open, FileAccess.Read); + return await ResumableUploadAsync( client, uri, fileStream, @@ -272,7 +272,7 @@ public static Task UploadOrContinueFileAsync( headers, progress, cancellationToken - ); + ).ConfigureAwait(false); } public static Task UploadOrContinueByteAsync(