mirror of
https://git.v0l.io/Kieran/void.cat.git
synced 2025-11-15 13:47:20 +01:00
Redirect from file store for direct serve
This commit is contained in:
@@ -75,6 +75,15 @@ public class DownloadController : Controller
|
|||||||
Response.ContentLength = range.Size;
|
Response.ContentLength = range.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var preResult = await _storage.StartEgress(egressReq);
|
||||||
|
if (preResult.Redirect != null)
|
||||||
|
{
|
||||||
|
Response.StatusCode = (int)HttpStatusCode.Redirect;
|
||||||
|
Response.Headers.Location = preResult.Redirect.ToString();
|
||||||
|
Response.ContentLength = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var cts = HttpContext.RequestAborted;
|
var cts = HttpContext.RequestAborted;
|
||||||
await Response.StartAsync(cts);
|
await Response.StartAsync(cts);
|
||||||
await _storage.Egress(egressReq, Response.Body, cts);
|
await _storage.Egress(egressReq, Response.Body, cts);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using VoidCat.Services.Abstractions;
|
|
||||||
|
|
||||||
namespace VoidCat.Model;
|
namespace VoidCat.Model;
|
||||||
|
|
||||||
public sealed record EgressRequest(Guid Id, IEnumerable<RangeRequest> Ranges)
|
public sealed record EgressRequest(Guid Id, IEnumerable<RangeRequest> Ranges);
|
||||||
{
|
|
||||||
}
|
public sealed record EgressResult(Uri? Redirect = null);
|
||||||
@@ -29,6 +29,13 @@ public interface IFileStore
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ValueTask Egress(EgressRequest request, Stream outStream, CancellationToken cts);
|
ValueTask Egress(EgressRequest request, Stream outStream, CancellationToken cts);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pre-Egress checks
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
ValueTask<EgressResult> StartEgress(EgressRequest request);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes file data only, metadata must be deleted with <see cref="IFileInfoManager.Delete"/>
|
/// Deletes file data only, metadata must be deleted with <see cref="IFileInfoManager.Delete"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ public class FileStoreFactory : IFileStore
|
|||||||
await store.Egress(request, outStream, cts);
|
await store.Egress(request, outStream, cts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async ValueTask<EgressResult> StartEgress(EgressRequest request)
|
||||||
|
{
|
||||||
|
var store = await GetStore(request.Id);
|
||||||
|
return await store.StartEgress(request);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async ValueTask DeleteFile(Guid id)
|
public async ValueTask DeleteFile(Guid id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
|
|||||||
await EgressFromStream(fs, request, outStream, cts);
|
await EgressFromStream(fs, request, outStream, cts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ValueTask<EgressResult> StartEgress(EgressRequest request)
|
||||||
|
{
|
||||||
|
return ValueTask.FromResult(new EgressResult());
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Key => "local-disk";
|
public string Key => "local-disk";
|
||||||
|
|
||||||
|
|||||||
@@ -143,15 +143,6 @@ public class S3FileMetadataStore : IFileMetadataStore
|
|||||||
if (ret != default)
|
if (ret != default)
|
||||||
{
|
{
|
||||||
ret.Id = id;
|
ret.Id = id;
|
||||||
if (_config.Direct)
|
|
||||||
{
|
|
||||||
var ub = new UriBuilder(_config.ServiceUrl!)
|
|
||||||
{
|
|
||||||
Path = $"/{_config.BucketName}/{id}"
|
|
||||||
};
|
|
||||||
|
|
||||||
ret.Url = ub.Uri;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -61,6 +61,19 @@ public class S3FileStore : StreamFileStore, IFileStore
|
|||||||
await EgressFull(request.Id, stream, outStream, cts);
|
await EgressFull(request.Id, stream, outStream, cts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ValueTask<EgressResult> StartEgress(EgressRequest request)
|
||||||
|
{
|
||||||
|
if (!_config.Direct) return ValueTask.FromResult(new EgressResult());
|
||||||
|
|
||||||
|
var ub = new UriBuilder(_config.ServiceUrl!)
|
||||||
|
{
|
||||||
|
Path = $"/{_config.BucketName}/{request.Id}"
|
||||||
|
};
|
||||||
|
|
||||||
|
return ValueTask.FromResult(new EgressResult(ub.Uri));
|
||||||
|
}
|
||||||
|
|
||||||
public async ValueTask<PagedResult<PublicVoidFile>> ListFiles(PagedRequest request)
|
public async ValueTask<PagedResult<PublicVoidFile>> ListFiles(PagedRequest request)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ export default function ApiKeyList() {
|
|||||||
let rsp = await Api.createApiKey({
|
let rsp = await Api.createApiKey({
|
||||||
expiry: new Date(new Date().getTime() + DefaultExpiry)
|
expiry: new Date(new Date().getTime() + DefaultExpiry)
|
||||||
});
|
});
|
||||||
setNewApiKey(await rsp.json());
|
if (rsp.ok) {
|
||||||
|
setNewApiKey(await rsp.json());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -59,7 +61,7 @@ export default function ApiKeyList() {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{newApiKey ?
|
{newApiKey ?
|
||||||
<VoidModal title="New Api Key" style={{ maxWidth: "50vw"}}>
|
<VoidModal title="New Api Key" style={{maxWidth: "50vw"}}>
|
||||||
Please save this now as it will not be shown again:
|
Please save this now as it will not be shown again:
|
||||||
<pre className="copy">{newApiKey.token}</pre>
|
<pre className="copy">{newApiKey.token}</pre>
|
||||||
<VoidButton onClick={(e) => setNewApiKey(undefined)}>Close</VoidButton>
|
<VoidButton onClick={(e) => setNewApiKey(undefined)}>Close</VoidButton>
|
||||||
|
|||||||
Reference in New Issue
Block a user