网站首页 网站源码
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;
}
}
上述代码定义了一个名为 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。