@@ -22,8 +22,7 @@ public static class SendFileResponseExtensions
22
22
/// <param name="response"></param>
23
23
/// <param name="file">The file.</param>
24
24
/// <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 )
27
26
{
28
27
if ( response == null )
29
28
{
@@ -34,7 +33,7 @@ public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
34
33
throw new ArgumentNullException ( nameof ( file ) ) ;
35
34
}
36
35
37
- return response . SendFileAsync ( file , 0 , null , cancellationToken ) ;
36
+ return SendFileAsyncCore ( response , file , 0 , null , cancellationToken ) ;
38
37
}
39
38
40
39
/// <summary>
@@ -46,8 +45,7 @@ public static Task SendFileAsync(this HttpResponse response, IFileInfo file,
46
45
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
47
46
/// <param name="cancellationToken"></param>
48
47
/// <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 )
51
49
{
52
50
if ( response == null )
53
51
{
@@ -57,23 +55,8 @@ public static async Task SendFileAsync(this HttpResponse response, IFileInfo fil
57
55
{
58
56
throw new ArgumentNullException ( nameof ( file ) ) ;
59
57
}
60
- CheckRange ( offset , count , file . Length ) ;
61
58
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 ) ;
77
60
}
78
61
79
62
/// <summary>
@@ -83,8 +66,7 @@ public static async Task SendFileAsync(this HttpResponse response, IFileInfo fil
83
66
/// <param name="fileName">The full path to the file.</param>
84
67
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
85
68
/// <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 )
88
70
{
89
71
if ( response == null )
90
72
{
@@ -96,7 +78,7 @@ public static Task SendFileAsync(this HttpResponse response, string fileName,
96
78
throw new ArgumentNullException ( nameof ( fileName ) ) ;
97
79
}
98
80
99
- return response . SendFileAsync ( fileName , 0 , null , cancellationToken ) ;
81
+ return SendFileAsyncCore ( response , fileName , 0 , null , cancellationToken ) ;
100
82
}
101
83
102
84
/// <summary>
@@ -108,8 +90,7 @@ public static Task SendFileAsync(this HttpResponse response, string fileName,
108
90
/// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param>
109
91
/// <param name="cancellationToken"></param>
110
92
/// <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 )
113
94
{
114
95
if ( response == null )
115
96
{
@@ -121,26 +102,50 @@ public static Task SendFileAsync(this HttpResponse response, string fileName, lo
121
102
throw new ArgumentNullException ( nameof ( fileName ) ) ;
122
103
}
123
104
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
+ {
124
131
var sendFile = response . HttpContext . Features . Get < IHttpSendFileFeature > ( ) ;
125
132
if ( sendFile == null )
126
133
{
127
- return SendFileAsync ( response . Body , fileName , offset , count , cancellationToken ) ;
134
+ return SendFileAsyncCore ( response . Body , fileName , offset , count , cancellationToken ) ;
128
135
}
129
136
130
137
return sendFile . SendFileAsync ( fileName , offset , count , cancellationToken ) ;
131
138
}
132
139
133
140
// 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 )
136
142
{
137
143
cancel . ThrowIfCancellationRequested ( ) ;
138
144
139
145
var fileInfo = new FileInfo ( fileName ) ;
140
146
CheckRange ( offset , count , fileInfo . Length ) ;
141
147
142
148
int bufferSize = 1024 * 16 ;
143
-
144
149
var fileStream = new FileStream (
145
150
fileName ,
146
151
FileMode . Open ,
@@ -151,7 +156,11 @@ private static async Task SendFileAsync(Stream outputStream, string fileName, lo
151
156
152
157
using ( fileStream )
153
158
{
154
- fileStream . Seek ( offset , SeekOrigin . Begin ) ;
159
+ if ( offset > 0 )
160
+ {
161
+ fileStream . Seek ( offset , SeekOrigin . Begin ) ;
162
+ }
163
+
155
164
await StreamCopyOperation . CopyToAsync ( fileStream , outputStream , count , cancel ) ;
156
165
}
157
166
}
0 commit comments