All checks were successful
Build & Deploy PLDpro.Web Test to 192.168.1.100 / build-and-deploy (push) Successful in 1m13s
78 lines
2.5 KiB
C#
78 lines
2.5 KiB
C#
|
|
using Amazon.S3;
|
|
using Amazon.S3.Model;
|
|
using Pldpro.Web.Services.Models;
|
|
|
|
namespace Pldpro.Web.Services;
|
|
|
|
public sealed class S3StorageService(IAmazonS3 s3) : IStorageService
|
|
{
|
|
private readonly IAmazonS3 _s3 = s3;
|
|
|
|
public async Task<IEnumerable<BucketItem>> ListBucketsAsync(CancellationToken ct = default)
|
|
{
|
|
var resp = await _s3.ListBucketsAsync(ct);
|
|
return resp.Buckets.Select(b => new BucketItem(b.BucketName, b.CreationDate));
|
|
}
|
|
|
|
public async Task CreateBucketAsync(string bucketName, CancellationToken ct = default)
|
|
{
|
|
// Für S3-kompatible Endpoints reicht häufig nur der Name
|
|
var req = new PutBucketRequest { BucketName = bucketName };
|
|
await _s3.PutBucketAsync(req, ct);
|
|
}
|
|
|
|
public async Task<IEnumerable<ObjectItem>> ListObjectsAsync(string bucket, CancellationToken ct = default)
|
|
{
|
|
var items = new List<ObjectItem>();
|
|
string? token = null;
|
|
do
|
|
{
|
|
var resp = await _s3.ListObjectsV2Async(new ListObjectsV2Request
|
|
{
|
|
BucketName = bucket,
|
|
ContinuationToken = token
|
|
}, ct);
|
|
if (resp.S3Objects != null)
|
|
{
|
|
items.AddRange(resp.S3Objects.Select(o => new ObjectItem(o.Key, o.Size, o.LastModified)));
|
|
token = (bool)resp.IsTruncated ? resp.NextContinuationToken : null;
|
|
}
|
|
} while (token is not null);
|
|
|
|
return items;
|
|
}
|
|
|
|
public async Task UploadObjectAsync(string bucket, string key, Stream content, string contentType, CancellationToken ct = default)
|
|
{
|
|
var req = new PutObjectRequest
|
|
{
|
|
BucketName = bucket,
|
|
Key = key,
|
|
InputStream = content,
|
|
ContentType = contentType
|
|
};
|
|
await _s3.PutObjectAsync(req, ct);
|
|
}
|
|
|
|
|
|
public async Task<(Stream Stream, string ContentType, long? ContentLength)> GetObjectAsync(
|
|
string bucket, string key, CancellationToken ct = default)
|
|
{
|
|
var resp = await _s3.GetObjectAsync(new GetObjectRequest
|
|
{
|
|
BucketName = bucket,
|
|
Key = key
|
|
}, ct);
|
|
|
|
// ResponseStream NICHT kopieren, sondern direkt zurückgeben (Server streamt es weiter)
|
|
var contentType = string.IsNullOrWhiteSpace(resp.Headers.ContentType)
|
|
? "application/octet-stream"
|
|
: resp.Headers.ContentType;
|
|
|
|
long? len = resp.Headers.ContentLength >= 0 ? resp.Headers.ContentLength : null;
|
|
return (resp.ResponseStream, contentType, len);
|
|
}
|
|
|
|
}
|