voidkitty/VoidCat/Controllers/UploadController.cs

119 lines
3.8 KiB
C#
Raw Normal View History

2022-01-25 16:17:48 +00:00
using Microsoft.AspNetCore.Mvc;
2022-01-28 10:32:00 +00:00
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
2022-01-25 23:39:51 +00:00
using Newtonsoft.Json;
2022-01-25 16:17:48 +00:00
using VoidCat.Model;
using VoidCat.Services;
2022-02-16 16:33:00 +00:00
using VoidCat.Services.Abstractions;
2022-01-25 16:17:48 +00:00
namespace VoidCat.Controllers
{
[Route("upload")]
public class UploadController : Controller
{
2022-02-08 18:20:59 +00:00
private readonly IFileStore _storage;
2022-01-25 16:17:48 +00:00
2022-02-08 18:20:59 +00:00
public UploadController(IFileStore storage)
2022-01-25 16:17:48 +00:00
{
2022-01-25 23:39:51 +00:00
_storage = storage;
2022-01-25 16:17:48 +00:00
}
[HttpPost]
2022-01-25 23:39:51 +00:00
[DisableRequestSizeLimit]
2022-01-28 10:32:00 +00:00
[DisableFormValueModelBinding]
2022-02-10 22:22:34 +00:00
public async Task<UploadResult> UploadFile()
2022-01-25 16:17:48 +00:00
{
2022-02-10 22:22:34 +00:00
try
2022-02-03 23:06:39 +00:00
{
2022-02-10 22:22:34 +00:00
var meta = new VoidFileMeta()
{
MimeType = Request.ContentType,
Name = Request.Headers.GetHeader("X-Filename")
};
var digest = Request.Headers.GetHeader("X-Digest");
2022-02-16 16:33:00 +00:00
var vf = await _storage.Ingress(new(Request.Body, meta, digest!), HttpContext.RequestAborted);
2022-02-10 22:22:34 +00:00
return UploadResult.Success(vf);
}
catch (Exception ex)
{
return UploadResult.Error(ex.Message);
}
}
[HttpPost]
[DisableRequestSizeLimit]
[DisableFormValueModelBinding]
[Route("{id}")]
public async Task<UploadResult> UploadFileAppend([FromRoute] string id)
{
try
{
var gid = id.FromBase58Guid();
var fileInfo = await _storage.Get(gid);
2022-02-16 16:33:00 +00:00
if (fileInfo == default) return UploadResult.Error("File not found");
2022-02-10 22:22:34 +00:00
var editSecret = Request.Headers.GetHeader("X-EditSecret");
var digest = Request.Headers.GetHeader("X-Digest");
var vf = await _storage.Ingress(new(Request.Body, fileInfo.Metadata, digest!)
{
EditSecret = editSecret?.FromBase58Guid(),
Id = gid
}, HttpContext.RequestAborted);
return UploadResult.Success(vf);
}
catch (Exception ex)
{
return UploadResult.Error(ex.Message);
}
2022-01-25 16:17:48 +00:00
}
2022-01-25 23:39:51 +00:00
[HttpGet]
[Route("{id}")]
2022-02-16 16:33:00 +00:00
public ValueTask<VoidFile?> GetInfo([FromRoute] string id)
2022-01-25 16:17:48 +00:00
{
2022-01-25 23:39:51 +00:00
return _storage.Get(id.FromBase58Guid());
2022-01-25 16:17:48 +00:00
}
2022-02-10 22:22:34 +00:00
2022-01-25 23:39:51 +00:00
[HttpPatch]
[Route("{id}")]
2022-02-16 16:33:00 +00:00
public ValueTask UpdateFileInfo([FromRoute] string id, [FromBody] UpdateFileInfoRequest request)
2022-01-25 23:39:51 +00:00
{
return _storage.UpdateInfo(new VoidFile()
{
Id = id.FromBase58Guid(),
Metadata = request.Metadata
}, request.EditSecret);
}
2022-02-16 16:33:00 +00:00
public record UpdateFileInfoRequest([JsonConverter(typeof(Base58GuidConverter))] Guid EditSecret,
VoidFileMeta Metadata);
2022-01-25 16:17:48 +00:00
}
2022-01-28 10:32:00 +00:00
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
2022-02-10 22:22:34 +00:00
public record UploadResult(bool Ok, InternalVoidFile? File, string? ErrorMessage)
{
public static UploadResult Success(InternalVoidFile vf)
=> new(true, vf, null);
public static UploadResult Error(string message)
=> new(false, null, message);
}
2022-02-16 16:33:00 +00:00
}