using Femto.Api.Controllers.Media.Dto; using Femto.Modules.Media.Application; using Femto.Modules.Media.Contracts.LoadFile; using Femto.Modules.Media.Contracts.SaveFile; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Femto.Api.Controllers.Media; [ApiController] [Route("media")] public class MediaController(IMediaModule mediaModule) : ControllerBase { [HttpPost] [Authorize] public async Task> UploadMedia( IFormFile file, CancellationToken cancellationToken ) { await using var data = file.OpenReadStream(); var id = await mediaModule.PostCommand( new SaveFileCommand(data, file.ContentType, file.Length), cancellationToken ); var fileGetUrl = $"{this.HttpContext.Request.Scheme}://{this.HttpContext.Request.Host}/media/{id}"; return new UploadMediaResponse(id, fileGetUrl); } [HttpGet("{id}")] public async Task GetMedia(Guid id, CancellationToken cancellationToken) { var res = await mediaModule.PostQuery(new LoadFileQuery(id), cancellationToken); // Set cache headers HttpContext.Response.Headers.CacheControl = "public,max-age=31536000"; // Cache for 1 year HttpContext.Response.Headers.Expires = DateTime.UtcNow.AddYears(1).ToString("R"); // If you want to support cache validation HttpContext.Response.Headers.ETag = $"\"{id}\""; // Using the file ID as ETag HttpContext.Response.ContentType = res.Type; HttpContext.Response.ContentLength = res.Size; await res.Data.CopyToAsync(HttpContext.Response.Body, cancellationToken); }}