If I wanted to interrupt the download without corrupting the .flv file stream, how could I do that? Considering that there might be multiple downloads at the same time, so I don't want to interrupt them all at once.
Here is how I download the file:
app.MapGet("/stream", async context =>
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
context.Response.ContentType = "application/octet-stream";
context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"file.flv\"");
context.Response.Headers.Add("Transfer-Encoding", "chunked");
using var responseStream = await
response.Content.ReadAsStreamAsync();
await responseStream.CopyToAsync(context.Response.Body);
});
app.MapGet("/stop", async context =>
{
await context.Response.WriteAsync("Download stopped.");
// How do I stop?????????
});
I see the option of implementing that through CancellationTokenSource
, you need to keep reference to every download you start, so you can abort it in different request.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpsRedirection();
var cancellationTokens = new Dictionary<string, CancellationTokenSource>();
app.MapGet("/stream", async context =>
{
var id = context.Request.Query["id"];
var cts = new CancellationTokenSource();
cancellationTokens[id] = cts;
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://filesamples.com/samples/video/flv/sample_1280x720_surfing_with_audio.flv");
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
context.Response.ContentType = "application/octet-stream";
context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"file.flv\"");
context.Response.Headers.Add("Transfer-Encoding", "chunked");
using var responseStream = await response.Content.ReadAsStreamAsync(cts.Token);
await responseStream.CopyToAsync(context.Response.Body, cts.Token);
});
app.MapGet("/stop", async context =>
{
var id = context.Request.Query["id"];
cancellationTokens[id].Cancel();
await context.Response.WriteAsync("Download stopped.");
});
app.Run();
Call to stop endpoint produces following stacktrace in console indicating that cancellation is done inside of CopyToAsync
method. I also pass the same token in all methods that accept it