@@ -107,41 +107,28 @@ public static Task SendFileAsync(this HttpResponse response, string fileName, lo
107
107
108
108
private static async Task SendFileAsyncCore ( HttpResponse response , IFileInfo file , long offset , long ? count , CancellationToken cancellationToken )
109
109
{
110
- if ( string . IsNullOrEmpty ( file . PhysicalPath ) )
110
+ if ( ! string . IsNullOrEmpty ( file . PhysicalPath ) )
111
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
- }
112
+ await response . SendFileAsync ( file . PhysicalPath , offset , count , cancellationToken ) ;
113
+ return ;
122
114
}
123
- else
115
+
116
+ CheckRange ( offset , count , file . Length ) ;
117
+ using ( var fileContent = file . CreateReadStream ( ) )
124
118
{
125
- await response . SendFileAsync ( file . PhysicalPath , offset , count , cancellationToken ) ;
119
+ await SendStreamAsync ( fileContent , response , offset , count , cancellationToken ) ;
126
120
}
127
121
}
128
122
129
- private static Task SendFileAsyncCore ( HttpResponse response , string fileName , long offset , long ? count , CancellationToken cancellationToken = default )
123
+ private static async Task SendFileAsyncCore ( HttpResponse response , string fileName , long offset , long ? count , CancellationToken cancellationToken = default )
130
124
{
131
125
var sendFile = response . HttpContext . Features . Get < IHttpSendFileFeature > ( ) ;
132
- if ( sendFile = = null )
126
+ if ( sendFile ! = null )
133
127
{
134
- return SendFileAsyncCore ( response . Body , fileName , offset , count , cancellationToken ) ;
128
+ await sendFile . SendFileAsync ( fileName , offset , count , cancellationToken ) ;
129
+ return ;
135
130
}
136
131
137
- return sendFile . SendFileAsync ( fileName , offset , count , cancellationToken ) ;
138
- }
139
-
140
- // Not safe for overlapped writes.
141
- private static async Task SendFileAsyncCore ( Stream outputStream , string fileName , long offset , long ? count , CancellationToken cancel = default )
142
- {
143
- cancel . ThrowIfCancellationRequested ( ) ;
144
-
145
132
var fileInfo = new FileInfo ( fileName ) ;
146
133
CheckRange ( offset , count , fileInfo . Length ) ;
147
134
@@ -155,14 +142,44 @@ private static async Task SendFileAsyncCore(Stream outputStream, string fileName
155
142
options : FileOptions . Asynchronous | FileOptions . SequentialScan ) ;
156
143
157
144
using ( fileStream )
145
+ {
146
+ await SendStreamAsync ( fileStream , response , offset , count , cancellationToken ) ;
147
+ }
148
+ }
149
+
150
+ private static Task SendStreamAsync ( Stream source , HttpResponse response , long offset , long ? count , CancellationToken cancellationToken )
151
+ {
152
+ if ( ! cancellationToken . CanBeCanceled )
153
+ {
154
+ return SendStreamQuietAsync ( source , response , offset , count , response . HttpContext . RequestAborted ) ;
155
+ }
156
+
157
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
158
+ if ( offset > 0 )
159
+ {
160
+ source . Seek ( offset , SeekOrigin . Begin ) ;
161
+ }
162
+
163
+ return StreamCopyOperation . CopyToAsync ( source , response . Body , count , cancellationToken ) ;
164
+ }
165
+
166
+ private static async Task SendStreamQuietAsync ( Stream source , HttpResponse response , long offset , long ? count , CancellationToken cancellationToken )
167
+ {
168
+ if ( cancellationToken . IsCancellationRequested )
169
+ {
170
+ return ;
171
+ }
172
+
173
+ try
158
174
{
159
175
if ( offset > 0 )
160
176
{
161
- fileStream . Seek ( offset , SeekOrigin . Begin ) ;
177
+ source . Seek ( offset , SeekOrigin . Begin ) ;
162
178
}
163
179
164
- await StreamCopyOperation . CopyToAsync ( fileStream , outputStream , count , cancel ) ;
180
+ await StreamCopyOperation . CopyToAsync ( source , response . Body , count , cancellationToken ) ;
165
181
}
182
+ catch ( OperationCanceledException ) { }
166
183
}
167
184
168
185
private static void CheckRange ( long offset , long ? count , long fileLength )
@@ -178,4 +195,4 @@ private static void CheckRange(long offset, long? count, long fileLength)
178
195
}
179
196
}
180
197
}
181
- }
198
+ }
0 commit comments