Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 43 additions & 26 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,11 @@ internal static async Task BucketExists_Test(IMinioClient minio)

try
{
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
await minio.RemoveBucketAsync(rbArgs).ConfigureAwait(false);
var found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsFalse(found);
await minio.MakeBucketAsync(mbArgs).ConfigureAwait(false);
found = await minio.BucketExistsAsync(beArgs).ConfigureAwait(false);
Assert.IsTrue(found);
new MintLogger(nameof(BucketExists_Test), bucketExistsSignature, "Tests whether BucketExists passes",
TestStatus.PASS, DateTime.Now - startTime, args: args).Log();
Expand Down Expand Up @@ -1006,7 +1009,7 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
filestream = bs.AsStream();
}

using (filestream)
await using (filestream.ConfigureAwait(false))
{
var file_write_size = filestream.Length;
var tempFileName = "tempfile-" + GetRandomName();
Expand All @@ -1019,7 +1022,7 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
.WithProgress(progress)
.WithContentType(contentType)
.WithHeaders(metaData);
await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
var statPutObj = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);

var statObjectArgs = new StatObjectArgs()
.WithBucket(bucketName)
Expand All @@ -1035,11 +1038,6 @@ internal static async Task<ObjectStat> PutObject_Tester(IMinioClient minio,
Assert.IsNotNull(statObject.ContentType);
Assert.IsTrue(statObject.ContentType.Equals(contentType, StringComparison.OrdinalIgnoreCase));
}

var rmArgs = new RemoveObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName);
await minio.RemoveObjectAsync(rmArgs).ConfigureAwait(false);
}

return statObject;
Expand Down Expand Up @@ -3504,8 +3502,11 @@ internal static async Task PutObject_Test9(IMinioClient minio)
totalBytesTransferred = progressReport.TotalBytesTransferred;
// Console.WriteLine(
// $"PutObject_Test9 - Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
// if (progressReport.Percentage != 100)
// Console.SetCursorPosition(0, Console.CursorTop - 1);
if (progressReport.Percentage != 100)
{
var topPosition = Console.CursorTop > 0 ? Console.CursorTop - 1 : Console.CursorTop;
Console.SetCursorPosition(0, topPosition);
}
// else Console.WriteLine();
});
var args = new Dictionary<string, string>
Expand All @@ -3519,8 +3520,10 @@ internal static async Task PutObject_Test9(IMinioClient minio)
try
{
await Setup_Test(minio, bucketName).ConfigureAwait(false);
_ = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
rsg.GenerateStreamFromSeed(objSize), progress).ConfigureAwait(false);

var stream = rsg.GenerateStreamFromSeed(objSize);
var statObj = await PutObject_Tester(minio, bucketName, objectName, null, contentType, 0, null,
stream, progress).ConfigureAwait(false);
Assert.IsTrue(percentage == 100);
Assert.IsTrue(totalBytesTransferred == objSize);
new MintLogger(nameof(PutObject_Test9), putObjectSignature,
Expand Down Expand Up @@ -3556,8 +3559,11 @@ internal static async Task PutObject_Test10(IMinioClient minio)
totalBytesTransferred = progressReport.TotalBytesTransferred;
// Console.WriteLine(
// $"PutObject_Test10 - Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
// if (progressReport.Percentage != 100)
// Console.SetCursorPosition(0, Console.CursorTop - 1);
if (progressReport.Percentage != 100)
{
var topPosition = Console.CursorTop > 0 ? Console.CursorTop - 1 : Console.CursorTop;
Console.SetCursorPosition(0, topPosition);
}
// else Console.WriteLine();
});
var args = new Dictionary<string, string>
Expand Down Expand Up @@ -3673,6 +3679,9 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
var startTime = DateTime.Now;
var bucketName = GetRandomName(15);
var objectName = GetRandomObjectName(10);
var objectSize = 1 * KB;
var objectSizeStr = objectSize.ToString(CultureInfo.InvariantCulture)
.Replace(" * ", "", StringComparison.Ordinal);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var args = new Dictionary<string, string>
Expand All @@ -3682,30 +3691,30 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
{ "objectName", objectName },
{ "destBucketName", destBucketName },
{ "destObjectName", destObjectName },
{ "data", "1KB" },
{ "size", "1KB" }
{ "data", objectSizeStr },
{ "size", objectSizeStr }
};
try
{
// Test CopyConditions where matching ETag is not found
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);

using var filestream = rsg.GenerateStreamFromSeed(1 * KB);
using var filestream = rsg.GenerateStreamFromSeed(objectSize);
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length)
.WithHeaders(null);
.WithObjectSize(filestream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}
catch (Exception ex)
{
await TearDown(minio, bucketName).ConfigureAwait(false);
await TearDown(minio, destBucketName).ConfigureAwait(false);
new MintLogger("CopyObject_Test2", copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch (initial part) passes", TestStatus.FAIL,
DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
Expand All @@ -3724,6 +3733,10 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
.WithObject(destObjectName);

await minio.CopyObjectAsync(copyObjectArgs).ConfigureAwait(false);

new MintLogger("CopyObject_Test2", copyObjectSignature,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.PASS, DateTime.Now - startTime,
args: args).Log();
}
catch (MinioException ex)
{
Expand All @@ -3732,21 +3745,23 @@ internal static async Task CopyObject_Test2(IMinioClient minio)
StringComparison.OrdinalIgnoreCase))
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.PASS, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.PASS,
DateTime.Now - startTime,
args: args).Log();
}
else
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.FAIL,
DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
}
catch (Exception ex)
{
new MintLogger(nameof(CopyObject_Test2), copyObjectSignature,
"Tests whether CopyObject with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
"Tests whether CopyObject_Test2 with Etag mismatch passes", TestStatus.FAIL, DateTime.Now - startTime,
ex.Message, ex.ToString(), args: args).Log();
throw;
}
Expand Down Expand Up @@ -4074,6 +4089,7 @@ internal static async Task CopyObject_Test7(IMinioClient minio)
var objectName = GetRandomObjectName(10);
var destBucketName = GetRandomName(15);
var destObjectName = GetRandomName(10);
var objectSize = 1 * KB;
var args = new Dictionary<string, string>
(StringComparer.Ordinal)
{
Expand All @@ -4089,13 +4105,14 @@ internal static async Task CopyObject_Test7(IMinioClient minio)
// Test CopyConditions where matching ETag is found
await Setup_Test(minio, bucketName).ConfigureAwait(false);
await Setup_Test(minio, destBucketName).ConfigureAwait(false);
using (var filestream = rsg.GenerateStreamFromSeed(1 * KB))
Stream stream = null;
await using ((stream = rsg.GenerateStreamFromSeed(objectSize)).ConfigureAwait(false))
{
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithStreamData(filestream)
.WithObjectSize(filestream.Length);
.WithStreamData(stream)
.WithObjectSize(stream.Length);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
}

Expand Down
6 changes: 3 additions & 3 deletions Minio.Functional.Tests/Minio.Functional.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<ProjectReference Include="..\Minio\Minio.csproj" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) ">
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) ">
<Reference Include="System.Web" />
</ItemGroup>

</Project>
15 changes: 6 additions & 9 deletions Minio/ApiEndpoints/BucketOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,21 @@ public async Task<bool> BucketExistsAsync(BucketExistsArgs args, CancellationTok
using var response =
await this.ExecuteTaskAsync(ResponseErrorHandlers, requestMessageBuilder,
cancellationToken: cancellationToken).ConfigureAwait(false);
if (response.Exception is not null &&
response.Exception.GetType() == typeof(BucketNotFoundException))
return false;
return response is not null &&
(response.Exception is null ||
response.Exception.GetType() != typeof(BucketNotFoundException));
}
catch (InternalClientException ice)
{
if ((ice.ServerResponse is not null &&
HttpStatusCode.NotFound.Equals(ice.ServerResponse.StatusCode)) ||
ice.ServerResponse is null)
return false;
return (ice.ServerResponse is null ||
!HttpStatusCode.NotFound.Equals(ice.ServerResponse.StatusCode)) &&
ice.ServerResponse is not null;
}
catch (Exception ex)
{
if (ex.GetType() == typeof(BucketNotFoundException)) return false;
throw;
}

return true;
}

/// <summary>
Expand Down
14 changes: 6 additions & 8 deletions Minio/ApiEndpoints/ObjectOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,12 @@ public async Task CopyObjectAsync(CopyObjectArgs args, CancellationToken cancell
(srcByteRangeSize > 0 &&
args.SourceObject.CopyOperationConditions.byteRangeEnd >=
args.SourceObjectInfo.Size))
throw new InvalidDataException(
$"Specified byte range ({
args.SourceObject.CopyOperationConditions
.byteRangeStart.ToString(CultureInfo.InvariantCulture)}-{
args.SourceObject.CopyOperationConditions.byteRangeEnd
.ToString(CultureInfo.InvariantCulture)
}) does not fit within source object (size={
args.SourceObjectInfo.Size.ToString(CultureInfo.InvariantCulture)})");
throw new InvalidDataException($"Specified byte range ({args.SourceObject
.CopyOperationConditions
.byteRangeStart.ToString(CultureInfo.InvariantCulture)}-{args.SourceObject
.CopyOperationConditions.byteRangeEnd.ToString(CultureInfo.InvariantCulture)
}) does not fit within source object (size={args.SourceObjectInfo.Size
.ToString(CultureInfo.InvariantCulture)})");

if (copySize > Constants.MaxSingleCopyObjectSize ||
(srcByteRangeSize > 0 &&
Expand Down
2 changes: 1 addition & 1 deletion Minio/DataModel/Args/PutObjectArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public override PutObjectArgs WithHeaders(IDictionary<string, string> headers)
}

if (string.IsNullOrWhiteSpace(ContentType)) ContentType = "application/octet-stream";
if (!Headers.ContainsKey("Content-Type")) Headers["Content-Type"] = ContentType;
Headers["Content-Type"] = ContentType;
return this;
}

Expand Down
7 changes: 2 additions & 5 deletions Minio/DataModel/Response/CopyObjectResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/

using System.Net;
using System.Text;
using CommunityToolkit.HighPerformance;
using Minio.DataModel.Result;
using Minio.Helper;

Expand All @@ -27,11 +25,10 @@ internal class CopyObjectResponse : GenericResponse
public CopyObjectResponse(HttpStatusCode statusCode, string responseContent, Type reqType)
: base(statusCode, responseContent)
{
using var stream = Encoding.UTF8.GetBytes(responseContent).AsMemory().AsStream();
if (reqType == typeof(CopyObjectResult))
CopyObjectRequestResult = Utils.DeserializeXml<CopyObjectResult>(stream);
CopyObjectRequestResult = Utils.DeserializeXml<CopyObjectResult>(responseContent);
else
CopyPartRequestResult = Utils.DeserializeXml<CopyPartResult>(stream);
CopyPartRequestResult = Utils.DeserializeXml<CopyPartResult>(responseContent);
}

internal CopyObjectResult CopyObjectRequestResult { get; set; }
Expand Down
9 changes: 3 additions & 6 deletions Minio/Exceptions/MinioException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ private static string GetMessage(string message, ResponseResult serverResponse)

var contentString = serverResponse.Content;

if (message is null)
return
$"MinIO API responded with status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";

return
$"MinIO API responded with message={message}. Status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";
return message is null
? $"MinIO API responded with status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}"
: $"MinIO API responded with message={message}. Status code={serverResponse.StatusCode}, response={serverResponse.ErrorMessage}, content={contentString}";
}
}
27 changes: 27 additions & 0 deletions Minio/Exceptions/PreconditionFailedException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Minio.DataModel.Result;

namespace Minio.Exceptions;

[Serializable]
public class PreconditionFailedException : MinioException
{
public PreconditionFailedException()
{
}

public PreconditionFailedException(string message, Exception innerException) : base(message, innerException)
{
}

public PreconditionFailedException(ResponseResult serverResponse) : base(serverResponse)
{
}

public PreconditionFailedException(string message) : base(message)
{
}

public PreconditionFailedException(string message, ResponseResult serverResponse) : base(message, serverResponse)
{
}
}
32 changes: 28 additions & 4 deletions Minio/Helper/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,10 @@ public static void Print(object obj)
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
var value = prop.GetValue(obj, Array.Empty<object>());
Console.WriteLine("DEBUG >> {0} = {1}", prop.Name, value);
if (string.Equals(prop.Name, "Headers", StringComparison.Ordinal))
PrintDict((Dictionary<string, string>)value);
else
Console.WriteLine("DEBUG >> {0} = {1}", prop.Name, value);
}

Console.WriteLine("DEBUG >> Print is DONE!\n\n");
Expand All @@ -1006,9 +1009,9 @@ public static void PrintDict(IDictionary<string, string> d)
{
if (d is not null)
foreach (var kv in d)
Console.WriteLine("DEBUG >> {0} = {1}", kv.Key, kv.Value);
Console.WriteLine("DEBUG >> Dictionary({0} => {1})", kv.Key, kv.Value);

Console.WriteLine("DEBUG >> Done printing\n");
Console.WriteLine("DEBUG >> Dictionary: Done printing\n");
}

public static string DetermineNamespace(XDocument document)
Expand Down Expand Up @@ -1062,10 +1065,23 @@ public static string SerializeToXml<T>(T anyobject) where T : class
XmlResolver = null
};

var xRoot = (XmlRootAttribute)typeof(T).GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault();

var serializer = new XmlSerializer(typeof(T), xRoot);

using var stringReader = new StringReader(xml);
using var xmlReader = XmlReader.Create(stringReader, settings);
if (xml.Contains("<Error><Code>", StringComparison.Ordinal))
{
// Skip the first line
xml = xml[(xml.IndexOf('\n', StringComparison.Ordinal) + 1)..];
stringReader.Dispose();
using var stringReader1 = new StringReader(xml);
xRoot = new XmlRootAttribute { ElementName = "Error", IsNullable = true };
serializer = new XmlSerializer(typeof(T), xRoot);
return (T)serializer.Deserialize(new NamespaceIgnorantXmlTextReader(stringReader1));
}

var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(xmlReader);
}

Expand All @@ -1076,4 +1092,12 @@ private static string GetNamespace<T>()
? xmlRootAttribute.Namespace
: null;
}

// Class to ignore namespaces when de-serializing
public class NamespaceIgnorantXmlTextReader : XmlTextReader
{
public NamespaceIgnorantXmlTextReader(TextReader reader) : base(reader) { }

public override string NamespaceURI => string.Empty;
}
}
Loading