From afa862a67b67602b549a621c659a59c0b6c8dae8 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Fri, 26 Jun 2026 15:16:29 -0400 Subject: [PATCH] fix: move LogInformation inside disposal guard in both GetTrack streaming arms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents an OS handle leak if the logger throws after the FileStream is opened but before File() takes ownership. Also corrects a stale "finally block" comment in the lossless arm — it has always been a catch. --- DeepDrftAPI/Controllers/TrackController.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/DeepDrftAPI/Controllers/TrackController.cs b/DeepDrftAPI/Controllers/TrackController.cs index 6932d93..361d0f4 100644 --- a/DeepDrftAPI/Controllers/TrackController.cs +++ b/DeepDrftAPI/Controllers/TrackController.cs @@ -741,7 +741,7 @@ public class TrackController : ControllerBase } // Resolve MIME and log before handing the stream to File(). - // If anything here throws, the finally block disposes the wrapper + // If anything here throws, the catch block disposes the wrapper // (and its inner FileStream) so neither leaks. On the success path // File() takes ownership of the inner stream; ASP.NET Core disposes // it after the response body is sent. The wrapper is a thin struct @@ -755,16 +755,15 @@ public class TrackController : ControllerBase streamMimeType = MimeTypeExtensions.GetMimeType(mediaStream.Extension); streamLength = mediaStream.Stream.Length; innerStream = mediaStream.Stream; + _logger.LogInformation( + "Streaming track from disk: {TrackId}, Size: {Size} bytes", + trackId, streamLength); } catch { await mediaStream.DisposeAsync(); throw; } - - _logger.LogInformation( - "Streaming track from disk: {TrackId}, Size: {Size} bytes", - trackId, streamLength); // enableRangeProcessing: true — seek is served by HTTP Range requests. // The FileStream is seekable, so ASP.NET Core honours an incoming // Range header by slicing the file and responding 206 Partial Content. @@ -808,6 +807,9 @@ public class TrackController : ControllerBase // Length from the seekable FileStream — a metadata read, not a body load. streamLength = resolved.Stream.Length; innerStream = resolved.Stream; + _logger.LogInformation( + "Streaming track {TrackId} as {Format} ({Size} bytes, {ContentType})", + trackId, resolved.ResolvedFormat, streamLength, contentType); } catch { @@ -815,10 +817,6 @@ public class TrackController : ControllerBase throw; } - _logger.LogInformation( - "Streaming track {TrackId} as {Format} ({Size} bytes, {ContentType})", - trackId, resolved.ResolvedFormat, streamLength, contentType); - return File(innerStream, contentType, enableRangeProcessing: true); } catch (Exception ex)