Files
TinfoilVibeServer/TinfoilVibeServer/Controllers/CancelableFileResult.cs
T
ecenshu a1ea34bc01
Build & Push Docker image / build-and-push (push) Has been cancelled
ci / build_linux (push) Has been cancelled
feature/ci (#1)
Consolidate data and config into separate folders that will be expected to be mapped in the container

Reviewed-on: #1
Co-authored-by: Huy Nguyen <ecenshu@gmail.com>
Co-committed-by: Huy Nguyen <ecenshu@gmail.com>
2025-11-13 09:11:21 +00:00

53 lines
1.7 KiB
C#
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.AspNetCore.Mvc;
namespace TinfoilVibeServer.Controllers;
public class CancelableFileResult : FileResult
{
private readonly Stream _fileStream;
public CancelableFileResult(string contentType, Stream fileStream)
: base(contentType)
{
_fileStream = fileStream ?? throw new ArgumentNullException(nameof(fileStream));
}
/// <summary>
/// Allows you to set a suggested download name.
/// It will be sent in a “ContentDisposition” header.
/// </summary>
public new string? FileDownloadName { get; set; }
public override async Task ExecuteResultAsync(ActionContext context)
{
var response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(FileDownloadName))
{
// Typical “attachment” disposition most browsers honour it.
response.Headers.Append("Content-Disposition",
$"attachment; filename=\"{FileDownloadName}\"");
}
// The requestaborted token tells the stream copy to stop ASAP
var cancellationToken = context.HttpContext.RequestAborted;
try
{
// Copy the file to the response body in 8KiB chunks
await _fileStream.CopyToAsync(
response.Body,
bufferSize: 81920, // 80KiB default for Stream.CopyToAsync
cancellationToken);
}
catch (OperationCanceledException)
{
// The client disconnected nothing to do.
// Swallowing keeps the API from returning a 500 error.
}
finally
{
await _fileStream.DisposeAsync();
}
}
}