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

Commit 1145b82

Browse files
committed
Changed to IFileInfo instead of file name string
1 parent 193ea80 commit 1145b82

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

src/Microsoft.AspNetCore.Http.Abstractions/HttpResponse.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading;
77
using System.Threading.Tasks;
88
using Microsoft.AspNetCore.Http.Features;
9+
using Microsoft.Extensions.FileProviders;
910

1011
namespace Microsoft.AspNetCore.Http
1112
{
@@ -109,41 +110,53 @@ public abstract class HttpResponse
109110
/// <summary>
110111
/// Sends the given file using the SendFile extension.
111112
/// </summary>
112-
/// <param name="fileName">The full path to the file.</param>
113+
/// <param name="file">The file to send.</param>
113114
/// <returns></returns>
114-
public virtual Task SendFileAsync(string fileName)
115+
public virtual Task SendFileAsync(IFileInfo file)
115116
{
116-
if (fileName == null)
117+
if (file == null)
117118
{
118-
throw new ArgumentNullException(nameof(fileName));
119+
throw new ArgumentNullException(nameof(file));
119120
}
120121

121-
return SendFileAsync(fileName, 0, null, CancellationToken.None);
122+
return SendFileAsync(file, 0, null, CancellationToken.None);
122123
}
123124

124125
/// <summary>
125126
/// Sends the given file using the SendFile extension.
126127
/// </summary>
127-
/// <param name="fileName">The full path to the file.</param>
128+
/// <param name="file">The file to send.</param>
128129
/// <param name="offset">The offset in the file.</param>
129130
/// <param name="count">The number of types to send, or null to send the remainder of the file.</param>
130131
/// <param name="cancellationToken"></param>
131132
/// <returns></returns>
132-
public virtual Task SendFileAsync(string fileName, long offset, long? count, CancellationToken cancellationToken = default(CancellationToken))
133+
public virtual async Task SendFileAsync(IFileInfo file, long offset, long? count, CancellationToken cancellationToken = default(CancellationToken))
133134
{
134-
if (fileName == null)
135+
if (file == null)
135136
{
136-
throw new ArgumentNullException(nameof(fileName));
137+
throw new ArgumentNullException(nameof(file));
138+
}
139+
140+
if (string.IsNullOrEmpty(file.PhysicalPath))
141+
{
142+
using (var readStream = file.CreateReadStream())
143+
{
144+
readStream.Seek(offset, SeekOrigin.Begin); // TODO: What if !CanSeek?
145+
146+
await StreamCopyOperation.CopyToAsync(readStream, Body, count, cancellationToken);
147+
return;
148+
}
137149
}
138150

139151
var sendFile = HttpContext.Features.Get<IHttpSendFileFeature>();
140152

141153
if (sendFile == null)
142154
{
143-
return SendFileAsync(Body, fileName, offset, count, cancellationToken);
155+
await SendFileAsync(Body, file.PhysicalPath, offset, count, cancellationToken);
156+
return;
144157
}
145158

146-
return sendFile.SendFileAsync(fileName, offset, count, cancellationToken);
159+
await sendFile.SendFileAsync(file.PhysicalPath, offset, count, cancellationToken);
147160
}
148161

149162
// Not safe for overlapped writes.

src/Microsoft.AspNetCore.Http.Abstractions/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
},
1212
"dependencies": {
1313
"Microsoft.AspNetCore.Http.Features": "1.0.0-*",
14+
"Microsoft.Extensions.FileProviders.Abstractions": "1.0.0-*",
1415
"Microsoft.Extensions.ActivatorUtilities.Sources": {
1516
"type": "build",
1617
"version": "1.0.0-*"

test/Microsoft.AspNetCore.Http.Extensions.Tests/SendFileResponseExtensionsTests.cs renamed to test/Microsoft.AspNetCore.Http.Abstractions.Tests/SendFileTests.cs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,13 @@
66
using System.Threading.Tasks;
77
using Microsoft.AspNetCore.Http.Features;
88
using Microsoft.AspNetCore.Http.Internal;
9+
using Microsoft.Extensions.FileProviders;
910
using Xunit;
1011

11-
namespace Microsoft.AspNetCore.Http.Extensions.Tests
12+
namespace Microsoft.AspNetCore.Http.Tests
1213
{
13-
public class SendFileResponseExtensionsTests
14+
public class SendFileTests
1415
{
15-
[Fact]
16-
public Task SendFileWhenFileNotFoundThrows()
17-
{
18-
var response = new DefaultHttpContext().Response;
19-
return Assert.ThrowsAsync<FileNotFoundException>(() => response.SendFileAsync("foo"));
20-
}
21-
2216
[Fact]
2317
public async Task SendFileWorks()
2418
{
@@ -27,7 +21,8 @@ public async Task SendFileWorks()
2721
var fakeFeature = new FakeSendFileFeature();
2822
context.Features.Set<IHttpSendFileFeature>(fakeFeature);
2923

30-
await response.SendFileAsync("bob", 1, 3, CancellationToken.None);
24+
var fileInfo = new FakeFileInfo("bob");
25+
await response.SendFileAsync(fileInfo, 1, 3, CancellationToken.None);
3126

3227
Assert.Equal("bob", fakeFeature.name);
3328
Assert.Equal(1, fakeFeature.offset);
@@ -51,5 +46,28 @@ public Task SendFileAsync(string path, long offset, long? length, CancellationTo
5146
return Task.FromResult(0);
5247
}
5348
}
49+
50+
private class FakeFileInfo : IFileInfo
51+
{
52+
public FakeFileInfo(string name, bool exists = true)
53+
{
54+
Name = name;
55+
Exists = exists;
56+
}
57+
58+
public Stream CreateReadStream() => new MemoryStream();
59+
60+
public bool Exists { get; }
61+
62+
public long Length => 0;
63+
64+
public string PhysicalPath => Name;
65+
66+
public string Name { get; }
67+
68+
public DateTimeOffset LastModified => DateTimeOffset.UtcNow;
69+
70+
public bool IsDirectory => false;
71+
}
5472
}
5573
}

0 commit comments

Comments
 (0)