浏览代码

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>
goknsh 6 月之前
父节点
当前提交
924c80a209
共有 1 个文件被更改,包括 15 次插入5 次删除
  1. 15 5
      Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs

+ 15 - 5
Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs

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