From 986b4e74e6ee94d5b9d452ab7dbd83793ee0e012 Mon Sep 17 00:00:00 2001 From: xRain Date: Wed, 10 Jul 2024 00:52:51 +0800 Subject: [PATCH] new upload --- Helpers/SimApiStorage.cs | 56 +++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/Helpers/SimApiStorage.cs b/Helpers/SimApiStorage.cs index 84c45ab..7247222 100644 --- a/Helpers/SimApiStorage.cs +++ b/Helpers/SimApiStorage.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.IO; using Microsoft.AspNetCore.Http; using Minio; @@ -14,6 +15,8 @@ public class SimApiStorage private string ServeUrl { get; } + private string Endpoint { get; } + public string Bucket { get; } private IHttpContextAccessor HttpContextAccessor { get; } @@ -22,6 +25,7 @@ public class SimApiStorage { var options = apiOptions.SimApiStorageOptions; HttpContextAccessor = httpContextAccessor; + Endpoint = options.Endpoint; var useSsl = false; string endpoint; if (options.Endpoint.StartsWith("http://")) @@ -39,6 +43,7 @@ public class SimApiStorage } ServeUrl = options.ServeUrl; + if (ServeUrl.EndsWith('/')) throw new Exception("SimApiStorage: ServeUrl must not end with /"); Bucket = options.Bucket; var mcb = new MinioClient().WithEndpoint(endpoint) .WithCredentials(options.AccessKey, options.SecretKey); @@ -62,10 +67,13 @@ public class SimApiStorage /// /// /// - public string GetUploadUrl(string path, int expire = 7200) + public GetUploadUrlResponse GetUploadUrl(string path, int expire = 7200) { - return Mc.PresignedPutObjectAsync(new PresignedPutObjectArgs().WithBucket(Bucket) - .WithObject(path).WithExpiry(expire)).Result; + 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); } /// @@ -76,20 +84,37 @@ public class SimApiStorage /// public string GetDownloadUrl(string path, int expire = 600) { + CheckPath(path); + path = path.TrimStart('/'); return Mc.PresignedGetObjectAsync(new PresignedGetObjectArgs().WithBucket(Bucket).WithObject(path) .WithExpiry(expire)).Result; } - public string UploadFile(string path, Stream stream, string contentType = "image/png") + /// + /// 直接上传文件 + /// + /// + /// + /// + public void UploadFile(string path, Stream stream, string contentType = "image/png") { + CheckPath(path); + path = path.TrimStart('/'); Mc.PutObjectAsync(new PutObjectArgs().WithBucket(Bucket).WithObject(path).WithObjectSize(stream.Length) .WithStreamData(stream).WithContentType(contentType)).Wait(); - return null; } + /// + /// 使用path获取完整的访问URL + /// + /// + /// + /// public string FullUrl(string path) { + if(path.StartsWith("http://") || path.StartsWith("https://")) return path; + if (!(path.StartsWith('/') || path.StartsWith("~/"))) throw new Exception("path must start with / or ~/"); var httpRequest = HttpContextAccessor.HttpContext?.Request; var url = $"{httpRequest?.Scheme}://{httpRequest?.Host}"; if (string.IsNullOrEmpty(path)) @@ -99,4 +124,21 @@ public class SimApiStorage return path.StartsWith('~') ? string.Concat(url, path.AsSpan(1, path.Length - 1)) : $"{ServeUrl}{path}"; } -} \ No newline at end of file + + /// + /// 从URL中获取相对路径 (如果url不是当前服务器的url,则原样返回) + /// + /// + /// + public string? GetPath(string? url) + { + return url?.Replace(Endpoint, string.Empty); + } + + private void CheckPath(string path) + { + if (!path.StartsWith('/')) throw new Exception("path must start with /"); + } +} + +public record GetUploadUrlResponse(string UploadUrl, string DownloadUrl, string Path); \ No newline at end of file