Skip to content
This repository has been archived by the owner on Nov 22, 2018. It is now read-only.

Commit

Permalink
#150 Handle OperationCancelledExceptions to prevent log noise
Browse files Browse the repository at this point in the history
  • Loading branch information
Tratcher committed Aug 26, 2016
1 parent 33dbd6d commit 7ef8953
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 28 deletions.
10 changes: 10 additions & 0 deletions src/Microsoft.AspNetCore.StaticFiles/LoggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ internal static class LoggerExtensions
private static Action<ILogger, StringValues, string, Exception> _logCopyingFileRange;
private static Action<ILogger, long, string, string, Exception> _logCopyingBytesToResponse;
private static Action<ILogger, string, Exception> _logMultipleFileRanges;
private static Action<ILogger, Exception> _logWriteCancelled;

static LoggerExtensions()
{
Expand Down Expand Up @@ -80,6 +81,10 @@ static LoggerExtensions()
logLevel: LogLevel.Warning,
eventId: 13,
formatString: "Multiple ranges are not allowed: '{Ranges}'");
_logWriteCancelled = LoggerMessage.Define(
logLevel: LogLevel.Debug,
eventId: 14,
formatString: "The file transmission was cancelled");
}

public static void LogRequestMethodNotSupported(this ILogger logger, string method)
Expand Down Expand Up @@ -155,5 +160,10 @@ public static void LogMultipleFileRanges(this ILogger logger, string range)
{
_logMultipleFileRanges(logger, range, null);
}

public static void LogWriteCancelled(this ILogger logger, Exception ex)
{
_logWriteCancelled(logger, ex);
}
}
}
76 changes: 48 additions & 28 deletions src/Microsoft.AspNetCore.StaticFiles/StaticFileContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,23 +346,33 @@ public async Task SendAsync()
{
ApplyResponseHeaders(Constants.Status200Ok);

string physicalPath = _fileInfo.PhysicalPath;
var sendFile = _context.Features.Get<IHttpSendFileFeature>();
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
{
await sendFile.SendFileAsync(physicalPath, 0, _length, _context.RequestAborted);
return;
}

Stream readStream = _fileInfo.CreateReadStream();
try
{
// Larger StreamCopyBufferSize is required because in case of FileStream readStream isn't going to be buffering
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, _length, StreamCopyBufferSize, _context.RequestAborted);
string physicalPath = _fileInfo.PhysicalPath;
var sendFile = _context.Features.Get<IHttpSendFileFeature>();
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
{
await sendFile.SendFileAsync(physicalPath, 0, _length, _context.RequestAborted);
return;
}

Stream readStream = _fileInfo.CreateReadStream();
try
{
// Larger StreamCopyBufferSize is required because in case of FileStream readStream isn't going to be buffering
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, _length, StreamCopyBufferSize, _context.RequestAborted);
}
finally
{
readStream.Dispose();
}
}
finally
catch (OperationCanceledException ex)
{
readStream.Dispose();
_logger.LogWriteCancelled(ex);
// Don't throw this exception, it's most likely caused by the client disconnecting.
// However, if it was cancelled for any other reason we need to prevent empty responses.
_context.Abort();
}
}

Expand Down Expand Up @@ -395,25 +405,35 @@ internal async Task SendRangeAsync()
_response.ContentLength = length;
ApplyResponseHeaders(Constants.Status206PartialContent);

string physicalPath = _fileInfo.PhysicalPath;
var sendFile = _context.Features.Get<IHttpSendFileFeature>();
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
{
_logger.LogSendingFileRange(_response.Headers[HeaderNames.ContentRange], physicalPath);
await sendFile.SendFileAsync(physicalPath, start, length, _context.RequestAborted);
return;
}

Stream readStream = _fileInfo.CreateReadStream();
try
{
readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
_logger.LogCopyingFileRange(_response.Headers[HeaderNames.ContentRange], SubPath);
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);
string physicalPath = _fileInfo.PhysicalPath;
var sendFile = _context.Features.Get<IHttpSendFileFeature>();
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
{
_logger.LogSendingFileRange(_response.Headers[HeaderNames.ContentRange], physicalPath);
await sendFile.SendFileAsync(physicalPath, start, length, _context.RequestAborted);
return;
}

Stream readStream = _fileInfo.CreateReadStream();
try
{
readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
_logger.LogCopyingFileRange(_response.Headers[HeaderNames.ContentRange], SubPath);
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);
}
finally
{
readStream.Dispose();
}
}
finally
catch (OperationCanceledException ex)
{
readStream.Dispose();
_logger.LogWriteCancelled(ex);
// Don't throw this exception, it's most likely caused by the client disconnecting.
// However, if it was cancelled for any other reason we need to prevent empty responses.
_context.Abort();
}
}

Expand Down

0 comments on commit 7ef8953

Please sign in to comment.