Kit.Core/LibExternal/Minio/DataModel/Args/PutObjectArgs.cs

194 lines
7.0 KiB
C#

/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2020, 2021 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Security.Cryptography;
using Minio.Helper;
namespace Minio.DataModel.Args;
public class PutObjectArgs : ObjectWriteArgs<PutObjectArgs>
{
public PutObjectArgs()
{
RequestMethod = HttpMethod.Put;
RequestBody = null;
ObjectStreamData = null;
PartNumber = 0;
ContentType = "application/octet-stream";
}
internal PutObjectArgs(PutObjectPartArgs args)
{
RequestMethod = HttpMethod.Put;
BucketName = args.BucketName;
ContentType = args.ContentType ?? "application/octet-stream";
FileName = args.FileName;
Headers = args.Headers;
ObjectName = args.ObjectName;
ObjectSize = args.ObjectSize;
PartNumber = args.PartNumber;
SSE = args.SSE;
UploadId = args.UploadId;
}
internal string UploadId { get; private set; }
internal int PartNumber { get; set; }
internal string FileName { get; set; }
internal long ObjectSize { get; set; }
internal Stream ObjectStreamData { get; set; }
internal IProgress<ProgressReport> Progress { get; set; }
internal override void Validate()
{
base.Validate();
// Check atleast one of filename or stream are initialized
if (string.IsNullOrWhiteSpace(FileName) && ObjectStreamData is null)
throw new InvalidOperationException("One of " + nameof(FileName) + " or " + nameof(ObjectStreamData) +
" must be set.");
if (PartNumber < 0)
throw new InvalidDataException("Invalid Part number value. Cannot be less than 0");
// Check if only one of filename or stream are initialized
if (!string.IsNullOrWhiteSpace(FileName) && ObjectStreamData is not null)
throw new InvalidOperationException("Only one of " + nameof(FileName) + " or " + nameof(ObjectStreamData) +
" should be set.");
if (!string.IsNullOrWhiteSpace(FileName)) Utils.ValidateFile(FileName);
// Check object size when using stream data
if (ObjectStreamData is not null && ObjectSize == 0)
throw new InvalidOperationException($"{nameof(ObjectSize)} must be set");
Populate();
}
private void Populate()
{
if (!string.IsNullOrWhiteSpace(FileName))
{
var fileInfo = new FileInfo(FileName);
ObjectSize = fileInfo.Length;
ObjectStreamData = new FileStream(FileName, FileMode.Open, FileAccess.Read);
}
}
internal override HttpRequestMessageBuilder BuildRequest(HttpRequestMessageBuilder requestMessageBuilder)
{
requestMessageBuilder = base.BuildRequest(requestMessageBuilder);
if (string.IsNullOrWhiteSpace(ContentType)) ContentType = "application/octet-stream";
if (!Headers.ContainsKey("Content-Type")) Headers["Content-Type"] = ContentType;
requestMessageBuilder.AddOrUpdateHeaderParameter("Content-Type", Headers["Content-Type"]);
if (!string.IsNullOrWhiteSpace(UploadId) && PartNumber > 0)
{
requestMessageBuilder.AddQueryParameter("uploadId", $"{UploadId}");
requestMessageBuilder.AddQueryParameter("partNumber", $"{PartNumber}");
}
if (ObjectTags?.TaggingSet?.Tag.Count > 0)
requestMessageBuilder.AddOrUpdateHeaderParameter("x-amz-tagging", ObjectTags.GetTagString());
if (Retention is not null)
{
requestMessageBuilder.AddOrUpdateHeaderParameter("x-amz-object-lock-retain-until-date",
Retention.RetainUntilDate);
requestMessageBuilder.AddOrUpdateHeaderParameter("x-amz-object-lock-mode", Retention.Mode.ToString());
requestMessageBuilder.AddOrUpdateHeaderParameter("Content-Md5",
Utils.GetMD5SumStr(RequestBody.Span));
}
if (LegalHoldEnabled is not null)
requestMessageBuilder.AddOrUpdateHeaderParameter("x-amz-object-lock-legal-hold",
LegalHoldEnabled == true ? "ON" : "OFF");
if (!RequestBody.IsEmpty)
{
#if NETSTANDARD
using var sha = SHA256.Create();
var hash
= sha.ComputeHash(RequestBody.ToArray());
#else
var hash = SHA256.HashData(RequestBody.Span);
#endif
var hex = BitConverter.ToString(hash).Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase)
.ToLowerInvariant();
requestMessageBuilder.AddOrUpdateHeaderParameter("x-amz-content-sha256", hex);
requestMessageBuilder.SetBody(RequestBody);
}
return requestMessageBuilder;
}
public override PutObjectArgs WithHeaders(IDictionary<string, string> headers)
{
Headers ??= new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (headers is not null)
foreach (var p in headers)
{
var key = p.Key;
if (!OperationsUtil.IsSupportedHeader(p.Key) &&
!p.Key.StartsWith("x-amz-meta-", StringComparison.OrdinalIgnoreCase) &&
!OperationsUtil.IsSSEHeader(p.Key))
{
key = "x-amz-meta-" + key.ToLowerInvariant();
_ = Headers.Remove(p.Key);
}
Headers[key] = p.Value;
if (string.Equals(key, "Content-Type", StringComparison.OrdinalIgnoreCase))
ContentType = p.Value;
}
if (string.IsNullOrWhiteSpace(ContentType)) ContentType = "application/octet-stream";
if (!Headers.ContainsKey("Content-Type")) Headers["Content-Type"] = ContentType;
return this;
}
internal PutObjectArgs WithUploadId(string id = null)
{
UploadId = id;
return this;
}
internal PutObjectArgs WithPartNumber(int num)
{
PartNumber = num;
return this;
}
public PutObjectArgs WithFileName(string file)
{
FileName = file;
return this;
}
public PutObjectArgs WithObjectSize(long size)
{
ObjectSize = size;
return this;
}
public PutObjectArgs WithStreamData(Stream data)
{
ObjectStreamData = data;
return this;
}
public PutObjectArgs WithProgress(IProgress<ProgressReport> progress)
{
Progress = progress;
return this;
}
}