mirror of
https://git.v0l.io/Kieran/void.cat.git
synced 2025-04-11 02:19:03 +02:00
Serve files directly from cloud storage
This commit is contained in:
parent
0635aedc31
commit
ac47edc52d
@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using VoidCat.Model;
|
||||
using VoidCat.Model.Paywall;
|
||||
using VoidCat.Services.Abstractions;
|
||||
using VoidCat.Services.Files;
|
||||
|
||||
namespace VoidCat.Controllers;
|
||||
|
||||
@ -41,7 +40,7 @@ public class DownloadController : Controller
|
||||
var voidFile = await SetupDownload(gid);
|
||||
if (voidFile == default) return;
|
||||
|
||||
var egressReq = new EgressRequest(gid, GetRanges(Request, (long) voidFile!.Metadata!.Size));
|
||||
var egressReq = new EgressRequest(gid, GetRanges(Request, (long)voidFile!.Metadata!.Size));
|
||||
if (egressReq.Ranges.Count() > 1)
|
||||
{
|
||||
_logger.LogWarning("Multi-range request not supported!");
|
||||
@ -53,10 +52,10 @@ public class DownloadController : Controller
|
||||
}
|
||||
else if (egressReq.Ranges.Count() == 1)
|
||||
{
|
||||
Response.StatusCode = (int) HttpStatusCode.PartialContent;
|
||||
Response.StatusCode = (int)HttpStatusCode.PartialContent;
|
||||
if (egressReq.Ranges.Sum(a => a.Size) == 0)
|
||||
{
|
||||
Response.StatusCode = (int) HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
Response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -92,7 +91,7 @@ public class DownloadController : Controller
|
||||
var orderId = Request.Headers.GetHeader("V-OrderId") ?? Request.Query["orderId"];
|
||||
if (!await IsOrderPaid(orderId))
|
||||
{
|
||||
Response.StatusCode = (int) HttpStatusCode.PaymentRequired;
|
||||
Response.StatusCode = (int)HttpStatusCode.PaymentRequired;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@ -133,4 +132,4 @@ public class DownloadController : Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace VoidCat.Model
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Base58GuidConverter))]
|
||||
public Guid Id { get; init; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Metadta related to the file
|
||||
/// </summary>
|
||||
|
@ -53,6 +53,11 @@ public record VoidFileMeta : IVoidFileMeta
|
||||
/// </summary>
|
||||
public string? Digest { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Url to download the file
|
||||
/// </summary>
|
||||
public Uri? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User who uploaded the file
|
||||
/// </summary>
|
||||
|
@ -34,6 +34,7 @@ namespace VoidCat.Model
|
||||
|
||||
public sealed record CloudStorageSettings
|
||||
{
|
||||
public bool ServeFromCloud { get; init; }
|
||||
public S3BlobConfig? S3 { get; set; }
|
||||
}
|
||||
|
||||
|
@ -5,20 +5,21 @@ using VoidCat.Services.Abstractions;
|
||||
|
||||
namespace VoidCat.Services.Files;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class S3FileMetadataStore : IFileMetadataStore
|
||||
{
|
||||
private readonly ILogger<S3FileMetadataStore> _logger;
|
||||
private readonly AmazonS3Client _client;
|
||||
private readonly S3BlobConfig _config;
|
||||
|
||||
private readonly bool _includeUrl;
|
||||
|
||||
public S3FileMetadataStore(VoidSettings settings, ILogger<S3FileMetadataStore> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_includeUrl = settings.CloudStorage?.ServeFromCloud ?? false;
|
||||
_config = settings.CloudStorage!.S3!;
|
||||
_client = _config.CreateClient();
|
||||
}
|
||||
|
||||
|
||||
public async ValueTask<TMeta?> Get<TMeta>(Guid id) where TMeta : VoidFileMeta
|
||||
{
|
||||
try
|
||||
@ -27,7 +28,18 @@ public class S3FileMetadataStore : IFileMetadataStore
|
||||
|
||||
using var sr = new StreamReader(obj.ResponseStream);
|
||||
var json = await sr.ReadToEndAsync();
|
||||
return JsonConvert.DeserializeObject<TMeta>(json);
|
||||
var ret = JsonConvert.DeserializeObject<TMeta>(json);
|
||||
if (ret != default && _includeUrl)
|
||||
{
|
||||
var ub = new UriBuilder(_config.ServiceUrl!)
|
||||
{
|
||||
Path = $"/{_config.BucketName}/{id}"
|
||||
};
|
||||
|
||||
ret.Url = ub.Uri;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch (AmazonS3Exception aex)
|
||||
{
|
||||
@ -54,4 +66,4 @@ public class S3FileMetadataStore : IFileMetadataStore
|
||||
}
|
||||
|
||||
private static string ToKey(Guid id) => $"{id}-metadata";
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ using VoidCat.Services.Abstractions;
|
||||
|
||||
namespace VoidCat.Services.Files;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class S3FileStore : StreamFileStore, IFileStore
|
||||
{
|
||||
private readonly IFileInfoManager _fileInfo;
|
||||
|
@ -114,13 +114,14 @@ export function FilePreview() {
|
||||
|
||||
useEffect(() => {
|
||||
if (info) {
|
||||
let fileLink = info.metadata?.url ?? `${ApiHost}/d/${info.id}`;
|
||||
let order = window.localStorage.getItem(`paywall-${info.id}`);
|
||||
if (order) {
|
||||
let orderObj = JSON.parse(order);
|
||||
setOrder(orderObj);
|
||||
setLink(`${ApiHost}/d/${info.id}?orderId=${orderObj.id}`);
|
||||
setLink(`${fileLink}?orderId=${orderObj.id}`);
|
||||
} else {
|
||||
setLink(`${ApiHost}/d/${info.id}`);
|
||||
setLink(fileLink);
|
||||
}
|
||||
}
|
||||
}, [info]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user