diff --git a/src/Microsoft.AspNetCore.Http.Extensions/SendFileResponseExtensions.cs b/src/Microsoft.AspNetCore.Http.Extensions/SendFileResponseExtensions.cs
index cbddfe97c9..74c0422ef4 100644
--- a/src/Microsoft.AspNetCore.Http.Extensions/SendFileResponseExtensions.cs
+++ b/src/Microsoft.AspNetCore.Http.Extensions/SendFileResponseExtensions.cs
@@ -22,8 +22,7 @@ namespace Microsoft.AspNetCore.Http
///
/// The file.
/// The .
- public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
- CancellationToken cancellationToken = default(CancellationToken))
+ public static Task SendFileAsync(this HttpResponse response, IFileInfo file, CancellationToken cancellationToken = default)
{
if (response == null)
{
@@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.Http
throw new ArgumentNullException(nameof(file));
}
- return response.SendFileAsync(file, 0, null, cancellationToken);
+ return SendFileAsyncCore(response, file, 0, null, cancellationToken);
}
///
@@ -46,8 +45,7 @@ namespace Microsoft.AspNetCore.Http
/// The number of bytes to send, or null to send the remainder of the file.
///
///
- public static async Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count,
- CancellationToken cancellationToken = default(CancellationToken))
+ public static Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count, CancellationToken cancellationToken = default)
{
if (response == null)
{
@@ -57,10 +55,62 @@ namespace Microsoft.AspNetCore.Http
{
throw new ArgumentNullException(nameof(file));
}
- CheckRange(offset, count, file.Length);
+ return SendFileAsyncCore(response, file, offset, count, cancellationToken);
+ }
+
+ ///
+ /// Sends the given file using the SendFile extension.
+ ///
+ ///
+ /// The full path to the file.
+ /// The .
+ ///
+ public static Task SendFileAsync(this HttpResponse response, string fileName, CancellationToken cancellationToken = default)
+ {
+ if (response == null)
+ {
+ throw new ArgumentNullException(nameof(response));
+ }
+
+ if (fileName == null)
+ {
+ throw new ArgumentNullException(nameof(fileName));
+ }
+
+ return SendFileAsyncCore(response, fileName, 0, null, cancellationToken);
+ }
+
+ ///
+ /// Sends the given file using the SendFile extension.
+ ///
+ ///
+ /// The full path to the file.
+ /// The offset in the file.
+ /// The number of bytes to send, or null to send the remainder of the file.
+ ///
+ ///
+ public static Task SendFileAsync(this HttpResponse response, string fileName, long offset, long? count, CancellationToken cancellationToken = default)
+ {
+ if (response == null)
+ {
+ throw new ArgumentNullException(nameof(response));
+ }
+
+ if (fileName == null)
+ {
+ throw new ArgumentNullException(nameof(fileName));
+ }
+
+ return SendFileAsyncCore(response, fileName, offset, count, cancellationToken);
+ }
+
+ private static async Task SendFileAsyncCore(HttpResponse response, IFileInfo file, long offset, long? count, CancellationToken cancellationToken)
+ {
if (string.IsNullOrEmpty(file.PhysicalPath))
{
+ CheckRange(offset, count, file.Length);
+
using (var fileContent = file.CreateReadStream())
{
if (offset > 0)
@@ -76,63 +126,19 @@ namespace Microsoft.AspNetCore.Http
}
}
- ///
- /// Sends the given file using the SendFile extension.
- ///
- ///
- /// The full path to the file.
- /// The .
- ///
- public static Task SendFileAsync(this HttpResponse response, string fileName,
- CancellationToken cancellationToken = default(CancellationToken))
+ private static Task SendFileAsyncCore(HttpResponse response, string fileName, long offset, long? count, CancellationToken cancellationToken = default)
{
- if (response == null)
- {
- throw new ArgumentNullException(nameof(response));
- }
-
- if (fileName == null)
- {
- throw new ArgumentNullException(nameof(fileName));
- }
-
- return response.SendFileAsync(fileName, 0, null, cancellationToken);
- }
-
- ///
- /// Sends the given file using the SendFile extension.
- ///
- ///
- /// The full path to the file.
- /// The offset in the file.
- /// The number of bytes to send, or null to send the remainder of the file.
- ///
- ///
- public static Task SendFileAsync(this HttpResponse response, string fileName, long offset, long? count,
- CancellationToken cancellationToken = default(CancellationToken))
- {
- if (response == null)
- {
- throw new ArgumentNullException(nameof(response));
- }
-
- if (fileName == null)
- {
- throw new ArgumentNullException(nameof(fileName));
- }
-
var sendFile = response.HttpContext.Features.Get();
if (sendFile == null)
{
- return SendFileAsync(response.Body, fileName, offset, count, cancellationToken);
+ return SendFileAsyncCore(response.Body, fileName, offset, count, cancellationToken);
}
return sendFile.SendFileAsync(fileName, offset, count, cancellationToken);
}
// Not safe for overlapped writes.
- private static async Task SendFileAsync(Stream outputStream, string fileName, long offset, long? count,
- CancellationToken cancel = default(CancellationToken))
+ private static async Task SendFileAsyncCore(Stream outputStream, string fileName, long offset, long? count, CancellationToken cancel = default)
{
cancel.ThrowIfCancellationRequested();
@@ -140,7 +146,6 @@ namespace Microsoft.AspNetCore.Http
CheckRange(offset, count, fileInfo.Length);
int bufferSize = 1024 * 16;
-
var fileStream = new FileStream(
fileName,
FileMode.Open,
@@ -151,7 +156,11 @@ namespace Microsoft.AspNetCore.Http
using (fileStream)
{
- fileStream.Seek(offset, SeekOrigin.Begin);
+ if (offset > 0)
+ {
+ fileStream.Seek(offset, SeekOrigin.Begin);
+ }
+
await StreamCopyOperation.CopyToAsync(fileStream, outputStream, count, cancel);
}
}