using Microsoft.AspNetCore.Mvc; using StorageServer.IO; using StorageServer.Models; using StorageServer.Models.Request; using StorageServer.Models.Response; namespace StorageServer.Controllers; public class FileController : Controller { private readonly DatabaseFactory database; private readonly StorageProvider provider; public FileController(DatabaseFactory database, StorageProvider provider) { this.database = database; this.provider = provider; } [HttpPost] [DisableRequestSizeLimit] public async Task Create(FileCreateModel model) { if (!ModelState.IsValid) { return BadRequest(); } if (model.File is null || string.IsNullOrWhiteSpace(model.File.ContentType)) { return BadRequest(); } try { using (TempFile tempFile = new TempFile()) { string fileName = string.IsNullOrWhiteSpace(model.FileName) ? model.File.FileName : model.FileName; FileModel fileModel = new FileModel() { FileName = fileName, MimeType = model.File.ContentType, CreatedAt = DateTime.Now, }; using (FileStream fs = tempFile.Open()) { await model.File.CopyToAsync(fs); fs.Seek(0, SeekOrigin.Begin); string hash = await this.provider.ComputeStreamHash(fs); fileModel.HashValue = hash; } long fileId = this.database.Create(fileModel); fileModel.FileID = fileId; using (FileStream fs = tempFile.Open()) { await this.provider.SaveFile(fileModel, fs); } return Json(new FileCreateResponseModel() { FileId = fileId, FileName = fileName, MimeType = fileModel.MimeType, }); } } catch (Exception) { return Problem(); } } [HttpGet] public IActionResult ReadInfo(FileReadModel model) { if (!ModelState.IsValid) { return BadRequest(); } try { FileModel fileModel = this.database.Read(model.FileID); if (fileModel is null) { return NotFound(); } return Json(fileModel); } catch (Exception) { return Problem(); } } [HttpGet] public IActionResult Read(FileReadModel model) { if (!ModelState.IsValid) { return BadRequest(); } try { FileModel fileModel = this.database.Read(model.FileID); if (fileModel is null) { return NotFound(); } Stream stream = this.provider.GetFile(fileModel); this.HttpContext.Response.RegisterForDispose(stream); return File(stream, fileModel.MimeType, fileModel.FileName, true); } catch (FileNotFoundException) { return NotFound(); } catch (Exception) { return Problem(); } } [HttpPost] public IActionResult Delete(FileDeleteModel model) { if (!ModelState.IsValid) { return BadRequest(); } try { FileModel fileModel = this.database.Read(model.FileID); if (fileModel is null) { return NotFound(); } this.provider.DeleteFile(fileModel); return Ok(); } catch (FileNotFoundException) { return NotFound(); } catch (Exception) { return Problem(); } } }