Backport pull request #13033 from jellyfin/release-10.10.z

Respect cancellation token/HTTP request aborts correctly in `SymlinkFollowingPhysicalFileResultExecutor`

Original-merge: 293e0f5fafe6ba0c7cfc269b889cb0d4d1ada59a

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
This commit is contained in:
goknsh 2024-11-19 15:43:32 -05:00 committed by Joshua M. Boniface
parent 7f81bbd42f
commit 924c80a209

View File

@ -101,7 +101,7 @@ namespace Jellyfin.Server.Infrastructure
count: null); count: null);
} }
private async Task SendFileAsync(string filePath, HttpResponse response, long offset, long? count) private async Task SendFileAsync(string filePath, HttpResponse response, long offset, long? count, CancellationToken cancellationToken = default)
{ {
var fileInfo = GetFileInfo(filePath); var fileInfo = GetFileInfo(filePath);
if (offset < 0 || offset > fileInfo.Length) if (offset < 0 || offset > fileInfo.Length)
@ -118,6 +118,9 @@ namespace Jellyfin.Server.Infrastructure
// Copied from SendFileFallback.SendFileAsync // Copied from SendFileFallback.SendFileAsync
const int BufferSize = 1024 * 16; const int BufferSize = 1024 * 16;
var useRequestAborted = !cancellationToken.CanBeCanceled;
var localCancel = useRequestAborted ? response.HttpContext.RequestAborted : cancellationToken;
var fileStream = new FileStream( var fileStream = new FileStream(
filePath, filePath,
FileMode.Open, FileMode.Open,
@ -127,10 +130,17 @@ namespace Jellyfin.Server.Infrastructure
options: FileOptions.Asynchronous | FileOptions.SequentialScan); options: FileOptions.Asynchronous | FileOptions.SequentialScan);
await using (fileStream.ConfigureAwait(false)) await using (fileStream.ConfigureAwait(false))
{ {
fileStream.Seek(offset, SeekOrigin.Begin); try
await StreamCopyOperation {
.CopyToAsync(fileStream, response.Body, count, BufferSize, CancellationToken.None) localCancel.ThrowIfCancellationRequested();
.ConfigureAwait(true); fileStream.Seek(offset, SeekOrigin.Begin);
await StreamCopyOperation
.CopyToAsync(fileStream, response.Body, count, BufferSize, localCancel)
.ConfigureAwait(true);
}
catch (OperationCanceledException) when (useRequestAborted)
{
}
} }
} }