using System.Net.Mime;
using File.Application.Features.Files.Queries;
using MediatR;
namespace BuildFlow.Host.Endpoints.File.Files;
///
/// 文件预览端点。GET /api/files/preview,流式返回文件内容供内联展示(非下载)。
/// 后端从 S3 拉流透传,前端永远不接触 S3 URL 和凭据。
/// 鉴权:[Authorize] + JWT 中间件从 token query 参数读 JWT(img src / window.open 无法带 header)。
/// 该路径在 ApiResponseMiddlewareOptions.PassthroughPrefixes 注册,绕过响应包裹中间件的缓冲。
///
[Authorize]
public class GetFilePreviewEndpoint(IMediator mediator) : Endpoint
{
public override void Configure()
{
Get("/files/preview");
Permissions("file:read");
}
public override async Task HandleAsync(GetFilePreviewRequest req, CancellationToken ct)
{
// 复用下载查询(返回 Stream + ContentType + FileName)
var result = await mediator.Send(new DownloadFileQuery(req.ObjectKey), ct);
// inline = 浏览器内联展示(图片/PDF 直接渲染),而非触发下载
HttpContext.Response.ContentType = result.ContentType;
var disposition = new ContentDisposition { FileName = result.FileName, Inline = true };
HttpContext.Response.Headers.ContentDisposition = disposition.ToString();
// 流式透传:S3 流 → HTTP 响应体
try
{
await result.Stream.CopyToAsync(HttpContext.Response.Body, ct);
await HttpContext.Response.Body.FlushAsync(ct);
}
finally
{
await result.Stream.DisposeAsync();
}
}
}