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

Commit 816ecf5

Browse files
authored
Reduce the amount of argument checking by flattening the call graph. (#995)
1 parent 672a5f3 commit 816ecf5

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

src/Microsoft.AspNetCore.Http.Extensions/SendFileResponseExtensions.cs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ public static class SendFileResponseExtensions
2222
/// <param name="response"></param>
2323
/// <param name="file">The file.</param>
2424
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
25-
public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
26-
CancellationToken cancellationToken = default(CancellationToken))
25+
public static Task SendFileAsync(this HttpResponse response, IFileInfo file, CancellationToken cancellationToken = default)
2726
{
2827
if (response == null)
2928
{
@@ -34,7 +33,7 @@ public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
3433
throw new ArgumentNullException(nameof(file));
3534
}
3635

37-
return response.SendFileAsync(file, 0, null, cancellationToken);
36+
return SendFileAsyncCore(response, file, 0, null, cancellationToken);
3837
}
3938

4039
/// <summary>
@@ -46,8 +45,7 @@ public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
4645
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
4746
/// <param name="cancellationToken"></param>
4847
/// <returns></returns>
49-
public static async Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count,
50-
CancellationToken cancellationToken = default(CancellationToken))
48+
public static Task SendFileAsync(this HttpResponse response, IFileInfo file, long offset, long? count, CancellationToken cancellationToken = default)
5149
{
5250
if (response == null)
5351
{
@@ -57,23 +55,8 @@ public static async Task SendFileAsync(this HttpResponse response, IFileInfo fil
5755
{
5856
throw new ArgumentNullException(nameof(file));
5957
}
60-
CheckRange(offset, count, file.Length);
6158

62-
if (string.IsNullOrEmpty(file.PhysicalPath))
63-
{
64-
using (var fileContent = file.CreateReadStream())
65-
{
66-
if (offset > 0)
67-
{
68-
fileContent.Seek(offset, SeekOrigin.Begin);
69-
}
70-
await StreamCopyOperation.CopyToAsync(fileContent, response.Body, count, cancellationToken);
71-
}
72-
}
73-
else
74-
{
75-
await response.SendFileAsync(file.PhysicalPath, offset, count, cancellationToken);
76-
}
59+
return SendFileAsyncCore(response, file, offset, count, cancellationToken);
7760
}
7861

7962
/// <summary>
@@ -83,8 +66,7 @@ public static async Task SendFileAsync(this HttpResponse response, IFileInfo fil
8366
/// <param name="fileName">The full path to the file.</param>
8467
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
8568
/// <returns></returns>
86-
public static Task SendFileAsync(this HttpResponse response, string fileName,
87-
CancellationToken cancellationToken = default(CancellationToken))
69+
public static Task SendFileAsync(this HttpResponse response, string fileName, CancellationToken cancellationToken = default)
8870
{
8971
if (response == null)
9072
{
@@ -96,7 +78,7 @@ public static Task SendFileAsync(this HttpResponse response, string fileName,
9678
throw new ArgumentNullException(nameof(fileName));
9779
}
9880

99-
return response.SendFileAsync(fileName, 0, null, cancellationToken);
81+
return SendFileAsyncCore(response, fileName, 0, null, cancellationToken);
10082
}
10183

10284
/// <summary>
@@ -108,8 +90,7 @@ public static Task SendFileAsync(this HttpResponse response, string fileName,
10890
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
10991
/// <param name="cancellationToken"></param>
11092
/// <returns></returns>
111-
public static Task SendFileAsync(this HttpResponse response, string fileName, long offset, long? count,
112-
CancellationToken cancellationToken = default(CancellationToken))
93+
public static Task SendFileAsync(this HttpResponse response, string fileName, long offset, long? count, CancellationToken cancellationToken = default)
11394
{
11495
if (response == null)
11596
{
@@ -121,26 +102,50 @@ public static Task SendFileAsync(this HttpResponse response, string fileName, lo
121102
throw new ArgumentNullException(nameof(fileName));
122103
}
123104

105+
return SendFileAsyncCore(response, fileName, offset, count, cancellationToken);
106+
}
107+
108+
private static async Task SendFileAsyncCore(HttpResponse response, IFileInfo file, long offset, long? count, CancellationToken cancellationToken)
109+
{
110+
if (string.IsNullOrEmpty(file.PhysicalPath))
111+
{
112+
CheckRange(offset, count, file.Length);
113+
114+
using (var fileContent = file.CreateReadStream())
115+
{
116+
if (offset > 0)
117+
{
118+
fileContent.Seek(offset, SeekOrigin.Begin);
119+
}
120+
await StreamCopyOperation.CopyToAsync(fileContent, response.Body, count, cancellationToken);
121+
}
122+
}
123+
else
124+
{
125+
await response.SendFileAsync(file.PhysicalPath, offset, count, cancellationToken);
126+
}
127+
}
128+
129+
private static Task SendFileAsyncCore(HttpResponse response, string fileName, long offset, long? count, CancellationToken cancellationToken = default)
130+
{
124131
var sendFile = response.HttpContext.Features.Get<IHttpSendFileFeature>();
125132
if (sendFile == null)
126133
{
127-
return SendFileAsync(response.Body, fileName, offset, count, cancellationToken);
134+
return SendFileAsyncCore(response.Body, fileName, offset, count, cancellationToken);
128135
}
129136

130137
return sendFile.SendFileAsync(fileName, offset, count, cancellationToken);
131138
}
132139

133140
// Not safe for overlapped writes.
134-
private static async Task SendFileAsync(Stream outputStream, string fileName, long offset, long? count,
135-
CancellationToken cancel = default(CancellationToken))
141+
private static async Task SendFileAsyncCore(Stream outputStream, string fileName, long offset, long? count, CancellationToken cancel = default)
136142
{
137143
cancel.ThrowIfCancellationRequested();
138144

139145
var fileInfo = new FileInfo(fileName);
140146
CheckRange(offset, count, fileInfo.Length);
141147

142148
int bufferSize = 1024 * 16;
143-
144149
var fileStream = new FileStream(
145150
fileName,
146151
FileMode.Open,
@@ -151,7 +156,11 @@ private static async Task SendFileAsync(Stream outputStream, string fileName, lo
151156

152157
using (fileStream)
153158
{
154-
fileStream.Seek(offset, SeekOrigin.Begin);
159+
if (offset > 0)
160+
{
161+
fileStream.Seek(offset, SeekOrigin.Begin);
162+
}
163+
155164
await StreamCopyOperation.CopyToAsync(fileStream, outputStream, count, cancel);
156165
}
157166
}

0 commit comments

Comments
 (0)