diff --git a/Minio.Functional.Tests/FunctionalTest.cs b/Minio.Functional.Tests/FunctionalTest.cs index e7393fd3..0dc4d0f7 100644 --- a/Minio.Functional.Tests/FunctionalTest.cs +++ b/Minio.Functional.Tests/FunctionalTest.cs @@ -1,4 +1,4 @@ -/* +/* * MinIO .NET Library for Amazon S3 Compatible Cloud Storage, * (C) 2017-2021 MinIO, Inc. * @@ -4657,16 +4657,16 @@ internal static async Task GetObject_Test1(IMinioClient minio) try { await Setup_Test(minio, bucketName).ConfigureAwait(false); - - using (var filestream = rsg.GenerateStreamFromSeed(1 * MB)) + Stream strm; + await using ((strm = rsg.GenerateStreamFromSeed(1 * MB)).ConfigureAwait(false)) { - var file_write_size = filestream.Length; + var file_write_size = strm.Length; long file_read_size = 0; var putObjectArgs = new PutObjectArgs() .WithBucket(bucketName) .WithObject(objectName) - .WithStreamData(filestream) - .WithObjectSize(filestream.Length) + .WithStreamData(strm) + .WithObjectSize(strm.Length) .WithContentType(contentType); _ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false); @@ -4775,6 +4775,85 @@ internal static async Task GetObject_Test2(IMinioClient minio) } } + internal static async Task GetObjectNegObjNotFound_Test3(IMinioClient minio) + { + var stopwatch = Stopwatch.StartNew(); + var bucketName = GetRandomName(15); + var objectName = GetRandomObjectName(10); + var args = new Dictionary + (StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } }; + try + { + await Setup_Test(minio, bucketName).ConfigureAwait(false); + // Don't Put the object, so we can hit "ObjectNotFound" exception + var getObjectArgs = new GetObjectArgs() + .WithBucket(bucketName) + .WithObject(objectName) + .WithCallbackStream(_ => throw new Exception("Should never be reached at the Callback function")); + _ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false); + new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature, + "Tests whether GetObjectAsync hits ObjectNotFoundException", + TestStatus.FAIL, stopwatch.Elapsed, "Failed to hit ObjectNotFoundxception", args: args).Log(); + throw new Exception("Failed to hit ObjectNotFoundException"); + } + catch (ObjectNotFoundException) + { + new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature, + "Tests whether GetObjectAsync hits ObjectNotFoundException", + TestStatus.PASS, stopwatch.Elapsed, args: args).Log(); + } + catch (Exception ex) + { + new MintLogger("GetObjectNegObjNotFound_Test3", getObjectSignature, + "Tests whether GetObjectAsync hits ObjectNotFoundException", + TestStatus.FAIL, stopwatch.Elapsed, ex.Message, ex.ToString(), args: args).Log(); + throw; + } + finally + { + await TearDown(minio, bucketName).ConfigureAwait(false); + } + } + + internal static async Task GetObjectNegBcktNotFound_Test4(IMinioClient minio) + { + var stopwatch = Stopwatch.StartNew(); + var bucketName = GetRandomName(15); + var objectName = GetRandomObjectName(10); + var args = new Dictionary + (StringComparer.Ordinal) { { "bucketName", bucketName }, { "objectName", objectName } }; + try + { + // No object, no bucket, so we can hit "BucketNotFoundException" with + var getObjectArgs = new GetObjectArgs() + .WithBucket(bucketName) + .WithObject(objectName) + .WithCallbackStream(_ => throw new Exception("Should never be reached")); + _ = await minio.GetObjectAsync(getObjectArgs).ConfigureAwait(false); + new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature, + "Tests whether GetObjectAsync hits BucketNotFoundException", + TestStatus.FAIL, stopwatch.Elapsed, "Failed to hit BucketNotFoundException", args: args).Log(); + throw new Exception("Failed to hit BucketNotFoundException"); + } + catch (BucketNotFoundException) + { + new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature, + "Tests whether GetObjectAsync hits BucketNotFoundException", + TestStatus.PASS, stopwatch.Elapsed, args: args).Log(); + } + catch (Exception ex) + { + new MintLogger("GetObjectNegBcktNotFound_Test4", getObjectSignature, + "Tests whether GetObjectAsync hits BucketNotFoundException", + TestStatus.FAIL, stopwatch.Elapsed, ex.Message, ex.ToString(), args: args).Log(); + throw; + } + finally + { + await TearDown(minio, bucketName).ConfigureAwait(false); + } + } + internal static async Task GetObject_3_OffsetLength_Tests(IMinioClient minio) // 3 tests will run to check different values of offset and length parameters // when GetObject api returns part of the object as defined by the offset diff --git a/Minio.Functional.Tests/Program.cs b/Minio.Functional.Tests/Program.cs index 20297e92..65239f3f 100644 --- a/Minio.Functional.Tests/Program.cs +++ b/Minio.Functional.Tests/Program.cs @@ -151,6 +151,8 @@ public static async Task Main(string[] args) // Test GetObjectAsync function functionalTestTasks.Add(FunctionalTest.GetObject_Test1(minioClient)); functionalTestTasks.Add(FunctionalTest.GetObject_Test2(minioClient)); + functionalTestTasks.Add(FunctionalTest.GetObjectNegObjNotFound_Test3(minioClient)); + functionalTestTasks.Add(FunctionalTest.GetObjectNegBcktNotFound_Test4(minioClient)); // 3 tests will run to check different values of offset and length parameters // when GetObject api returns part of the object as defined by the offset // and length parameters. Tests will be reported as GetObject_Test3, diff --git a/Minio/ApiEndpoints/BucketOperations.cs b/Minio/ApiEndpoints/BucketOperations.cs index 95f1cb04..1a7cb5f0 100644 --- a/Minio/ApiEndpoints/BucketOperations.cs +++ b/Minio/ApiEndpoints/BucketOperations.cs @@ -90,10 +90,9 @@ await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder, HttpStatusCode.NotFound != ice.ServerResponse.StatusCode) && ice.ServerResponse is not null; } - catch (Exception ex) + catch (BucketNotFoundException) { - if (ex.GetType() == typeof(BucketNotFoundException)) return false; - throw; + return false; } } diff --git a/Minio/RequestExtensions.cs b/Minio/RequestExtensions.cs index aa955e55..5cd32ec5 100644 --- a/Minio/RequestExtensions.cs +++ b/Minio/RequestExtensions.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Net; +using System.Web; using Minio.Credentials; using Minio.DataModel; using Minio.DataModel.Args; @@ -80,7 +81,6 @@ private static async Task ExecuteTaskCoreAsync(this IMinioClient CancellationToken cancellationToken = default) { var startTime = DateTime.Now; - var v4Authenticator = new V4Authenticator(minioClient.Config.Secure, minioClient.Config.AccessKey, minioClient.Config.SecretKey, minioClient.Config.Region, minioClient.Config.SessionToken); @@ -101,19 +101,29 @@ private static async Task ExecuteTaskCoreAsync(this IMinioClient await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancellationToken) .ConfigureAwait(false); - var path = request.RequestUri.LocalPath.TrimStart('/').TrimEnd('/').Split('/'); + var path = request.RequestUri.LocalPath.TrimStart('/').TrimEnd('/') + .Split('/', StringSplitOptions.RemoveEmptyEntries); if (responseResult.Response.StatusCode == HttpStatusCode.NotFound) { + if (request.Method == HttpMethod.Get) + { + var q = HttpUtility.ParseQueryString(request.RequestUri.Query); + if (q.Get("object-lock") != null) + { + responseResult.Exception = new MissingObjectLockConfigurationException(); + return responseResult; + } + } + if (request.Method == HttpMethod.Head) { - if (responseResult.Exception?.GetType().Equals(typeof(BucketNotFoundException)) == true || - path.Length == 1) + if (responseResult.Exception is BucketNotFoundException || path.Length == 1) responseResult.Exception = new BucketNotFoundException(); if (path.Length > 1) { var found = await minioClient - .BucketExistsAsync(new BucketExistsArgs().WithBucket(path.ToList()[0]), cancellationToken) + .BucketExistsAsync(new BucketExistsArgs().WithBucket(path[0]), cancellationToken) .ConfigureAwait(false); responseResult.Exception = !found ? new Exception("ThrowBucketNotFoundException") @@ -122,10 +132,11 @@ await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancell } } - if (request.RequestUri.ToString().Contains("lock", StringComparison.OrdinalIgnoreCase) && - request.Method == HttpMethod.Get) - responseResult.Exception = new MissingObjectLockConfigurationException(); + return responseResult; } + + minioClient.HandleIfErrorResponse(responseResult, errorHandlers, startTime); + return responseResult; } catch (Exception ex) when (ex is not (OperationCanceledException or ObjectNotFoundException)) @@ -139,9 +150,6 @@ await requestMessageBuilder.ResponseWriter(responseResult.ContentStream, cancell responseResult = new ResponseResult(request, ex); return responseResult; } - - minioClient.HandleIfErrorResponse(responseResult, errorHandlers, startTime); - return responseResult; } private static Task ExecuteWithRetry(this IMinioClient minioClient,