Files

167 lines
5.2 KiB
C#
Raw Permalink Normal View History

2024-07-10 00:52:51 +08:00
#nullable enable
using System;
using System.IO;
using Microsoft.AspNetCore.Http;
using Minio;
2024-07-10 03:30:09 +08:00
using Minio.DataModel.Args;
2024-04-16 06:57:56 +08:00
using SimApi.Configurations;
2024-03-23 07:29:43 +08:00
namespace SimApi.Helpers;
public class SimApiStorage
{
2024-07-10 03:30:09 +08:00
private IMinioClient Mc { get; }
2024-03-23 07:29:43 +08:00
2024-07-10 03:30:09 +08:00
public IMinioClient Client => Mc;
2024-03-23 07:29:43 +08:00
private string ServeUrl { get; }
2024-07-10 00:52:51 +08:00
private string Endpoint { get; }
2024-06-27 04:38:04 +08:00
public string Bucket { get; }
2024-03-23 07:29:43 +08:00
private IHttpContextAccessor HttpContextAccessor { get; }
public SimApiStorage(SimApiOptions apiOptions, IHttpContextAccessor httpContextAccessor)
{
2024-03-23 07:29:43 +08:00
var options = apiOptions.SimApiStorageOptions;
HttpContextAccessor = httpContextAccessor;
2024-07-26 08:11:21 +08:00
Endpoint = options.Endpoint!;
2024-03-23 07:29:43 +08:00
var useSsl = false;
string endpoint;
2024-07-26 08:11:21 +08:00
if (options.Endpoint!.StartsWith("http://"))
{
2024-03-23 07:29:43 +08:00
endpoint = options.Endpoint.Replace("http://", string.Empty);
}
else if (options.Endpoint.StartsWith("https://"))
{
endpoint = options.Endpoint.Replace("https://", string.Empty);
useSsl = true;
}
else
{
throw new Exception("SimApiStorage: Error Endpoint");
}
2024-07-26 08:11:21 +08:00
ServeUrl = options.ServeUrl!;
2024-07-10 00:52:51 +08:00
if (ServeUrl.EndsWith('/')) throw new Exception("SimApiStorage: ServeUrl must not end with /");
2024-07-26 08:11:21 +08:00
Bucket = options.Bucket!;
2024-03-23 07:29:43 +08:00
var mcb = new MinioClient().WithEndpoint(endpoint)
.WithCredentials(options.AccessKey, options.SecretKey);
if (useSsl)
2021-09-29 02:37:14 +08:00
{
2024-03-23 07:29:43 +08:00
mcb = mcb.WithSSL();
2021-09-29 02:37:14 +08:00
}
2024-04-16 06:57:56 +08:00
2024-03-23 07:29:43 +08:00
Mc = mcb.Build();
2021-09-29 02:37:14 +08:00
2024-03-23 07:29:43 +08:00
var found = Mc.BucketExistsAsync(new BucketExistsArgs().WithBucket(Bucket)).Result;
if (!found)
{
2024-03-23 07:29:43 +08:00
Mc.MakeBucketAsync(new MakeBucketArgs().WithBucket(Bucket)).Wait();
}
}
2024-03-23 07:29:43 +08:00
/// <summary>
/// 获取上传的URL
/// </summary>
/// <param name="path"></param>
/// <param name="expire"></param>
/// <returns></returns>
2024-07-10 00:52:51 +08:00
public GetUploadUrlResponse GetUploadUrl(string path, int expire = 7200)
2024-03-23 07:29:43 +08:00
{
2024-07-10 00:52:51 +08:00
CheckPath(path);
var obj = path.TrimStart('/');
var uploadUrl = Mc.PresignedPutObjectAsync(new PresignedPutObjectArgs().WithBucket(Bucket)
.WithObject(obj).WithExpiry(expire)).Result;
return new GetUploadUrlResponse(uploadUrl, $"{ServeUrl}{path}", path);
2024-03-23 07:29:43 +08:00
}
/// <summary>
/// 获取下载的URL
/// </summary>
/// <param name="path"></param>
/// <param name="expire"></param>
/// <returns></returns>
public string GetDownloadUrl(string path, int expire = 600)
{
2024-07-10 00:52:51 +08:00
CheckPath(path);
path = path.TrimStart('/');
2024-03-23 07:29:43 +08:00
return Mc.PresignedGetObjectAsync(new PresignedGetObjectArgs().WithBucket(Bucket).WithObject(path)
.WithExpiry(expire)).Result;
}
2024-07-10 00:52:51 +08:00
/// <summary>
/// 直接上传文件
/// </summary>
/// <param name="path"></param>
/// <param name="stream"></param>
/// <param name="contentType"></param>
public void UploadFile(string path, Stream stream, string contentType = "image/png")
2024-03-23 07:29:43 +08:00
{
2024-07-10 00:52:51 +08:00
CheckPath(path);
path = path.TrimStart('/');
2024-03-23 07:29:43 +08:00
Mc.PutObjectAsync(new PutObjectArgs().WithBucket(Bucket).WithObject(path).WithObjectSize(stream.Length)
.WithStreamData(stream).WithContentType(contentType)).Wait();
}
2024-07-10 00:52:51 +08:00
/// <summary>
/// 使用path获取完整的访问URL
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
2024-08-03 19:21:23 +08:00
public string? FullUrl(string? path)
2024-03-23 07:29:43 +08:00
{
2024-07-10 06:29:36 +08:00
if (string.IsNullOrEmpty(path)) return path;
2024-07-10 00:52:51 +08:00
if(path.StartsWith("http://") || path.StartsWith("https://")) return path;
2024-07-10 06:29:36 +08:00
if (!(path.StartsWith('/') || path.StartsWith("~/"))) return path;
2024-03-23 07:29:43 +08:00
var httpRequest = HttpContextAccessor.HttpContext?.Request;
var url = $"{httpRequest?.Scheme}://{httpRequest?.Host}";
if (string.IsNullOrEmpty(path))
{
return path;
}
return path.StartsWith('~') ? string.Concat(url, path.AsSpan(1, path.Length - 1)) : $"{ServeUrl}{path}";
}
2024-07-10 00:52:51 +08:00
2024-07-10 06:35:19 +08:00
/// <summary>
/// 获取一个Path得访问URL
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string? GetUrl(string? path)
{
if (string.IsNullOrEmpty(path)) return path;
if (path.StartsWith("~/"))
{
var httpRequest = HttpContextAccessor.HttpContext?.Request;
var url = $"{httpRequest?.Scheme}://{httpRequest?.Host}";
return string.Concat(url, path.AsSpan(1, path.Length - 1));
}
if (path.StartsWith('/'))
{
return $"{ServeUrl}{path}";
}
return path;
}
2024-07-10 00:52:51 +08:00
/// <summary>
/// 从URL中获取相对路径 (如果url不是当前服务器的url,则原样返回)
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public string? GetPath(string? url)
{
2024-07-21 13:50:12 +08:00
return url?.Replace($"{Endpoint}/{Bucket}", string.Empty).Replace(ServeUrl,string.Empty);
2024-07-10 00:52:51 +08:00
}
private void CheckPath(string path)
{
if (!path.StartsWith('/')) throw new Exception("path must start with /");
}
}
public record GetUploadUrlResponse(string UploadUrl, string DownloadUrl, string Path);