Skip to content

Commit 11cbf35

Browse files
committed
Update File Service
1 parent 6a307fc commit 11cbf35

File tree

3 files changed

+41
-15
lines changed

3 files changed

+41
-15
lines changed

FileService/.idea/.idea.FileService/.idea/workspace.xml

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FileService/FileService.Service/Implementation/MinioService.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,29 +149,56 @@ public Task<string> GetPublicFileUrlAsync(string objectName)
149149
if (string.IsNullOrWhiteSpace(objectName))
150150
throw new ArgumentException("Invalid object name", nameof(objectName));
151151

152-
objectName = objectName.TrimStart('/');
153-
var key = Uri.EscapeDataString(objectName);
154-
155-
// Nếu có PublicEndpoint thì dùng nó làm base (có thể gồm scheme + path), KHÔNG thêm :port
152+
// 1) Chuẩn hoá key và chỉ encode từng segment, không encode dấu '/'
153+
var key = string.Join("/",
154+
objectName.Trim().TrimStart('/')
155+
.Split('/', StringSplitOptions.RemoveEmptyEntries)
156+
.Select(s => Uri.EscapeDataString(s))
157+
);
158+
159+
// 2) Nếu có PublicEndpoint (vd: https://codecampus.site/s3) thì dùng làm base
156160
var pub = _config.PublicEndpoint?.Trim().TrimEnd('/');
157161
if (!string.IsNullOrEmpty(pub))
158162
{
159-
// Nếu thiếu scheme thì tự thêm theo cấu hình Secure
160163
if (!pub.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
161164
!pub.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
162165
{
163166
pub = $"{(_config.Secure ? "https" : "http")}://{pub}";
164167
}
165-
var url = $"{pub}/{_config.BucketName}/{key}";
166-
Console.WriteLine($"Generated public URL: {url}");
167-
return Task.FromResult(url);
168+
return Task.FromResult($"{pub}/{_config.BucketName}/{key}");
168169
}
169170

170-
// Fallback: dùng endpoint nội bộ (có :port)
171+
// 3) Fallback: endpoint nội bộ MinIO
171172
var scheme = _config.Secure ? "https" : "http";
172-
var direct = $"{scheme}://{_config.Endpoint}:{_config.Port}/{_config.BucketName}/{key}";
173-
Console.WriteLine($"Generated direct URL: {direct}");
174-
return Task.FromResult(direct);
173+
return Task.FromResult($"{scheme}://{_config.Endpoint}:{_config.Port}/{_config.BucketName}/{key}");
174+
}
175+
176+
// Thêm tiện ích: nhận vào URL hoặc key, trả về object key dùng cho MinIO
177+
public string UrlToObjectKey(string urlOrKey)
178+
{
179+
if (string.IsNullOrWhiteSpace(urlOrKey)) return urlOrKey;
180+
181+
var s = urlOrKey.Trim();
182+
183+
// Nếu đã là key thì trả về key (bỏ dấu '/')
184+
if (!s.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
185+
!s.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
186+
return s.TrimStart('/');
187+
188+
// Cắt bỏ PublicEndpoint (nếu khớp)
189+
var pub = _config.PublicEndpoint?.Trim().TrimEnd('/') ?? "";
190+
if (!string.IsNullOrEmpty(pub) && s.StartsWith(pub, StringComparison.OrdinalIgnoreCase))
191+
s = s.Substring(pub.Length);
192+
193+
s = s.TrimStart('/');
194+
195+
// Cắt bỏ bucket name nếu có
196+
var bucketPrefix = _config.BucketName + "/";
197+
if (s.StartsWith(bucketPrefix, StringComparison.OrdinalIgnoreCase))
198+
s = s.Substring(bucketPrefix.Length);
199+
200+
// Giải mã phần còn lại (đề phòng URL cũ có %2F)
201+
return Uri.UnescapeDataString(s);
175202
}
176203

177204
public async Task<string> GeneratePresignedUrlAsync(string objectName, int expirySeconds)

FileService/FileService.Service/Interfaces/IMinioService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public interface IMinioService
1313
Task<string> GeneratePresignedUrlAsync(string objectName, int expirySeconds);
1414
Task EnsureBucketExistsAsync();
1515
Task RemoveFileAsync(string objectName);
16-
16+
string UrlToObjectKey(string urlOrKey);
1717
}
1818
}

0 commit comments

Comments
 (0)