网站首页 网站源码
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,
CancellationToken cancellationToken = default
)
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,
cancellationToken: cancellationToken
);
request.Content = setContent();
var response = await httpClient.SendAsync(request, cancellationToken);
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;
}
}
上述代码定义了一个名为 UpyunUpload
的类,主要用于将文件上传到 Upyun 对象存储服务。以下是代码的主要功能和结构的详细解释:
UpyunUpload
HttpClient httpClient
: 用于发送 HTTP 请求的客户端。ILogger<UpyunUpload> logger
: 用于记录日志的记录器。UploadAsync<TOperator>
这是一个异步方法,负责上传文件到 Upyun。它的参数包括:
ICollection<string> pathToFile
: 要上传的文件路径集合。Func<HttpContent> setContent
: 一个函数,用于设置 HTTP 请求的内容。TOperator operatorConfiguration
: 包含上传所需配置的对象,必须是 UpyunOperator
的子类。string? contentMd5
: 可选的 MD5 校验值。参数验证:
pathToFile
是否为空,如果为空则抛出异常。operatorConfiguration.Bucket
是否为空,如果为空则抛出异常。构建上传地址:
string.Join
和 Uri.EscapeDataString
将文件路径集合转换为 URL 编码的字符串。创建 HTTP 请求:
HttpRequestMessage
对象,设置为 PUT 方法,并指定上传的 URL。SignatureAsync
方法为请求签名(假设这是一个扩展方法,用于生成请求的签名)。发送请求:
httpClient.SendAsync
发送请求,并等待响应。处理上传结果:
UploadResult
对象,存储上传结果信息。UploadResult
中。UploadResult
中。返回结果:
UploadResult
对象,包含上传后的文件信息。GetAccessUrl<TOperator>
这是一个私有静态方法,用于生成文件的访问 URL。它的参数包括:
string pathToFile
: 文件的路径。TOperator upyunOperator
: 包含主机信息的对象。整体而言,UpyunUpload
类提供了一个用于将文件上传到 Upyun 对象存储的功能,处理了请求的构建、发送、响应的处理以及错误的记录。它还提供了一个方法来生成文件的访问 URL。