using Dpz.Core.Infrastructure;
using Microsoft.Extensions.Logging;
namespace Dpz.Core.Service.ObjectStorage;
public class UpyunUpload(HttpClient httpClient,ILogger<UpyunUpload> logger)
{
internal async Task<UploadResult> UploadAsync<TOperator>(
ICollection<string> pathToFile,
Func<HttpContent> setContent,
TOperator operatorConfiguration,
string? contentMd5 = null)
where TOperator : UpyunOperator
{
if (pathToFile.Count == 0)
{
throw new ArgumentException("argument pathToFile does not any contain item.", nameof(pathToFile));
}
if (string.IsNullOrEmpty(operatorConfiguration.Bucket))
{
throw new ArgumentException("argument operatorConfiguration does not have bucket.", nameof(operatorConfiguration));
}
var uploadAddress = string.Join("/", pathToFile.Select(Uri.EscapeDataString));
var request = new HttpRequestMessage(HttpMethod.Put, $"/{operatorConfiguration.Bucket}/{uploadAddress}")
{
Version = new Version(2, 0)
};
await request.SignatureAsync(operatorConfiguration, contentMd5);
request.Content = setContent();
var response = await httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
logger.LogError("upload fail,status code:{StatusCode}", response.StatusCode);
throw new BusinessException($"upload fail,response status code:{response.StatusCode}");
}
#region upload result
var uploadResult = new UploadResult
{
AccessUrl = GetAccessUrl(uploadAddress,operatorConfiguration),
FileType = response.Headers.GetResponseHeaderValue("x-upyun-file-type", ""),
};
var frames = response.Headers.GetResponseHeaderValue("x-upyun-frames", "0");
if (int.TryParse(frames, out var framesInt))
{
uploadResult.Frames = framesInt;
}
var width = response.Headers.GetResponseHeaderValue("x-upyun-width", "0");
if (int.TryParse(width, out var widthInt))
{
uploadResult.Width = widthInt;
}
var height = response.Headers.GetResponseHeaderValue("x-upyun-height", "0");
if (int.TryParse(height, out var heightInt))
{
uploadResult.Height = heightInt;
}
if (response.Content.Headers.ContentMD5 != null)
{
var md5Value = BitConverter.ToString(response.Content.Headers.ContentMD5).Replace("-", "")
.ToLowerInvariant();
logger.LogInformation("upload file:{AccessUrl},MD5 value:{MD5Value}", uploadResult.AccessUrl, md5Value);
uploadResult.Md5 = md5Value;
}
#endregion
return uploadResult;
}
private static string GetAccessUrl<TOperator>(string pathToFile, TOperator upyunOperator)
where TOperator : UpyunOperator
{
return (upyunOperator.Host?.LastOrDefault() == '/' ? upyunOperator.Host : upyunOperator.Host + "/") +
pathToFile;
}
}