diff --git a/ProjectLighthouse/Controllers/ResourcesController.cs b/ProjectLighthouse/Controllers/ResourcesController.cs index d0398660..60ff7ae0 100644 --- a/ProjectLighthouse/Controllers/ResourcesController.cs +++ b/ProjectLighthouse/Controllers/ResourcesController.cs @@ -7,6 +7,7 @@ using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Serialization; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Files; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc; using IOFile = System.IO.File; @@ -50,14 +51,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers { // TODO: check if this is a valid hash [HttpPost("upload/{hash}")] + [AllowSynchronousIo] public async Task UploadResource(string hash) { + string assetsDirectory = FileHelper.ResourcePath; string path = FileHelper.GetResourcePath(hash); FileHelper.EnsureDirectoryCreated(assetsDirectory); if(FileHelper.ResourceExists(hash)) this.Ok(); // no reason to fail if it's already uploaded - LbpFile file = new(Encoding.ASCII.GetBytes(await new StreamReader(this.Request.Body).ReadToEndAsync())); + LbpFile file = new(this.Request.Body); if(!FileHelper.IsFileSafe(file)) return this.UnprocessableEntity(); diff --git a/ProjectLighthouse/Helpers/AllowSynchronousIOAttribute.cs b/ProjectLighthouse/Helpers/AllowSynchronousIOAttribute.cs new file mode 100644 index 00000000..8cf82612 --- /dev/null +++ b/ProjectLighthouse/Helpers/AllowSynchronousIOAttribute.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc.Filters; + +namespace LBPUnion.ProjectLighthouse.Helpers { + // Yoinked from https://stackoverflow.com/a/68530667 + // Thanks to T-moty! + /// + /// Allows synchronous stream operations for this request. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class AllowSynchronousIoAttribute : ActionFilterAttribute { + public override void OnResultExecuting(ResultExecutingContext context) { + IHttpBodyControlFeature syncIoFeature = context.HttpContext.Features.Get(); + if(syncIoFeature != null) syncIoFeature.AllowSynchronousIO = true; + } + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Types/Files/LbpFile.cs b/ProjectLighthouse/Types/Files/LbpFile.cs index 7f0a61b9..b8f7645c 100644 --- a/ProjectLighthouse/Types/Files/LbpFile.cs +++ b/ProjectLighthouse/Types/Files/LbpFile.cs @@ -1,10 +1,19 @@ +using System.IO; using LBPUnion.ProjectLighthouse.Helpers; namespace LBPUnion.ProjectLighthouse.Types.Files { public class LbpFile { public LbpFile(byte[] data) { this.Data = data; - this.FileType = FileHelper.DetermineFileType(data); + this.FileType = FileHelper.DetermineFileType(this.Data); + } + + public LbpFile(Stream stream) { + using MemoryStream ms = new(); + stream.CopyToAsync(ms); + + this.Data = ms.ToArray(); + this.FileType = FileHelper.DetermineFileType(this.Data); } ///