Reduce the amount of argument checking by flattening the call graph. (#995)
This commit is contained in:
parent
672a5f3c76
commit
816ecf5cda
|
|
@ -22,8 +22,7 @@ namespace Microsoft.AspNetCore.Http
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
/// <param name="file">The file.</param>
|
/// <param name="file">The file.</param>
|
||||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||||
public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
|
public static Task SendFileAsync(this HttpResponse response, IFileInfo file, CancellationToken cancellationToken = default)
|
||||||
CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
{
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
|
|
@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.Http
|
||||||
throw new ArgumentNullException(nameof(file));
|
throw new ArgumentNullException(nameof(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.SendFileAsync(file, 0, null, cancellationToken);
|
return SendFileAsyncCore(response, file, 0, null, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -46,8 +45,7 @@ namespace Microsoft.AspNetCore.Http
|
||||||
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
|
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count,
|
public static Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count, CancellationToken cancellationToken = default)
|
||||||
CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
{
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
|
|
@ -57,10 +55,62 @@ namespace Microsoft.AspNetCore.Http
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(file));
|
throw new ArgumentNullException(nameof(file));
|
||||||
}
|
}
|
||||||
CheckRange(offset, count, file.Length);
|
|
||||||
|
|
||||||
|
return SendFileAsyncCore(response, file, offset, count, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends the given file using the SendFile extension.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="response"></param>
|
||||||
|
/// <param name="fileName">The full path to the file.</param>
|
||||||
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends the given file using the SendFile extension.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="response"></param>
|
||||||
|
/// <param name="fileName">The full path to the file.</param>
|
||||||
|
/// <param name="offset">The offset in the file.</param>
|
||||||
|
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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))
|
if (string.IsNullOrEmpty(file.PhysicalPath))
|
||||||
{
|
{
|
||||||
|
CheckRange(offset, count, file.Length);
|
||||||
|
|
||||||
using (var fileContent = file.CreateReadStream())
|
using (var fileContent = file.CreateReadStream())
|
||||||
{
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
|
|
@ -76,63 +126,19 @@ namespace Microsoft.AspNetCore.Http
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static Task SendFileAsyncCore(HttpResponse response, string fileName, long offset, long? count, CancellationToken cancellationToken = default)
|
||||||
/// Sends the given file using the SendFile extension.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="response"></param>
|
|
||||||
/// <param name="fileName">The full path to the file.</param>
|
|
||||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Task SendFileAsync(this HttpResponse response, string fileName,
|
|
||||||
CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
{
|
||||||
if (response == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileName == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.SendFileAsync(fileName, 0, null, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends the given file using the SendFile extension.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="response"></param>
|
|
||||||
/// <param name="fileName">The full path to the file.</param>
|
|
||||||
/// <param name="offset">The offset in the file.</param>
|
|
||||||
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
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<IHttpSendFileFeature>();
|
var sendFile = response.HttpContext.Features.Get<IHttpSendFileFeature>();
|
||||||
if (sendFile == null)
|
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);
|
return sendFile.SendFileAsync(fileName, offset, count, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not safe for overlapped writes.
|
// Not safe for overlapped writes.
|
||||||
private static async Task SendFileAsync(Stream outputStream, string fileName, long offset, long? count,
|
private static async Task SendFileAsyncCore(Stream outputStream, string fileName, long offset, long? count, CancellationToken cancel = default)
|
||||||
CancellationToken cancel = default(CancellationToken))
|
|
||||||
{
|
{
|
||||||
cancel.ThrowIfCancellationRequested();
|
cancel.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
|
@ -140,7 +146,6 @@ namespace Microsoft.AspNetCore.Http
|
||||||
CheckRange(offset, count, fileInfo.Length);
|
CheckRange(offset, count, fileInfo.Length);
|
||||||
|
|
||||||
int bufferSize = 1024 * 16;
|
int bufferSize = 1024 * 16;
|
||||||
|
|
||||||
var fileStream = new FileStream(
|
var fileStream = new FileStream(
|
||||||
fileName,
|
fileName,
|
||||||
FileMode.Open,
|
FileMode.Open,
|
||||||
|
|
@ -151,7 +156,11 @@ namespace Microsoft.AspNetCore.Http
|
||||||
|
|
||||||
using (fileStream)
|
using (fileStream)
|
||||||
{
|
{
|
||||||
fileStream.Seek(offset, SeekOrigin.Begin);
|
if (offset > 0)
|
||||||
|
{
|
||||||
|
fileStream.Seek(offset, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
|
||||||
await StreamCopyOperation.CopyToAsync(fileStream, outputStream, count, cancel);
|
await StreamCopyOperation.CopyToAsync(fileStream, outputStream, count, cancel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue